11#ifndef EIGEN_HOMOGENEOUS_H
12#define EIGEN_HOMOGENEOUS_H
15#include "./InternalHeaderCheck.h"
36template <
typename MatrixType,
int Direction>
37struct traits<Homogeneous<MatrixType, Direction> > : traits<MatrixType> {
38 using StorageKind =
typename traits<MatrixType>::StorageKind;
39 using MatrixTypeNested =
typename ref_selector<MatrixType>::type;
40 using MatrixTypeNested_ = std::remove_reference_t<MatrixTypeNested>;
42 RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ?
int(MatrixType::RowsAtCompileTime) + 1 : Dynamic,
43 ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ?
int(MatrixType::ColsAtCompileTime) + 1 : Dynamic,
44 RowsAtCompileTime = Direction ==
Vertical ? RowsPlusOne : MatrixType::RowsAtCompileTime,
45 ColsAtCompileTime = Direction ==
Horizontal ? ColsPlusOne : MatrixType::ColsAtCompileTime,
46 MaxRowsAtCompileTime = RowsAtCompileTime,
47 MaxColsAtCompileTime = ColsAtCompileTime,
48 TmpFlags = MatrixTypeNested_::Flags & HereditaryBits,
49 Flags = ColsAtCompileTime == 1 ? (TmpFlags & ~RowMajorBit)
55template <
typename MatrixType,
typename Lhs>
56struct homogeneous_left_product_impl;
57template <
typename MatrixType,
typename Rhs>
58struct homogeneous_right_product_impl;
62template <
typename MatrixType,
int Direction_>
63class Homogeneous :
public MatrixBase<Homogeneous<MatrixType, Direction_> >, internal::no_assignment_operator {
65 using NestedExpression = MatrixType;
66 enum { Direction = Direction_ };
68 using Base = MatrixBase<Homogeneous>;
69 EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous)
71 EIGEN_DEVICE_FUNC
explicit inline Homogeneous(
const MatrixType& matrix) : m_matrix(matrix) {}
73 EIGEN_DEVICE_FUNC
constexpr Index rows()
const noexcept {
74 return m_matrix.rows() + (int(Direction) ==
Vertical ? 1 : 0);
76 EIGEN_DEVICE_FUNC
constexpr Index cols()
const noexcept {
77 return m_matrix.cols() + (int(Direction) ==
Horizontal ? 1 : 0);
80 EIGEN_DEVICE_FUNC
const NestedExpression& nestedExpression()
const {
return m_matrix; }
82 template <
typename Rhs>
87 template <
typename Lhs>
89 const Homogeneous& rhs) {
93 template <
typename Scalar,
int Dim,
int Mode,
int Options>
96 eigen_assert(
int(Direction) ==
Vertical);
100 template <
typename Func>
101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
typename internal::result_of<Func(
Scalar,
Scalar)>::type redux(
102 const Func& func)
const {
103 return func(m_matrix.redux(func),
Scalar(1));
107 typename MatrixType::Nested m_matrix;
124template <
typename Derived>
126 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
127 return HomogeneousReturnType(derived());
141template <
typename ExpressionType,
int Direction>
144 return HomogeneousReturnType(_expression());
164template <
typename Derived>
167 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
168 return ConstStartMinusOne(derived(), 0, 0,
ColsAtCompileTime == 1 ? size() - 1 : 1,
188template <
typename ExpressionType,
int Direction>
189EIGEN_DEVICE_FUNC
inline const typename VectorwiseOp<ExpressionType, Direction>::HNormalizedReturnType
191 return HNormalized_Block(_expression(), 0, 0, Direction ==
Vertical ? _expression().rows() - 1 : _expression().rows(),
192 Direction ==
Horizontal ? _expression().cols() - 1 : _expression().cols())
193 .cwiseQuotient(
Replicate < HNormalized_Factors, Direction ==
Vertical ? HNormalized_SizeMinusOne : 1,
195 ? HNormalized_SizeMinusOne
196 : 1 > (HNormalized_Factors(_expression(), Direction ==
Vertical ? _expression().rows() - 1 : 0,
197 Direction ==
Horizontal ? _expression().cols() - 1 : 0,
198 Direction ==
Vertical ? 1 : _expression().rows(),
199 Direction ==
Horizontal ? 1 : _expression().cols()),
200 Direction ==
Vertical ? _expression().rows() - 1 : 1,
201 Direction ==
Horizontal ? _expression().cols() - 1 : 1));
206template <
typename MatrixOrTransformType>
207struct take_matrix_for_product {
208 using type = MatrixOrTransformType;
209 EIGEN_DEVICE_FUNC
static const type& run(
const type& x) {
return x; }
212template <
typename Scalar,
int Dim,
int Mode,
int Options>
213struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> > {
214 using TransformType = Transform<Scalar, Dim, Mode, Options>;
215 using type = std::add_const_t<typename TransformType::ConstAffinePart>;
216 EIGEN_DEVICE_FUNC
static type run(
const TransformType& x) {
return x.affine(); }
219template <
typename Scalar,
int Dim,
int Options>
220struct take_matrix_for_product<Transform<Scalar, Dim,
Projective, Options> > {
221 using TransformType = Transform<Scalar, Dim, Projective, Options>;
222 using type =
typename TransformType::MatrixType;
223 EIGEN_DEVICE_FUNC
static const type& run(
const TransformType& x) {
return x.matrix(); }
226template <
typename MatrixType,
typename Lhs>
227struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType,
Vertical>, Lhs> > {
228 using LhsMatrixType =
typename take_matrix_for_product<Lhs>::type;
229 using MatrixTypeCleaned = remove_all_t<MatrixType>;
230 using LhsMatrixTypeCleaned = remove_all_t<LhsMatrixType>;
231 using ReturnType =
typename make_proper_matrix_type<
232 typename traits<MatrixTypeCleaned>::Scalar, LhsMatrixTypeCleaned::RowsAtCompileTime,
233 MatrixTypeCleaned::ColsAtCompileTime, MatrixTypeCleaned::PlainObject::Options,
234 LhsMatrixTypeCleaned::MaxRowsAtCompileTime, MatrixTypeCleaned::MaxColsAtCompileTime>::type;
237template <
typename MatrixType,
typename Lhs>
238struct homogeneous_left_product_impl<Homogeneous<MatrixType,
Vertical>, Lhs>
239 :
public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType, Vertical>, Lhs> > {
240 using LhsMatrixType =
typename traits<homogeneous_left_product_impl>::LhsMatrixType;
241 using LhsMatrixTypeCleaned = remove_all_t<LhsMatrixType>;
242 using LhsMatrixTypeNested = remove_all_t<typename LhsMatrixTypeCleaned::Nested>;
243 EIGEN_DEVICE_FUNC homogeneous_left_product_impl(
const Lhs& lhs,
const MatrixType& rhs)
244 : m_lhs(take_matrix_for_product<Lhs>::run(lhs)), m_rhs(rhs) {}
246 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
return m_lhs.rows(); }
247 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return m_rhs.cols(); }
249 template <
typename Dest>
250 EIGEN_DEVICE_FUNC
void evalTo(Dest& dst)
const {
252 dst = Block <
const LhsMatrixTypeNested, LhsMatrixTypeNested::RowsAtCompileTime,
253 LhsMatrixTypeNested::ColsAtCompileTime == Dynamic
255 : LhsMatrixTypeNested::ColsAtCompileTime - 1 > (m_lhs, 0, 0, m_lhs.rows(), m_lhs.cols() - 1) * m_rhs;
256 dst += m_lhs.col(m_lhs.cols() - 1).rowwise().template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols());
259 typename LhsMatrixTypeCleaned::Nested m_lhs;
260 typename MatrixType::Nested m_rhs;
263template <
typename MatrixType,
typename Rhs>
264struct traits<homogeneous_right_product_impl<Homogeneous<MatrixType,
Horizontal>, Rhs> > {
266 typename make_proper_matrix_type<typename traits<MatrixType>::Scalar, MatrixType::RowsAtCompileTime,
267 Rhs::ColsAtCompileTime, MatrixType::PlainObject::Options,
268 MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime>::type;
271template <
typename MatrixType,
typename Rhs>
272struct homogeneous_right_product_impl<Homogeneous<MatrixType,
Horizontal>, Rhs>
273 :
public ReturnByValue<homogeneous_right_product_impl<Homogeneous<MatrixType, Horizontal>, Rhs> > {
274 using RhsNested = remove_all_t<typename Rhs::Nested>;
275 EIGEN_DEVICE_FUNC homogeneous_right_product_impl(
const MatrixType& lhs,
const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) {}
277 EIGEN_DEVICE_FUNC
constexpr Index rows() const noexcept {
return m_lhs.rows(); }
278 EIGEN_DEVICE_FUNC
constexpr Index cols() const noexcept {
return m_rhs.cols(); }
280 template <
typename Dest>
281 EIGEN_DEVICE_FUNC
void evalTo(Dest& dst)
const {
283 dst = m_lhs * Block <
const RhsNested,
284 RhsNested::RowsAtCompileTime == Dynamic ? Dynamic : RhsNested::RowsAtCompileTime - 1,
285 RhsNested::ColsAtCompileTime > (m_rhs, 0, 0, m_rhs.rows() - 1, m_rhs.cols());
286 dst += m_rhs.row(m_rhs.rows() - 1).colwise().template replicate<MatrixType::RowsAtCompileTime>(m_lhs.rows());
289 typename MatrixType::Nested m_lhs;
290 typename Rhs::Nested m_rhs;
293template <
typename ArgType,
int Direction>
294struct evaluator_traits<Homogeneous<ArgType, Direction> > {
295 using Kind =
typename storage_kind_to_evaluator_kind<typename ArgType::StorageKind>::Kind;
296 using Shape = HomogeneousShape;
300struct AssignmentKind<DenseShape, HomogeneousShape> {
301 using Kind = Dense2Dense;
304template <
typename ArgType,
int Direction>
305struct unary_evaluator<Homogeneous<ArgType, Direction>, IndexBased>
306 : evaluator<typename Homogeneous<ArgType, Direction>::PlainObject> {
307 using XprType = Homogeneous<ArgType, Direction>;
308 using PlainObject =
typename XprType::PlainObject;
309 using Base = evaluator<PlainObject>;
311 EIGEN_DEVICE_FUNC
explicit unary_evaluator(
const XprType& op) : Base(), m_temp(op) {
312 internal::construct_at<Base>(
this, m_temp);
320template <
typename DstXprType,
typename ArgType,
typename Scalar>
321struct Assignment<DstXprType, Homogeneous<ArgType,
Vertical>, internal::assign_op<Scalar, typename ArgType::Scalar>,
323 using SrcXprType = Homogeneous<ArgType, Vertical>;
324 EIGEN_DEVICE_FUNC
static void run(DstXprType& dst,
const SrcXprType& src,
325 const internal::assign_op<Scalar, typename ArgType::Scalar>&) {
326 Index dstRows = src.rows();
327 Index dstCols = src.cols();
328 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
330 dst.template topRows<ArgType::RowsAtCompileTime>(src.nestedExpression().rows()) = src.nestedExpression();
331 dst.row(dst.rows() - 1).setOnes();
336template <
typename DstXprType,
typename ArgType,
typename Scalar>
337struct Assignment<DstXprType, Homogeneous<ArgType,
Horizontal>, internal::assign_op<Scalar, typename ArgType::Scalar>,
339 using SrcXprType = Homogeneous<ArgType, Horizontal>;
340 EIGEN_DEVICE_FUNC
static void run(DstXprType& dst,
const SrcXprType& src,
341 const internal::assign_op<Scalar, typename ArgType::Scalar>&) {
342 Index dstRows = src.rows();
343 Index dstCols = src.cols();
344 if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
346 dst.template leftCols<ArgType::ColsAtCompileTime>(src.nestedExpression().cols()) = src.nestedExpression();
347 dst.col(dst.cols() - 1).setOnes();
351template <
typename LhsArg,
typename Rhs,
int ProductTag>
352struct generic_product_impl<Homogeneous<LhsArg,
Horizontal>, Rhs, HomogeneousShape, DenseShape, ProductTag> {
353 template <
typename Dest>
354 EIGEN_DEVICE_FUNC
static void evalTo(Dest& dst,
const Homogeneous<LhsArg, Horizontal>& lhs,
const Rhs& rhs) {
355 homogeneous_right_product_impl<Homogeneous<LhsArg, Horizontal>, Rhs>(lhs.nestedExpression(), rhs).evalTo(dst);
359template <
typename Lhs,
typename Rhs>
360struct homogeneous_right_product_refactoring_helper {
361 enum { Dim = Lhs::ColsAtCompileTime, Rows = Lhs::RowsAtCompileTime };
362 using LinearBlockConst =
typename Rhs::template ConstNRowsBlockXpr<Dim>::Type;
363 using LinearBlock = std::remove_const_t<LinearBlockConst>;
364 using ConstantColumn =
typename Rhs::ConstRowXpr;
365 using ConstantBlock = Replicate<const ConstantColumn, Rows, 1>;
366 using LinearProduct = Product<Lhs, LinearBlock, LazyProduct>;
367 using Xpr = CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar, typename Rhs::Scalar>,
const LinearProduct,
368 const ConstantBlock>;
371template <
typename Lhs,
typename Rhs,
int ProductTag>
372struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, HomogeneousShape, DenseShape>
374 typename homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression, Rhs>::Xpr> {
375 using XprType = Product<Lhs, Rhs, LazyProduct>;
376 using helper = homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression, Rhs>;
377 using ConstantBlock =
typename helper::ConstantBlock;
378 using RefactoredXpr =
typename helper::Xpr;
379 using Base = evaluator<RefactoredXpr>;
381 EIGEN_DEVICE_FUNC
explicit product_evaluator(
const XprType& xpr)
382 : Base(xpr.lhs().nestedExpression().lazyProduct(
383 xpr.rhs().template topRows<helper::Dim>(xpr.lhs().nestedExpression().cols())) +
384 ConstantBlock(xpr.rhs().row(xpr.rhs().rows() - 1), xpr.lhs().rows(), 1)) {}
387template <
typename Lhs,
typename RhsArg,
int ProductTag>
388struct generic_product_impl<Lhs, Homogeneous<RhsArg,
Vertical>, DenseShape, HomogeneousShape, ProductTag> {
389 template <
typename Dest>
390 EIGEN_DEVICE_FUNC
static void evalTo(Dest& dst,
const Lhs& lhs,
const Homogeneous<RhsArg, Vertical>& rhs) {
391 homogeneous_left_product_impl<Homogeneous<RhsArg, Vertical>, Lhs>(lhs, rhs.nestedExpression()).evalTo(dst);
395template <
typename Lhs,
typename RhsArg,
int ProductTag>
396struct generic_product_impl<Lhs, Homogeneous<RhsArg,
Vertical>, TriangularShape, HomogeneousShape, ProductTag> {
397 template <
typename Dest>
398 static void evalTo(Dest& dst,
const Lhs& lhs,
const Homogeneous<RhsArg, Vertical>& rhs) {
399 dst.noalias() = lhs * rhs.eval();
403template <
typename Lhs,
typename Rhs>
404struct homogeneous_left_product_refactoring_helper {
405 enum { Dim = Rhs::RowsAtCompileTime, Cols = Rhs::ColsAtCompileTime };
406 using LinearBlockConst =
typename Lhs::template ConstNColsBlockXpr<Dim>::Type;
407 using LinearBlock = std::remove_const_t<LinearBlockConst>;
408 using ConstantColumn =
typename Lhs::ConstColXpr;
409 using ConstantBlock = Replicate<const ConstantColumn, 1, Cols>;
410 using LinearProduct = Product<LinearBlock, Rhs, LazyProduct>;
411 using Xpr = CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar, typename Rhs::Scalar>,
const LinearProduct,
412 const ConstantBlock>;
415template <
typename Lhs,
typename Rhs,
int ProductTag>
416struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, HomogeneousShape>
417 :
public evaluator<typename homogeneous_left_product_refactoring_helper<Lhs, typename Rhs::NestedExpression>::Xpr> {
418 using XprType = Product<Lhs, Rhs, LazyProduct>;
419 using helper = homogeneous_left_product_refactoring_helper<Lhs, typename Rhs::NestedExpression>;
420 using ConstantBlock =
typename helper::ConstantBlock;
421 using RefactoredXpr =
typename helper::Xpr;
422 using Base = evaluator<RefactoredXpr>;
424 EIGEN_DEVICE_FUNC
explicit product_evaluator(
const XprType& xpr)
426 .template leftCols<helper::Dim>(xpr.rhs().nestedExpression().rows())
428 ConstantBlock(xpr.lhs().
col(xpr.lhs().cols() - 1), 1, xpr.rhs().cols())) {}
431template <
typename Scalar,
int Dim,
int Mode,
int Options,
typename RhsArg,
int ProductTag>
432struct generic_product_impl<Transform<Scalar, Dim, Mode, Options>, Homogeneous<RhsArg, Vertical>, DenseShape,
433 HomogeneousShape, ProductTag> {
435 template <
typename Dest>
437 homogeneous_left_product_impl<Homogeneous<RhsArg, Vertical>, TransformType>(lhs, rhs.nestedExpression())
442template <
typename ExpressionType,
int S
ide,
bool Transposed>
443struct permutation_matrix_product<ExpressionType, Side, Transposed, HomogeneousShape>
444 :
public permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape> {};
constexpr ColXpr col(Index i)
Definition DenseBase.h:1081
@ ColsAtCompileTime
Definition DenseBase.h:103
typename internal::traits< Homogeneous< MatrixType, Direction_ > >::Scalar Scalar
Definition DenseBase.h:63
Expression of one (or a set of) homogeneous vector(s)
Definition Homogeneous.h:63
const Product< MatrixWrapper< ExpressionType >, OtherDerived, LazyProduct > lazyProduct(const MatrixBase< OtherDerived > &other) const
Expression of the product of two arbitrary matrices or vectors.
Definition Product.h:203
Expression of the multiple replication of a matrix or vector.
Definition Replicate.h:65
const HNormalizedReturnType hnormalized() const
column or row-wise homogeneous normalization
Definition Homogeneous.h:190
const HNormalizedReturnType hnormalized() const
homogeneous normalization
Definition Homogeneous.h:165
HomogeneousReturnType homogeneous() const
Definition Homogeneous.h:125
HomogeneousReturnType homogeneous() const
Definition Homogeneous.h:142
@ Horizontal
Definition Constants.h:270
@ Vertical
Definition Constants.h:267
@ Projective
Definition Constants.h:479
constexpr unsigned int RowMajorBit
Definition Constants.h:71