MOAB
4.9.3pre
|
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