$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> 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 nested<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 CoeffReadCost = _MatrixTypeNested::CoeffReadCost 00053 }; 00054 }; 00055 00056 template<typename MatrixType,typename Lhs> struct homogeneous_left_product_impl; 00057 template<typename MatrixType,typename Rhs> struct homogeneous_right_product_impl; 00058 00059 } // end namespace internal 00060 00061 template<typename MatrixType,int _Direction> class Homogeneous 00062 : internal::no_assignment_operator, public MatrixBase<Homogeneous<MatrixType,_Direction> > 00063 { 00064 public: 00065 00066 enum { Direction = _Direction }; 00067 00068 typedef MatrixBase<Homogeneous> Base; 00069 EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous) 00070 00071 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 inline Scalar coeff(Index row, Index col) const 00079 { 00080 if( (int(Direction)==Vertical && row==m_matrix.rows()) 00081 || (int(Direction)==Horizontal && col==m_matrix.cols())) 00082 return Scalar(1); 00083 return m_matrix.coeff(row, col); 00084 } 00085 00086 template<typename Rhs> 00087 inline const internal::homogeneous_right_product_impl<Homogeneous,Rhs> 00088 operator* (const MatrixBase<Rhs>& rhs) const 00089 { 00090 eigen_assert(int(Direction)==Horizontal); 00091 return internal::homogeneous_right_product_impl<Homogeneous,Rhs>(m_matrix,rhs.derived()); 00092 } 00093 00094 template<typename Lhs> friend 00095 inline const internal::homogeneous_left_product_impl<Homogeneous,Lhs> 00096 operator* (const MatrixBase<Lhs>& lhs, const Homogeneous& rhs) 00097 { 00098 eigen_assert(int(Direction)==Vertical); 00099 return internal::homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix); 00100 } 00101 00102 template<typename Scalar, int Dim, int Mode, int Options> friend 00103 inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> > 00104 operator* (const Transform<Scalar,Dim,Mode,Options>& lhs, const Homogeneous& rhs) 00105 { 00106 eigen_assert(int(Direction)==Vertical); 00107 return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >(lhs,rhs.m_matrix); 00108 } 00109 00110 protected: 00111 typename MatrixType::Nested m_matrix; 00112 }; 00113 00125 template<typename Derived> 00126 inline typename MatrixBase<Derived>::HomogeneousReturnType 00127 MatrixBase<Derived>::homogeneous() const 00128 { 00129 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); 00130 return derived(); 00131 } 00132 00141 template<typename ExpressionType, int Direction> 00142 inline Homogeneous<ExpressionType,Direction> 00143 VectorwiseOp<ExpressionType,Direction>::homogeneous() const 00144 { 00145 return _expression(); 00146 } 00147 00156 template<typename Derived> 00157 inline const typename MatrixBase<Derived>::HNormalizedReturnType 00158 MatrixBase<Derived>::hnormalized() const 00159 { 00160 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); 00161 return ConstStartMinusOne(derived(),0,0, 00162 ColsAtCompileTime==1?size()-1:1, 00163 ColsAtCompileTime==1?1:size()-1) / coeff(size()-1); 00164 } 00165 00174 template<typename ExpressionType, int Direction> 00175 inline const typename VectorwiseOp<ExpressionType,Direction>::HNormalizedReturnType 00176 VectorwiseOp<ExpressionType,Direction>::hnormalized() const 00177 { 00178 return HNormalized_Block(_expression(),0,0, 00179 Direction==Vertical ? _expression().rows()-1 : _expression().rows(), 00180 Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient( 00181 Replicate<HNormalized_Factors, 00182 Direction==Vertical ? HNormalized_SizeMinusOne : 1, 00183 Direction==Horizontal ? HNormalized_SizeMinusOne : 1> 00184 (HNormalized_Factors(_expression(), 00185 Direction==Vertical ? _expression().rows()-1:0, 00186 Direction==Horizontal ? _expression().cols()-1:0, 00187 Direction==Vertical ? 1 : _expression().rows(), 00188 Direction==Horizontal ? 1 : _expression().cols()), 00189 Direction==Vertical ? _expression().rows()-1 : 1, 00190 Direction==Horizontal ? _expression().cols()-1 : 1)); 00191 } 00192 00193 namespace internal { 00194 00195 template<typename MatrixOrTransformType> 00196 struct take_matrix_for_product 00197 { 00198 typedef MatrixOrTransformType type; 00199 static const type& run(const type &x) { return x; } 00200 }; 00201 00202 template<typename Scalar, int Dim, int Mode,int Options> 00203 struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> > 00204 { 00205 typedef Transform<Scalar, Dim, Mode, Options> TransformType; 00206 typedef typename internal::add_const<typename TransformType::ConstAffinePart>::type type; 00207 static type run (const TransformType& x) { return x.affine(); } 00208 }; 00209 00210 template<typename Scalar, int Dim, int Options> 00211 struct take_matrix_for_product<Transform<Scalar, Dim, Projective, Options> > 00212 { 00213 typedef Transform<Scalar, Dim, Projective, Options> TransformType; 00214 typedef typename TransformType::MatrixType type; 00215 static const type& run (const TransformType& x) { return x.matrix(); } 00216 }; 00217 00218 template<typename MatrixType,typename Lhs> 00219 struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> > 00220 { 00221 typedef typename take_matrix_for_product<Lhs>::type LhsMatrixType; 00222 typedef typename remove_all<MatrixType>::type MatrixTypeCleaned; 00223 typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned; 00224 typedef typename make_proper_matrix_type< 00225 typename traits<MatrixTypeCleaned>::Scalar, 00226 LhsMatrixTypeCleaned::RowsAtCompileTime, 00227 MatrixTypeCleaned::ColsAtCompileTime, 00228 MatrixTypeCleaned::PlainObject::Options, 00229 LhsMatrixTypeCleaned::MaxRowsAtCompileTime, 00230 MatrixTypeCleaned::MaxColsAtCompileTime>::type ReturnType; 00231 }; 00232 00233 template<typename MatrixType,typename Lhs> 00234 struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> 00235 : public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> > 00236 { 00237 typedef typename traits<homogeneous_left_product_impl>::LhsMatrixType LhsMatrixType; 00238 typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned; 00239 typedef typename remove_all<typename LhsMatrixTypeCleaned::Nested>::type LhsMatrixTypeNested; 00240 typedef typename MatrixType::Index Index; 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 typedef typename MatrixType::Index Index; 00281 homogeneous_right_product_impl(const MatrixType& lhs, const Rhs& rhs) 00282 : m_lhs(lhs), m_rhs(rhs) 00283 {} 00284 00285 inline Index rows() const { return m_lhs.rows(); } 00286 inline Index cols() const { return m_rhs.cols(); } 00287 00288 template<typename Dest> void evalTo(Dest& dst) const 00289 { 00290 // FIXME investigate how to allow lazy evaluation of this product when possible 00291 dst = m_lhs * Block<const RhsNested, 00292 RhsNested::RowsAtCompileTime==Dynamic?Dynamic:RhsNested::RowsAtCompileTime-1, 00293 RhsNested::ColsAtCompileTime> 00294 (m_rhs,0,0,m_rhs.rows()-1,m_rhs.cols()); 00295 dst += m_rhs.row(m_rhs.rows()-1).colwise() 00296 .template replicate<MatrixType::RowsAtCompileTime>(m_lhs.rows()); 00297 } 00298 00299 typename MatrixType::Nested m_lhs; 00300 typename Rhs::Nested m_rhs; 00301 }; 00302 00303 } // end namespace internal 00304 00305 } // end namespace Eigen 00306 00307 #endif // EIGEN_HOMOGENEOUS_H