00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_MATRIX_H
00026 #define EIGEN_MATRIX_H
00027
00028 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00029 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
00030 #else
00031 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00032 #endif
00033
00112 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00113 struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00114 {
00115 typedef _Scalar Scalar;
00116 enum {
00117 RowsAtCompileTime = _Rows,
00118 ColsAtCompileTime = _Cols,
00119 MaxRowsAtCompileTime = _MaxRows,
00120 MaxColsAtCompileTime = _MaxCols,
00121 Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
00122 CoeffReadCost = NumTraits<Scalar>::ReadCost
00123 };
00124 };
00125
00126 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00127 class Matrix
00128 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00129 {
00130 public:
00131 EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
00132 enum { Options = _Options };
00133 friend class Eigen::Map<Matrix, Unaligned>;
00134 typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
00135 friend class Eigen::Map<Matrix, Aligned>;
00136 typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
00137
00138 protected:
00139 ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
00140
00141 public:
00142 enum { NeedsToAlign = (Options&AutoAlign) == AutoAlign
00143 && SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 };
00144 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00145
00146 Base& base() { return *static_cast<Base*>(this); }
00147 const Base& base() const { return *static_cast<const Base*>(this); }
00148
00149 EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
00150 EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); }
00151
00152 EIGEN_STRONG_INLINE int stride(void) const
00153 {
00154 if(Flags & RowMajorBit)
00155 return m_storage.cols();
00156 else
00157 return m_storage.rows();
00158 }
00159
00160 EIGEN_STRONG_INLINE const Scalar& coeff(int row, int col) const
00161 {
00162 if(Flags & RowMajorBit)
00163 return m_storage.data()[col + row * m_storage.cols()];
00164 else
00165 return m_storage.data()[row + col * m_storage.rows()];
00166 }
00167
00168 EIGEN_STRONG_INLINE const Scalar& coeff(int index) const
00169 {
00170 return m_storage.data()[index];
00171 }
00172
00173 EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col)
00174 {
00175 if(Flags & RowMajorBit)
00176 return m_storage.data()[col + row * m_storage.cols()];
00177 else
00178 return m_storage.data()[row + col * m_storage.rows()];
00179 }
00180
00181 EIGEN_STRONG_INLINE Scalar& coeffRef(int index)
00182 {
00183 return m_storage.data()[index];
00184 }
00185
00186 template<int LoadMode>
00187 EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
00188 {
00189 return ei_ploadt<Scalar, LoadMode>
00190 (m_storage.data() + (Flags & RowMajorBit
00191 ? col + row * m_storage.cols()
00192 : row + col * m_storage.rows()));
00193 }
00194
00195 template<int LoadMode>
00196 EIGEN_STRONG_INLINE PacketScalar packet(int index) const
00197 {
00198 return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index);
00199 }
00200
00201 template<int StoreMode>
00202 EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x)
00203 {
00204 ei_pstoret<Scalar, PacketScalar, StoreMode>
00205 (m_storage.data() + (Flags & RowMajorBit
00206 ? col + row * m_storage.cols()
00207 : row + col * m_storage.rows()), x);
00208 }
00209
00210 template<int StoreMode>
00211 EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x)
00212 {
00213 ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
00214 }
00215
00217 EIGEN_STRONG_INLINE const Scalar *data() const
00218 { return m_storage.data(); }
00219
00221 EIGEN_STRONG_INLINE Scalar *data()
00222 { return m_storage.data(); }
00223
00235 inline void resize(int rows, int cols)
00236 {
00237 ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows)
00238 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00239 && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
00240 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00241 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00242 int size = rows*cols;
00243 bool size_changed = size != this->size();
00244 m_storage.resize(size, rows, cols);
00245 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00246 #else
00247 m_storage.resize(rows*cols, rows, cols);
00248 #endif
00249 }
00250
00255 inline void resize(int size)
00256 {
00257 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
00258 ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00259 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00260 bool size_changed = size != this->size();
00261 #endif
00262 if(RowsAtCompileTime == 1)
00263 m_storage.resize(size, 1, size);
00264 else
00265 m_storage.resize(size, size, 1);
00266 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00267 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00268 #endif
00269 }
00270
00280 template<typename OtherDerived>
00281 EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
00282 {
00283 return _set(other);
00284 }
00285
00289 EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
00290 {
00291 return _set(other);
00292 }
00293
00294 EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=)
00295 EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, -=)
00296 EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, *=)
00297 EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, /=)
00298
00309 EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
00310 {
00311 _check_template_params();
00312 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00313 }
00314
00315 #ifndef EIGEN_PARSED_BY_DOXYGEN
00316
00317 Matrix(ei_constructor_without_unaligned_array_assert)
00318 : m_storage(ei_constructor_without_unaligned_array_assert())
00319 {EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED}
00320 #endif
00321
00328 EIGEN_STRONG_INLINE explicit Matrix(int dim)
00329 : m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
00330 {
00331 _check_template_params();
00332 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
00333 ei_assert(dim > 0);
00334 ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
00335 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00336 }
00337
00348 EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y)
00349 {
00350 _check_template_params();
00351 if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
00352 || (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
00353 {
00354 m_storage.data()[0] = Scalar(x);
00355 m_storage.data()[1] = Scalar(y);
00356 }
00357 else
00358 {
00359 ei_assert(x > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == x)
00360 && y > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == y));
00361 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00362 }
00363 }
00365 EIGEN_STRONG_INLINE Matrix(const float& x, const float& y)
00366 {
00367 _check_template_params();
00368 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
00369 m_storage.data()[0] = x;
00370 m_storage.data()[1] = y;
00371 }
00373 EIGEN_STRONG_INLINE Matrix(const double& x, const double& y)
00374 {
00375 _check_template_params();
00376 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
00377 m_storage.data()[0] = x;
00378 m_storage.data()[1] = y;
00379 }
00381 EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
00382 {
00383 _check_template_params();
00384 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
00385 m_storage.data()[0] = x;
00386 m_storage.data()[1] = y;
00387 m_storage.data()[2] = z;
00388 }
00390 EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
00391 {
00392 _check_template_params();
00393 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
00394 m_storage.data()[0] = x;
00395 m_storage.data()[1] = y;
00396 m_storage.data()[2] = z;
00397 m_storage.data()[3] = w;
00398 }
00399
00400 explicit Matrix(const Scalar *data);
00401
00403 template<typename OtherDerived>
00404 EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
00405 : m_storage(other.rows() * other.cols(), other.rows(), other.cols())
00406 {
00407 _check_template_params();
00408 _set_noalias(other);
00409 }
00411 EIGEN_STRONG_INLINE Matrix(const Matrix& other)
00412 : Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols())
00413 {
00414 _check_template_params();
00415 _set_noalias(other);
00416 }
00418 inline ~Matrix() {}
00419
00423 template<typename OtherDerived>
00424 void swap(const MatrixBase<OtherDerived>& other);
00425
00435 inline static const UnalignedMapType Map(const Scalar* data)
00436 { return UnalignedMapType(data); }
00437 inline static UnalignedMapType Map(Scalar* data)
00438 { return UnalignedMapType(data); }
00439 inline static const UnalignedMapType Map(const Scalar* data, int size)
00440 { return UnalignedMapType(data, size); }
00441 inline static UnalignedMapType Map(Scalar* data, int size)
00442 { return UnalignedMapType(data, size); }
00443 inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols)
00444 { return UnalignedMapType(data, rows, cols); }
00445 inline static UnalignedMapType Map(Scalar* data, int rows, int cols)
00446 { return UnalignedMapType(data, rows, cols); }
00447
00448 inline static const AlignedMapType MapAligned(const Scalar* data)
00449 { return AlignedMapType(data); }
00450 inline static AlignedMapType MapAligned(Scalar* data)
00451 { return AlignedMapType(data); }
00452 inline static const AlignedMapType MapAligned(const Scalar* data, int size)
00453 { return AlignedMapType(data, size); }
00454 inline static AlignedMapType MapAligned(Scalar* data, int size)
00455 { return AlignedMapType(data, size); }
00456 inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols)
00457 { return AlignedMapType(data, rows, cols); }
00458 inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols)
00459 { return AlignedMapType(data, rows, cols); }
00461
00462 using Base::setConstant;
00463 Matrix& setConstant(int size, const Scalar& value);
00464 Matrix& setConstant(int rows, int cols, const Scalar& value);
00465
00466 using Base::setZero;
00467 Matrix& setZero(int size);
00468 Matrix& setZero(int rows, int cols);
00469
00470 using Base::setOnes;
00471 Matrix& setOnes(int size);
00472 Matrix& setOnes(int rows, int cols);
00473
00474 using Base::setRandom;
00475 Matrix& setRandom(int size);
00476 Matrix& setRandom(int rows, int cols);
00477
00478 using Base::setIdentity;
00479 Matrix& setIdentity(int rows, int cols);
00480
00482
00483 template<typename OtherDerived>
00484 explicit Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
00485 template<typename OtherDerived>
00486 Matrix& operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
00487
00488
00489 #ifdef EIGEN_MATRIX_PLUGIN
00490 #include EIGEN_MATRIX_PLUGIN
00491 #endif
00492
00493 private:
00501 template<typename OtherDerived>
00502 EIGEN_STRONG_INLINE void _resize_to_match(const MatrixBase<OtherDerived>& other)
00503 {
00504 if(RowsAtCompileTime == 1)
00505 {
00506 ei_assert(other.isVector());
00507 resize(1, other.size());
00508 }
00509 else if(ColsAtCompileTime == 1)
00510 {
00511 ei_assert(other.isVector());
00512 resize(other.size(), 1);
00513 }
00514 else resize(other.rows(), other.cols());
00515 }
00516
00528 template<typename OtherDerived>
00529 EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other)
00530 {
00531
00532 enum { cond = int(OtherDerived::Flags) & EvalBeforeAssigningBit };
00533 _set_selector(other.derived(), typename ei_meta_if<bool(cond), ei_meta_true, ei_meta_false>::ret());
00534 return *this;
00535 }
00536
00537 template<typename OtherDerived>
00538 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_true&) { _set_noalias(other.eval()); }
00539
00540 template<typename OtherDerived>
00541 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_false&) { _set_noalias(other); }
00542
00548 template<typename OtherDerived>
00549 EIGEN_STRONG_INLINE Matrix& _set_noalias(const MatrixBase<OtherDerived>& other)
00550 {
00551 _resize_to_match(other);
00552
00553
00554 return ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived());
00555 }
00556
00557 static EIGEN_STRONG_INLINE void _check_template_params()
00558 {
00559 EIGEN_STATIC_ASSERT((_Rows > 0
00560 && _Cols > 0
00561 && _MaxRows <= _Rows
00562 && _MaxCols <= _Cols
00563 && (_Options & (AutoAlign|RowMajor)) == _Options),
00564 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00565 }
00566
00567 template<typename MatrixType, typename OtherDerived, bool IsSameType, bool IsDynamicSize>
00568 friend struct ei_matrix_swap_impl;
00569 };
00570
00571 template<typename MatrixType, typename OtherDerived,
00572 bool IsSameType = ei_is_same_type<MatrixType, OtherDerived>::ret,
00573 bool IsDynamicSize = MatrixType::SizeAtCompileTime==Dynamic>
00574 struct ei_matrix_swap_impl
00575 {
00576 static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
00577 {
00578 matrix.base().swap(other);
00579 }
00580 };
00581
00582 template<typename MatrixType, typename OtherDerived>
00583 struct ei_matrix_swap_impl<MatrixType, OtherDerived, true, true>
00584 {
00585 static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
00586 {
00587 matrix.m_storage.swap(other.derived().m_storage);
00588 }
00589 };
00590
00591 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00592 template<typename OtherDerived>
00593 inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
00594 {
00595
00596 Eigen::ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
00597 }
00598
00599
00620 #define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \
00621 \
00622 typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \
00623 \
00624 typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; \
00625 \
00626 typedef Matrix<Type, 1, Size> RowVector##SizeSuffix##TypeSuffix;
00627
00628 #define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
00629 EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \
00630 EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \
00631 EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \
00632 EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X)
00633
00634 EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i)
00635 EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f)
00636 EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d)
00637 EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>, cf)
00638 EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
00639
00640 #undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES
00641 #undef EIGEN_MAKE_TYPEDEFS
00642
00643 #undef EIGEN_MAKE_TYPEDEFS_LARGE
00644
00645 #define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
00646 using Eigen::Matrix##SizeSuffix##TypeSuffix; \
00647 using Eigen::Vector##SizeSuffix##TypeSuffix; \
00648 using Eigen::RowVector##SizeSuffix##TypeSuffix;
00649
00650 #define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \
00651 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
00652 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
00653 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
00654 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
00655
00656 #define EIGEN_USING_MATRIX_TYPEDEFS \
00657 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \
00658 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \
00659 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \
00660 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \
00661 EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd)
00662
00663 #endif // EIGEN_MATRIX_H