MOAB  4.9.3pre
Homogeneous.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009-2010 Gael Guennebaud <[email protected]>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_HOMOGENEOUS_H
00011 #define EIGEN_HOMOGENEOUS_H
00012 
00013 namespace Eigen { 
00014 
00030 namespace internal {
00031 
00032 template<typename MatrixType,int Direction>
00033 struct traits<Homogeneous<MatrixType,Direction> >
00034  : traits<MatrixType>
00035 {
00036   typedef typename traits<MatrixType>::StorageKind StorageKind;
00037   typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
00038   typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
00039   enum {
00040     RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ?
00041                   int(MatrixType::RowsAtCompileTime) + 1 : Dynamic,
00042     ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ?
00043                   int(MatrixType::ColsAtCompileTime) + 1 : Dynamic,
00044     RowsAtCompileTime = Direction==Vertical  ?  RowsPlusOne : MatrixType::RowsAtCompileTime,
00045     ColsAtCompileTime = Direction==Horizontal ? ColsPlusOne : MatrixType::ColsAtCompileTime,
00046     MaxRowsAtCompileTime = RowsAtCompileTime,
00047     MaxColsAtCompileTime = ColsAtCompileTime,
00048     TmpFlags = _MatrixTypeNested::Flags & HereditaryBits,
00049     Flags = ColsAtCompileTime==1 ? (TmpFlags & ~RowMajorBit)
00050           : RowsAtCompileTime==1 ? (TmpFlags | RowMajorBit)
00051           : TmpFlags
00052   };
00053 };
00054 
00055 template<typename MatrixType,typename Lhs> struct homogeneous_left_product_impl;
00056 template<typename MatrixType,typename Rhs> struct homogeneous_right_product_impl;
00057 
00058 } // end namespace internal
00059 
00060 template<typename MatrixType,int _Direction> class Homogeneous
00061   : public MatrixBase<Homogeneous<MatrixType,_Direction> >, internal::no_assignment_operator
00062 {
00063   public:
00064 
00065     typedef MatrixType NestedExpression;
00066     enum { Direction = _Direction };
00067 
00068     typedef MatrixBase<Homogeneous> Base;
00069     EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous)
00070 
00071     explicit inline Homogeneous(const MatrixType& matrix)
00072       : m_matrix(matrix)
00073     {}
00074 
00075     inline Index rows() const { return m_matrix.rows() + (int(Direction)==Vertical   ? 1 : 0); }
00076     inline Index cols() const { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); }
00077     
00078     const NestedExpression& nestedExpression() const { return m_matrix; }
00079 
00080     template<typename Rhs>
00081     inline const Product<Homogeneous,Rhs>
00082     operator* (const MatrixBase<Rhs>& rhs) const
00083     {
00084       eigen_assert(int(Direction)==Horizontal);
00085       return Product<Homogeneous,Rhs>(*this,rhs.derived());
00086     }
00087 
00088     template<typename Lhs> friend
00089     inline const Product<Lhs,Homogeneous>
00090     operator* (const MatrixBase<Lhs>& lhs, const Homogeneous& rhs)
00091     {
00092       eigen_assert(int(Direction)==Vertical);
00093       return Product<Lhs,Homogeneous>(lhs.derived(),rhs);
00094     }
00095 
00096     template<typename Scalar, int Dim, int Mode, int Options> friend
00097     inline const Product<Transform<Scalar,Dim,Mode,Options>, Homogeneous >
00098     operator* (const Transform<Scalar,Dim,Mode,Options>& lhs, const Homogeneous& rhs)
00099     {
00100       eigen_assert(int(Direction)==Vertical);
00101       return Product<Transform<Scalar,Dim,Mode,Options>, Homogeneous>(lhs,rhs);
00102     }
00103 
00104     template<typename Func>
00105     EIGEN_STRONG_INLINE typename internal::result_of<Func(Scalar,Scalar)>::type
00106     redux(const Func& func) const
00107     {
00108       return func(m_matrix.redux(func), Scalar(1));
00109     }
00110 
00111   protected:
00112     typename MatrixType::Nested m_matrix;
00113 };
00114 
00126 template<typename Derived>
00127 inline typename MatrixBase<Derived>::HomogeneousReturnType
00128 MatrixBase<Derived>::homogeneous() const
00129 {
00130   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
00131   return HomogeneousReturnType(derived());
00132 }
00133 
00142 template<typename ExpressionType, int Direction>
00143 inline Homogeneous<ExpressionType,Direction>
00144 VectorwiseOp<ExpressionType,Direction>::homogeneous() const
00145 {
00146   return HomogeneousReturnType(_expression());
00147 }
00148 
00157 template<typename Derived>
00158 inline const typename MatrixBase<Derived>::HNormalizedReturnType
00159 MatrixBase<Derived>::hnormalized() const
00160 {
00161   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
00162   return ConstStartMinusOne(derived(),0,0,
00163     ColsAtCompileTime==1?size()-1:1,
00164     ColsAtCompileTime==1?1:size()-1) / coeff(size()-1);
00165 }
00166 
00175 template<typename ExpressionType, int Direction>
00176 inline const typename VectorwiseOp<ExpressionType,Direction>::HNormalizedReturnType
00177 VectorwiseOp<ExpressionType,Direction>::hnormalized() const
00178 {
00179   return HNormalized_Block(_expression(),0,0,
00180       Direction==Vertical   ? _expression().rows()-1 : _expression().rows(),
00181       Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient(
00182       Replicate<HNormalized_Factors,
00183                 Direction==Vertical   ? HNormalized_SizeMinusOne : 1,
00184                 Direction==Horizontal ? HNormalized_SizeMinusOne : 1>
00185         (HNormalized_Factors(_expression(),
00186           Direction==Vertical    ? _expression().rows()-1:0,
00187           Direction==Horizontal  ? _expression().cols()-1:0,
00188           Direction==Vertical    ? 1 : _expression().rows(),
00189           Direction==Horizontal  ? 1 : _expression().cols()),
00190          Direction==Vertical   ? _expression().rows()-1 : 1,
00191          Direction==Horizontal ? _expression().cols()-1 : 1));
00192 }
00193 
00194 namespace internal {
00195 
00196 template<typename MatrixOrTransformType>
00197 struct take_matrix_for_product
00198 {
00199   typedef MatrixOrTransformType type;
00200   static const type& run(const type &x) { return x; }
00201 };
00202 
00203 template<typename Scalar, int Dim, int Mode,int Options>
00204 struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> >
00205 {
00206   typedef Transform<Scalar, Dim, Mode, Options> TransformType;
00207   typedef typename internal::add_const<typename TransformType::ConstAffinePart>::type type;
00208   static type run (const TransformType& x) { return x.affine(); }
00209 };
00210 
00211 template<typename Scalar, int Dim, int Options>
00212 struct take_matrix_for_product<Transform<Scalar, Dim, Projective, Options> >
00213 {
00214   typedef Transform<Scalar, Dim, Projective, Options> TransformType;
00215   typedef typename TransformType::MatrixType type;
00216   static const type& run (const TransformType& x) { return x.matrix(); }
00217 };
00218 
00219 template<typename MatrixType,typename Lhs>
00220 struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
00221 {
00222   typedef typename take_matrix_for_product<Lhs>::type LhsMatrixType;
00223   typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
00224   typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned;
00225   typedef typename make_proper_matrix_type<
00226                  typename traits<MatrixTypeCleaned>::Scalar,
00227                  LhsMatrixTypeCleaned::RowsAtCompileTime,
00228                  MatrixTypeCleaned::ColsAtCompileTime,
00229                  MatrixTypeCleaned::PlainObject::Options,
00230                  LhsMatrixTypeCleaned::MaxRowsAtCompileTime,
00231                  MatrixTypeCleaned::MaxColsAtCompileTime>::type ReturnType;
00232 };
00233 
00234 template<typename MatrixType,typename Lhs>
00235 struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs>
00236   : public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
00237 {
00238   typedef typename traits<homogeneous_left_product_impl>::LhsMatrixType LhsMatrixType;
00239   typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned;
00240   typedef typename remove_all<typename LhsMatrixTypeCleaned::Nested>::type LhsMatrixTypeNested;
00241   homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs)
00242     : m_lhs(take_matrix_for_product<Lhs>::run(lhs)),
00243       m_rhs(rhs)
00244   {}
00245 
00246   inline Index rows() const { return m_lhs.rows(); }
00247   inline Index cols() const { return m_rhs.cols(); }
00248 
00249   template<typename Dest> void evalTo(Dest& dst) const
00250   {
00251     // FIXME investigate how to allow lazy evaluation of this product when possible
00252     dst = Block<const LhsMatrixTypeNested,
00253               LhsMatrixTypeNested::RowsAtCompileTime,
00254               LhsMatrixTypeNested::ColsAtCompileTime==Dynamic?Dynamic:LhsMatrixTypeNested::ColsAtCompileTime-1>
00255             (m_lhs,0,0,m_lhs.rows(),m_lhs.cols()-1) * m_rhs;
00256     dst += m_lhs.col(m_lhs.cols()-1).rowwise()
00257             .template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols());
00258   }
00259 
00260   typename LhsMatrixTypeCleaned::Nested m_lhs;
00261   typename MatrixType::Nested m_rhs;
00262 };
00263 
00264 template<typename MatrixType,typename Rhs>
00265 struct traits<homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs> >
00266 {
00267   typedef typename make_proper_matrix_type<typename traits<MatrixType>::Scalar,
00268                  MatrixType::RowsAtCompileTime,
00269                  Rhs::ColsAtCompileTime,
00270                  MatrixType::PlainObject::Options,
00271                  MatrixType::MaxRowsAtCompileTime,
00272                  Rhs::MaxColsAtCompileTime>::type ReturnType;
00273 };
00274 
00275 template<typename MatrixType,typename Rhs>
00276 struct homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs>
00277   : public ReturnByValue<homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs> >
00278 {
00279   typedef typename remove_all<typename Rhs::Nested>::type RhsNested;
00280   homogeneous_right_product_impl(const MatrixType& lhs, const Rhs& rhs)
00281     : m_lhs(lhs), m_rhs(rhs)
00282   {}
00283 
00284   inline Index rows() const { return m_lhs.rows(); }
00285   inline Index cols() const { return m_rhs.cols(); }
00286 
00287   template<typename Dest> void evalTo(Dest& dst) const
00288   {
00289     // FIXME investigate how to allow lazy evaluation of this product when possible
00290     dst = m_lhs * Block<const RhsNested,
00291                         RhsNested::RowsAtCompileTime==Dynamic?Dynamic:RhsNested::RowsAtCompileTime-1,
00292                         RhsNested::ColsAtCompileTime>
00293             (m_rhs,0,0,m_rhs.rows()-1,m_rhs.cols());
00294     dst += m_rhs.row(m_rhs.rows()-1).colwise()
00295             .template replicate<MatrixType::RowsAtCompileTime>(m_lhs.rows());
00296   }
00297 
00298   typename MatrixType::Nested m_lhs;
00299   typename Rhs::Nested m_rhs;
00300 };
00301 
00302 template<typename ArgType,int Direction>
00303 struct evaluator_traits<Homogeneous<ArgType,Direction> >
00304 {
00305   typedef typename storage_kind_to_evaluator_kind<typename ArgType::StorageKind>::Kind Kind;
00306   typedef HomogeneousShape Shape;  
00307 };
00308 
00309 template<> struct AssignmentKind<DenseShape,HomogeneousShape> { typedef Dense2Dense Kind; };
00310 
00311 
00312 template<typename ArgType,int Direction>
00313 struct unary_evaluator<Homogeneous<ArgType,Direction>, IndexBased>
00314   : evaluator<typename Homogeneous<ArgType,Direction>::PlainObject >
00315 {
00316   typedef Homogeneous<ArgType,Direction> XprType;
00317   typedef typename XprType::PlainObject PlainObject;
00318   typedef evaluator<PlainObject> Base;
00319 
00320   explicit unary_evaluator(const XprType& op)
00321     : Base(), m_temp(op)
00322   {
00323     ::new (static_cast<Base*>(this)) Base(m_temp);
00324   }
00325 
00326 protected:
00327   PlainObject m_temp;
00328 };
00329 
00330 // dense = homogeneous
00331 template< typename DstXprType, typename ArgType, typename Scalar>
00332 struct Assignment<DstXprType, Homogeneous<ArgType,Vertical>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
00333 {
00334   typedef Homogeneous<ArgType,Vertical> SrcXprType;
00335   static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
00336   {
00337     dst.template topRows<ArgType::RowsAtCompileTime>(src.nestedExpression().rows()) = src.nestedExpression();
00338     dst.row(dst.rows()-1).setOnes();
00339   }
00340 };
00341 
00342 // dense = homogeneous
00343 template< typename DstXprType, typename ArgType, typename Scalar>
00344 struct Assignment<DstXprType, Homogeneous<ArgType,Horizontal>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
00345 {
00346   typedef Homogeneous<ArgType,Horizontal> SrcXprType;
00347   static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
00348   {
00349     dst.template leftCols<ArgType::ColsAtCompileTime>(src.nestedExpression().cols()) = src.nestedExpression();
00350     dst.col(dst.cols()-1).setOnes();
00351   }
00352 };
00353 
00354 template<typename LhsArg, typename Rhs, int ProductTag>
00355 struct generic_product_impl<Homogeneous<LhsArg,Horizontal>, Rhs, HomogeneousShape, DenseShape, ProductTag>
00356 {
00357   template<typename Dest>
00358   static void evalTo(Dest& dst, const Homogeneous<LhsArg,Horizontal>& lhs, const Rhs& rhs)
00359   {
00360     homogeneous_right_product_impl<Homogeneous<LhsArg,Horizontal>, Rhs>(lhs.nestedExpression(), rhs).evalTo(dst);
00361   }
00362 };
00363 
00364 template<typename Lhs,typename Rhs>
00365 struct homogeneous_right_product_refactoring_helper
00366 {
00367   enum {
00368     Dim  = Lhs::ColsAtCompileTime,
00369     Rows = Lhs::RowsAtCompileTime
00370   };
00371   typedef typename Rhs::template ConstNRowsBlockXpr<Dim>::Type          LinearBlockConst;
00372   typedef typename remove_const<LinearBlockConst>::type                 LinearBlock;
00373   typedef typename Rhs::ConstRowXpr                                     ConstantColumn;
00374   typedef Replicate<const ConstantColumn,Rows,1>                        ConstantBlock;
00375   typedef Product<Lhs,LinearBlock,LazyProduct>                          LinearProduct;
00376   typedef CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar>, const LinearProduct, const ConstantBlock> Xpr;
00377 };
00378 
00379 template<typename Lhs, typename Rhs, int ProductTag>
00380 struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, HomogeneousShape, DenseShape>
00381  : public evaluator<typename homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression,Rhs>::Xpr>
00382 {
00383   typedef Product<Lhs, Rhs, LazyProduct> XprType;
00384   typedef homogeneous_right_product_refactoring_helper<typename Lhs::NestedExpression,Rhs> helper;
00385   typedef typename helper::ConstantBlock ConstantBlock;
00386   typedef typename helper::Xpr RefactoredXpr;
00387   typedef evaluator<RefactoredXpr> Base;
00388   
00389   EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
00390     : Base(  xpr.lhs().nestedExpression() .lazyProduct(  xpr.rhs().template topRows<helper::Dim>(xpr.lhs().nestedExpression().cols()) )
00391             + ConstantBlock(xpr.rhs().row(xpr.rhs().rows()-1),xpr.lhs().rows(), 1) )
00392   {}
00393 };
00394 
00395 template<typename Lhs, typename RhsArg, int ProductTag>
00396 struct generic_product_impl<Lhs, Homogeneous<RhsArg,Vertical>, DenseShape, HomogeneousShape, ProductTag>
00397 {
00398   template<typename Dest>
00399   static void evalTo(Dest& dst, const Lhs& lhs, const Homogeneous<RhsArg,Vertical>& rhs)
00400   {
00401     homogeneous_left_product_impl<Homogeneous<RhsArg,Vertical>, Lhs>(lhs, rhs.nestedExpression()).evalTo(dst);
00402   }
00403 };
00404 
00405 template<typename Lhs,typename Rhs>
00406 struct homogeneous_left_product_refactoring_helper
00407 {
00408   enum {
00409     Dim = Rhs::RowsAtCompileTime,
00410     Cols = Rhs::ColsAtCompileTime
00411   };
00412   typedef typename Lhs::template ConstNColsBlockXpr<Dim>::Type          LinearBlockConst;
00413   typedef typename remove_const<LinearBlockConst>::type                 LinearBlock;
00414   typedef typename Lhs::ConstColXpr                                     ConstantColumn;
00415   typedef Replicate<const ConstantColumn,1,Cols>                        ConstantBlock;
00416   typedef Product<LinearBlock,Rhs,LazyProduct>                          LinearProduct;
00417   typedef CwiseBinaryOp<internal::scalar_sum_op<typename Lhs::Scalar>, const LinearProduct, const ConstantBlock> Xpr;
00418 };
00419 
00420 template<typename Lhs, typename Rhs, int ProductTag>
00421 struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, HomogeneousShape>
00422  : public evaluator<typename homogeneous_left_product_refactoring_helper<Lhs,typename Rhs::NestedExpression>::Xpr>
00423 {
00424   typedef Product<Lhs, Rhs, LazyProduct> XprType;
00425   typedef homogeneous_left_product_refactoring_helper<Lhs,typename Rhs::NestedExpression> helper;
00426   typedef typename helper::ConstantBlock ConstantBlock;
00427   typedef typename helper::Xpr RefactoredXpr;
00428   typedef evaluator<RefactoredXpr> Base;
00429   
00430   EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
00431     : Base(   xpr.lhs().template leftCols<helper::Dim>(xpr.rhs().nestedExpression().rows()) .lazyProduct( xpr.rhs().nestedExpression() )
00432             + ConstantBlock(xpr.lhs().col(xpr.lhs().cols()-1),1,xpr.rhs().cols()) )
00433   {}
00434 };
00435 
00436 template<typename Scalar, int Dim, int Mode,int Options, typename RhsArg, int ProductTag>
00437 struct generic_product_impl<Transform<Scalar,Dim,Mode,Options>, Homogeneous<RhsArg,Vertical>, DenseShape, HomogeneousShape, ProductTag>
00438 {
00439   typedef Transform<Scalar,Dim,Mode,Options> TransformType;
00440   template<typename Dest>
00441   static void evalTo(Dest& dst, const TransformType& lhs, const Homogeneous<RhsArg,Vertical>& rhs)
00442   {
00443     homogeneous_left_product_impl<Homogeneous<RhsArg,Vertical>, TransformType>(lhs, rhs.nestedExpression()).evalTo(dst);
00444   }
00445 };
00446 
00447 template<typename ExpressionType, int Side, bool Transposed>
00448 struct permutation_matrix_product<ExpressionType, Side, Transposed, HomogeneousShape>
00449   : public permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
00450 {};
00451 
00452 } // end namespace internal
00453 
00454 } // end namespace Eigen
00455 
00456 #endif // EIGEN_HOMOGENEOUS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines