diff options
-rw-r--r-- | doc/tutorial.cpp | 12 | ||||
-rw-r--r-- | src/Core | 2 | ||||
-rw-r--r-- | src/internal/Block.h | 56 | ||||
-rw-r--r-- | src/internal/EigenBase.h (renamed from src/internal/MatrixXpr.h) | 98 | ||||
-rw-r--r-- | src/internal/Matrix.h | 200 | ||||
-rw-r--r-- | src/internal/MatrixAlias.h | 78 | ||||
-rw-r--r-- | src/internal/MatrixBase.h | 201 | ||||
-rw-r--r-- | src/internal/MatrixOps.h | 273 | ||||
-rw-r--r-- | src/internal/MatrixRef.h | 29 | ||||
-rw-r--r-- | src/internal/MatrixStorage.h | 130 | ||||
-rw-r--r-- | src/internal/Minor.h | 54 | ||||
-rw-r--r-- | src/internal/RowAndCol.h | 95 | ||||
-rw-r--r-- | src/internal/ScalarOps.h | 112 | ||||
-rw-r--r-- | src/internal/Util.h | 77 | ||||
-rw-r--r-- | src/internal/Vector.h | 190 | ||||
-rw-r--r-- | test/matrixmanip.cpp | 8 | ||||
-rw-r--r-- | test/matrixops.cpp | 14 | ||||
-rw-r--r-- | test/vectorops.cpp | 17 |
18 files changed, 605 insertions, 1041 deletions
diff --git a/doc/tutorial.cpp b/doc/tutorial.cpp index 3b4489522..e37c245cc 100644 --- a/doc/tutorial.cpp +++ b/doc/tutorial.cpp @@ -5,18 +5,25 @@ using namespace Eigen; int main(int, char **) { - Matrix<double,2,2> m; // 2x2 fixed-size matrix with uninitialized entries + Matrix<double,2,2> m, n; // 2x2 fixed-size matrix with uninitialized entries m(0,0) = 1; m(0,1) = 2; m(1,0) = 3; m(1,1) = 4; + + n = m; + n = eval(n*n); + cout << n << endl; +#if 0 cout << "Here is a 2x2 matrix m:" << endl << m << endl; cout << "Let us now build a 4x4 matrix m2 by assembling together four 2x2 blocks." << endl; - MatrixX<double> m2(4, 4); // dynamic matrix with initial size 4x4 and uninitialized entries + Matrix<double,4,4> m2; // dynamic matrix with initial size 4x4 and uninitialized entries // notice how we are mixing fixed-size and dynamic-size types. cout << "In the top-left block, we put the matrix m shown above." << endl; m2.block(0,1,0,1) = m; + cout << "m2 is now " << endl << m2 << endl; + cout << "m2.block(0,1,0,1) has " << m2.block(0,1,0,1).rows() << " rows" << endl; cout << "In the bottom-left block, we put the matrix m*m, which is:" << endl << m*m << endl; m2.block(2,3,0,1) = m * m; cout << "In the top-right block, we put the matrix m+m, which is:" << endl << m+m << endl; @@ -47,5 +54,6 @@ int main(int, char **) m = m_save; m.alias() = m * m; cout << "And m is now:" << endl << m << endl << "as was expected." << endl; +#endif return 0; } @@ -26,7 +26,7 @@ #ifndef EIGEN_CORE_H #define EIGEN_CORE_H -#include "internal/Vector.h" +//#include "internal/Vector.h" #include "internal/Matrix.h" #endif // EIGEN_CORE_H diff --git a/src/internal/Block.h b/src/internal/Block.h index 68c4439cd..dde15b0c0 100644 --- a/src/internal/Block.h +++ b/src/internal/Block.h @@ -29,12 +29,17 @@ namespace Eigen { template<typename MatrixType> class MatrixBlock + : public EigenBase<typename MatrixType::Scalar, MatrixBlock<MatrixType> > { public: typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + friend class EigenBase<Scalar, MatrixBlock<MatrixType> >; + typedef MatrixBlock Ref; - MatrixBlock(const MatrixType& matrix, int startRow, int endRow, - int startCol = 0, int endCol = 0) + MatrixBlock(const MatRef& matrix, + int startRow, int endRow, + int startCol = 0, int endCol = 0) : m_matrix(matrix), m_startRow(startRow), m_endRow(endRow), m_startCol(startCol), m_endCol(endCol) { @@ -46,54 +51,35 @@ template<typename MatrixType> class MatrixBlock : m_matrix(other.m_matrix), m_startRow(other.m_startRow), m_endRow(other.m_endRow), m_startCol(other.m_startCol), m_endCol(other.m_endCol) {} - int rows() const { return m_endRow - m_startRow + 1; } - int cols() const { return m_endCol - m_startCol + 1; } + INHERIT_ASSIGNMENT_OPERATORS(MatrixBlock) - Scalar& write(int row, int col=0) + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_endRow - m_startRow + 1; } + int _cols() const { return m_endCol - m_startCol + 1; } + + Scalar& _write(int row, int col=0) { return m_matrix.write(row + m_startRow, col + m_startCol); } - Scalar read(int row, int col=0) const + Scalar _read(int row, int col=0) const { return m_matrix.read(row + m_startRow, col + m_startCol); } protected: - MatrixType m_matrix; + MatRef m_matrix; const int m_startRow, m_endRow, m_startCol, m_endCol; }; -template<typename Derived> -MatrixXpr< - MatrixBlock< - MatrixRef< - MatrixBase<Derived> - > - > -> -MatrixBase<Derived>::block(int startRow, int endRow, int startCol, int endCol) +template<typename Scalar, typename Derived> +MatrixBlock<EigenBase<Scalar, Derived> > +EigenBase<Scalar, Derived>::block(int startRow, int endRow, int startCol, int endCol) { - typedef MatrixBlock<Ref> ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(ref(), startRow, endRow, startCol, endCol)); + return MatrixBlock<EigenBase>(ref(), startRow, endRow, startCol, endCol); } -template<typename Content> -MatrixXpr< - MatrixBlock< - MatrixXpr<Content> - > -> -MatrixXpr<Content>::block(int startRow, int endRow, int startCol, int endCol) -{ - typedef MatrixBlock< - MatrixXpr<Content> - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(*this, startRow, endRow, startCol, endCol)); -} - -} +} // namespace Eigen #endif // EIGEN_BLOCK_H diff --git a/src/internal/MatrixXpr.h b/src/internal/EigenBase.h index fe890d16c..9f77ea6fc 100644 --- a/src/internal/MatrixXpr.h +++ b/src/internal/EigenBase.h @@ -23,86 +23,96 @@ // License. This exception does not invalidate any other reasons why a work // based on this file might be covered by the GNU General Public License. -#ifndef EIGEN_MATRIXXPR_H -#define EIGEN_MATRIXXPR_H +#ifndef EIGEN_EIGENBASE_H +#define EIGEN_EIGENBASE_H -namespace Eigen { +#include "Util.h" -//forward declarations -template<typename MatrixType> class MatrixRow; -template<typename MatrixType> class MatrixCol; -template<typename MatrixType> class MatrixMinor; -template<typename MatrixType> class MatrixBlock; +namespace Eigen { -template<typename Content> class MatrixXpr +template<typename _Scalar, typename Derived> class EigenBase { + static const int RowsAtCompileTime = Derived::RowsAtCompileTime, + ColsAtCompileTime = Derived::ColsAtCompileTime; public: - typedef typename Content::Scalar Scalar; + typedef typename ForwardDecl<Derived>::Ref Ref; + typedef _Scalar Scalar; - MatrixXpr(const Content& content) - : m_content(content) {} + int rows() const { return static_cast<const Derived *>(this)->_rows(); } + int cols() const { return static_cast<const Derived *>(this)->_cols(); } + int size() const { return rows() * cols(); } - MatrixXpr(const MatrixXpr& other) - : m_content(other.m_content) {} + Ref ref() + { return static_cast<Derived *>(this)->_ref(); } - ~MatrixXpr() {} - - int rows() const { return m_content.rows(); } - int cols() const { return m_content.cols(); } + Ref ref() const + { return static_cast<const Derived *>(this)->_ref(); } Scalar& write(int row, int col) { - return m_content.write(row, col); + return static_cast<Derived *>(this)->_write(row, col); } Scalar read(int row, int col) const { - return m_content.read(row, col); + return static_cast<const Derived *>(this)->_read(row, col); } - template<typename OtherContent> - MatrixXpr& operator=(const MatrixXpr<OtherContent>& other) + template<typename OtherDerived> + Derived& operator=(const EigenBase<Scalar, OtherDerived>& other) { assert(rows() == other.rows() && cols() == other.cols()); for(int i = 0; i < rows(); i++) for(int j = 0; j < cols(); j++) write(i, j) = other.read(i, j); - return *this; + return *static_cast<Derived*>(this); } //special case of the above template operator=. Strangely, g++ 4.1 failed to use - //that template when OtherContent == Content - MatrixXpr& operator=(const MatrixXpr& other) + //that template when OtherDerived == Derived + Derived& operator=(const EigenBase& other) { assert(rows() == other.rows() && cols() == other.cols()); for(int i = 0; i < rows(); i++) for(int j = 0; j < cols(); j++) write(i, j) = other.read(i, j); - return *this; + return *static_cast<Derived*>(this); } - template<typename Derived> - MatrixXpr& operator=(const MatrixBase<Derived>& matrix); - - MatrixXpr<MatrixRow<MatrixXpr<Content> > > row(int i); - MatrixXpr<MatrixCol<MatrixXpr<Content> > > col(int i); - MatrixXpr<MatrixMinor<MatrixXpr<Content> > > minor(int row, int col); - MatrixXpr<MatrixBlock<MatrixXpr<Content> > > + MatrixRow<EigenBase> row(int i); + MatrixCol<EigenBase> col(int i); + MatrixMinor<EigenBase> minor(int row, int col); + MatrixBlock<EigenBase> block(int startRow, int endRow, int startCol= 0, int endCol = 0); - template<typename Content2> - MatrixXpr& operator+=(const MatrixXpr<Content2> &other); - template<typename Content2> - MatrixXpr& operator-=(const MatrixXpr<Content2> &other); - template<typename Derived> - MatrixXpr& operator+=(MatrixBase<Derived> &matrix); - template<typename Derived> - MatrixXpr& operator-=(MatrixBase<Derived> &matrix); + template<typename OtherDerived> + Derived& operator+=(const EigenBase<Scalar, OtherDerived>& other); + template<typename OtherDerived> + Derived& operator-=(const EigenBase<Scalar, OtherDerived>& other); + + Scalar operator()(int row, int col = 0) const + { return read(row, col); } - protected: - Content m_content; + Scalar& operator()(int row, int col = 0) + { return write(row, col); } }; +template<typename Scalar, typename Derived> +std::ostream & operator << +( std::ostream & s, + const EigenBase<Scalar, Derived> & m ) +{ + for( int i = 0; i < m.rows(); i++ ) + { + s << m( i, 0 ); + for (int j = 1; j < m.cols(); j++ ) + s << " " << m( i, j ); + if( i < m.rows() - 1) + s << std::endl; + } + return s; +} + } // namespace Eigen -#endif // EIGEN_MATRIXXPR_H +#endif // EIGEN_EIGENBASE_H diff --git a/src/internal/Matrix.h b/src/internal/Matrix.h index be7c22bc3..a6efcd866 100644 --- a/src/internal/Matrix.h +++ b/src/internal/Matrix.h @@ -23,157 +23,111 @@ // License. This exception does not invalidate any other reasons why a work // based on this file might be covered by the GNU General Public License. -/** \file Matrix.h - * \brief Matrix and MatrixX class templates - */ - #ifndef EIGEN_MATRIX_H #define EIGEN_MATRIX_H -#include "MatrixBase.h" +#include "Util.h" +#include "EigenBase.h" +#include "MatrixRef.h" +#include "MatrixStorage.h" namespace Eigen { -template<typename T, int Rows, int Cols> -class Matrix: public MatrixBase< Matrix<T, Rows, Cols> > +template<typename _Scalar, int _Rows, int _Cols> +class Matrix : public EigenBase<_Scalar, Matrix<_Scalar, _Rows, _Cols> >, + public MatrixStorage<_Scalar, _Rows, _Cols> { - friend class MatrixBase<Matrix<T, Rows, Cols> >; - typedef class MatrixBase<Matrix<T, Rows, Cols> > Base; - public: - typedef T Scalar; - + friend class EigenBase<_Scalar, Matrix>; + typedef EigenBase<_Scalar, Matrix> Base; + typedef MatrixStorage<_Scalar, _Rows, _Cols> Storage; + typedef _Scalar Scalar; + typedef MatrixRef<Matrix> Ref; + typedef MatrixAlias<Matrix> Alias; + + static const int RowsAtCompileTime = _Rows, ColsAtCompileTime = _Cols; + + Alias alias(); + + const Scalar* array() const + { return Storage::m_array; } + + Scalar* array() + { return Storage::m_array; } + private: + Ref _ref() const { return Ref(*const_cast<Matrix*>(this)); } - static bool _hasDynamicNumRows() - { return false; } - - static bool _hasDynamicNumCols() - { return false; } - - int _rows() const - { return Rows; } + const Scalar& _read(int row, int col = 0) const + { + EIGEN_CHECK_RANGES(*this, row, col); + return array()[row + col * Storage::_rows()]; + } - int _cols() const - { return Cols; } - - void _resize( int rows, int cols ) const + Scalar& _write(int row, int col = 0) { - assert(rows == Rows && cols == Cols); + EIGEN_CHECK_RANGES(*this, row, col); + return array()[row + col * Storage::_rows()]; } - + public: - - Matrix() + template<typename OtherDerived> + Matrix& operator=(const EigenBase<Scalar, OtherDerived> &other) { - assert(Rows > 0 && Cols > 0); + resize(other.rows(), other.cols()); + return Base::operator=(other); } - Matrix(const Matrix& other) : Base() + template<typename OtherDerived> + Matrix& operator+=(const EigenBase<Scalar, OtherDerived> &other) { - *this = other; + return Base::operator+=(other); } - - Matrix(int rows, int cols) + template<typename OtherDerived> + Matrix& operator-=(const EigenBase<Scalar, OtherDerived> &other) { - assert(Rows > 0 && Cols > 0 && rows == Rows && cols == Cols); + return Base::operator-=(other); } - - void operator=(const Matrix & other) - { Base::operator=(other); } - - template<typename XprContent> - void operator=(const MatrixXpr<XprContent> &xpr) - { Base::operator=(xpr); } - - template<typename XprContent> - explicit Matrix(const MatrixXpr<XprContent>& xpr) + + explicit Matrix(int rows = 1, int cols = 1) : Storage(rows, cols) {} + template<typename OtherDerived> + Matrix(const EigenBase<Scalar, OtherDerived>& other) : Storage(other.rows(), other.cols()) { - *this = xpr; + *this = other; } - - protected: - - T m_array[ Rows * Cols ]; - + ~Matrix() {} }; -template<typename T> -class MatrixX : public MatrixBase< MatrixX<T> > +template<typename Scalar, typename Derived> +Matrix<Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime> +eval(const EigenBase<Scalar, Derived>& expression) { - friend class MatrixBase<MatrixX<T> >; - typedef class MatrixBase<MatrixX<T> > Base; - - public: - - typedef T Scalar; - - MatrixX(int rows, int cols) - { _init(rows, cols); } - - MatrixX(const MatrixX& other) : Base() - { - _init(other.rows(), other.cols()); - *this = other; - } - - ~MatrixX() - { delete[] m_array; } - - void operator=(const MatrixX& other) - { Base::operator=(other); } - - template<typename XprContent> - void operator=(const MatrixXpr<XprContent> &xpr) - { Base::operator=(xpr); } - - template<typename XprContent> - explicit MatrixX(const MatrixXpr<XprContent>& xpr) - { - _init(xpr.rows(), xpr.cols()); - *this = xpr; - } - - protected: - - int m_rows, m_cols; - - T *m_array; - - private: - - int _rows() const { return m_rows; } - int _cols() const { return m_cols; } - - static bool _hasDynamicNumRows() - { return true; } - - static bool _hasDynamicNumCols() - { return true; } - - void _resize( int rows, int cols ) - { - assert(rows > 0 && cols > 0); - if(rows * cols > m_rows * m_cols) - { - delete[] m_array; - m_array = new T[rows * cols]; - } - m_rows = rows; - m_cols = cols; - } - - void _init( int rows, int cols ) - { - assert(rows > 0 && cols > 0); - m_rows = rows; - m_cols = cols; - m_array = new T[m_rows * m_cols]; - } - -}; + return Matrix<Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime>(expression); +} + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \ +typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, DynamicSize, X) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<int>, ci) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) } // namespace Eigen +#include "MatrixAlias.h" +#include "MatrixOps.h" +#include "ScalarOps.h" +#include "RowAndCol.h" + #endif // EIGEN_MATRIX_H diff --git a/src/internal/MatrixAlias.h b/src/internal/MatrixAlias.h index 868011321..94d913a5f 100644 --- a/src/internal/MatrixAlias.h +++ b/src/internal/MatrixAlias.h @@ -29,86 +29,54 @@ namespace Eigen { -template<typename Derived> class MatrixAlias +template<typename MatrixType> class MatrixAlias + : public EigenBase<typename MatrixType::Scalar, MatrixAlias<MatrixType> > { public: - typedef typename Derived::Scalar Scalar; - typedef MatrixRef<MatrixAlias<Derived> > Ref; - typedef MatrixXpr<Ref> Xpr; + typedef typename MatrixType::Scalar Scalar; + typedef MatrixRef<MatrixAlias> Ref; + typedef EigenBase<typename MatrixType::Scalar, MatrixAlias> Base; + friend class EigenBase<typename MatrixType::Scalar, MatrixAlias>; - MatrixAlias(Derived& matrix) : m_aliased(matrix), m_tmp(matrix) {} + MatrixAlias(MatrixType& matrix) : m_aliased(matrix), m_tmp(matrix) {} MatrixAlias(const MatrixAlias& other) : m_aliased(other.m_aliased), m_tmp(other.m_tmp) {} ~MatrixAlias() { - m_aliased.xpr() = m_tmp; + m_aliased = m_tmp; } - Ref ref() - { - return Ref(*this); - } - - Xpr xpr() - { - return Xpr(ref()); - } - - static bool hasDynamicNumRows() - { - return MatrixBase<Derived>::hasDynamicNumRows(); - } + INHERIT_ASSIGNMENT_OPERATORS(MatrixAlias) - static bool hasDynamicNumCols() + private: + Ref _ref() const { - return MatrixBase<Derived>::hasDynamicNumCols(); + return Ref(*const_cast<MatrixAlias*>(this)); } - int rows() const { return m_tmp.rows(); } - int cols() const { return m_tmp.cols(); } + int _rows() const { return m_tmp.rows(); } + int _cols() const { return m_tmp.cols(); } - Scalar& write(int row, int col) + Scalar& _write(int row, int col) { return m_tmp.write(row, col); } - MatrixXpr<MatrixRow<Xpr> > row(int i) { return xpr().row(i); }; - MatrixXpr<MatrixCol<Xpr> > col(int i) { return xpr().col(i); }; - MatrixXpr<MatrixMinor<Xpr> > minor(int row, int col) { return xpr().minor(row, col); }; - MatrixXpr<MatrixBlock<Xpr> > - block(int startRow, int endRow, int startCol = 0, int endCol = 0) - { - return xpr().block(startRow, endRow, startCol, endCol); - } - - template<typename XprContent> - void operator=(const MatrixXpr<XprContent> &other) - { - xpr() = other; - } - - template<typename XprContent> - void operator+=(const MatrixXpr<XprContent> &other) - { - xpr() += other; - } - - template<typename XprContent> - void operator-=(const MatrixXpr<XprContent> &other) + Scalar _read(int row, int col) const { - xpr() -= other; + return m_aliased.read(row, col); } protected: - MatrixRef<MatrixBase<Derived> > m_aliased; - Derived m_tmp; + MatrixRef<MatrixType> m_aliased; + MatrixType m_tmp; }; -template<typename Derived> -typename MatrixBase<Derived>::Alias -MatrixBase<Derived>::alias() +template<typename _Scalar, int _Rows, int _Cols> +typename Matrix<_Scalar, _Rows, _Cols>::Alias +Matrix<_Scalar, _Rows, _Cols>::alias() { - return Alias(*static_cast<Derived*>(this)); + return Alias(*this); } } // namespace Eigen diff --git a/src/internal/MatrixBase.h b/src/internal/MatrixBase.h deleted file mode 100644 index 910cc4ac0..000000000 --- a/src/internal/MatrixBase.h +++ /dev/null @@ -1,201 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. Eigen itself is part of the KDE project. -// -// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> -// -// Eigen is free software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along -// with Eigen; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. This exception does not invalidate any other reasons why a work -// based on this file might be covered by the GNU General Public License. - -#ifndef EIGEN_MATRIXBASE_H -#define EIGEN_MATRIXBASE_H - -#include "Util.h" -#include "MatrixXpr.h" -#include "MatrixRef.h" - -namespace Eigen -{ - -template<typename Derived> -class MatrixBase -{ - public: - - typedef typename ForwardDecl<Derived>::Scalar Scalar; - typedef MatrixRef<MatrixBase<Derived> > Ref; - typedef MatrixXpr<Ref> Xpr; - typedef MatrixAlias<Derived> Alias; - - Ref ref() - { - return Ref(*this); - } - - Xpr xpr() - { - return Xpr(ref()); - } - - Alias alias(); - - static bool hasDynamicNumRows() - { - return Derived::_hasDynamicNumRows(); - } - - static bool hasDynamicNumCols() - { - return Derived::_hasDynamicNumCols(); - } - - int rows() const - { - return static_cast<const Derived*>(this)->_rows(); - } - - int cols() const - { - return static_cast<const Derived*>(this)->_cols(); - } - - void resize(int rows, int cols) - { - static_cast<Derived*>(this)->_resize(rows, cols); - } - - const Scalar* array() const - { - return static_cast<const Derived*>(this)->m_array; - } - - Scalar* array() - { - return static_cast<Derived*>(this)->m_array; - } - - const Scalar& read(int row, int col = 0) const - { - EIGEN_CHECK_RANGES(*this, row, col); - return array()[row + col * rows()]; - } - - const Scalar& operator()(int row, int col = 0) const - { - return read(row, col); - } - - Scalar& write(int row, int col = 0) - { - EIGEN_CHECK_RANGES(*this, row, col); - return array()[row + col * rows()]; - } - - Scalar& operator()(int row, int col = 0) - { - return write(row, col); - } - - template<typename XprContent> - MatrixBase& operator=(const MatrixXpr<XprContent> &otherXpr) - { - resize(otherXpr.rows(), otherXpr.cols()); - xpr() = otherXpr; - return *this; - } - - MatrixBase& operator=(const MatrixBase &other) - { - resize(other.rows(), other.cols()); - for(int i = 0; i < rows(); i++) - for(int j = 0; j < cols(); j++) - this->operator()(i, j) = other(i, j); - return *this; - } - - MatrixXpr<MatrixRow<Ref> > row(int i); - MatrixXpr<MatrixCol<Ref> > col(int i); - MatrixXpr<MatrixMinor<Ref> > minor(int row, int col); - MatrixXpr<MatrixBlock<Ref> > - block(int startRow, int endRow, int startCol = 0, int endCol = 0); - - template<typename Content> - MatrixBase& operator+=(const MatrixXpr<Content> &xpr); - template<typename Content> - MatrixBase& operator-=(const MatrixXpr<Content> &xpr); - template<typename Derived2> - MatrixBase& operator+=(MatrixBase<Derived2> &other); - template<typename Derived2> - MatrixBase& operator-=(MatrixBase<Derived2> &other); - - protected: - - MatrixBase() {}; -}; - -template<typename Content> -template<typename Derived> -MatrixXpr<Content>& MatrixXpr<Content>::operator=(const MatrixBase<Derived>& matrix) -{ - assert(rows() == matrix.rows() && cols() == matrix.cols()); - for(int i = 0; i < rows(); i++) - for(int j = 0; j < cols(); j++) - write(i, j) = matrix(i, j); - return *this; -} - -template<typename Derived> -std::ostream & operator << -( std::ostream & s, - const MatrixBase<Derived> & m ) -{ - for( int i = 0; i < m.rows(); i++ ) - { - s << m( i, 0 ); - for (int j = 1; j < m.cols(); j++ ) - s << " " << m( i, j ); - if( i < m.rows() - 1) - s << std::endl; - } - return s; -} - -template<typename Content> -std::ostream & operator << (std::ostream & s, - const MatrixXpr<Content>& xpr) -{ - for( int i = 0; i < xpr.rows(); i++ ) - { - s << xpr.read(i, 0); - for (int j = 1; j < xpr.cols(); j++ ) - s << " " << xpr.read(i, j); - if( i < xpr.rows() - 1) - s << std::endl; - } - return s; -} - -} // namespace Eigen - -#include "MatrixAlias.h" -#include "MatrixOps.h" -#include "ScalarOps.h" -#include "RowAndCol.h" - -#endif // EIGEN_MATRIXBASE_H diff --git a/src/internal/MatrixOps.h b/src/internal/MatrixOps.h index e76e64c85..34a24e914 100644 --- a/src/internal/MatrixOps.h +++ b/src/internal/MatrixOps.h @@ -28,45 +28,93 @@ namespace Eigen { -#define EIGEN_MAKE_MATRIX_OP_XPR(NAME, SYMBOL) \ -template<typename Lhs, typename Rhs> class Matrix##NAME \ -{ \ - public: \ - typedef typename Lhs::Scalar Scalar; \ -\ - Matrix##NAME(const Lhs& lhs, const Rhs& rhs) \ - : m_lhs(lhs), m_rhs(rhs) \ - { \ - assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); \ - } \ -\ - Matrix##NAME(const Matrix##NAME& other) \ - : m_lhs(other.m_lhs), m_rhs(other.m_rhs) {} \ -\ - int rows() const { return m_lhs.rows(); } \ - int cols() const { return m_lhs.cols(); } \ -\ - Scalar read(int row, int col) const \ - { \ - return m_lhs.read(row, col) SYMBOL m_rhs.read(row, col); \ - } \ -\ - protected: \ - const Lhs m_lhs; \ - const Rhs m_rhs; \ +template<typename Lhs, typename Rhs> class MatrixSum + : public EigenBase<typename Lhs::Scalar, MatrixSum<Lhs, Rhs> > +{ + public: + typedef typename Lhs::Scalar Scalar; + typedef typename Lhs::Ref LhsRef; + typedef typename Rhs::Ref RhsRef; + friend class EigenBase<Scalar, MatrixSum>; + typedef MatrixSum Ref; + + MatrixSum(const LhsRef& lhs, const RhsRef& rhs) + : m_lhs(lhs), m_rhs(rhs) + { + assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); + } + + MatrixSum(const MatrixSum& other) + : m_lhs(other.m_lhs), m_rhs(other.m_rhs) {} + + INHERIT_ASSIGNMENT_OPERATORS(MatrixSum) + + private: + + const Ref& _ref() const { return *this; } + int _rows() const { return m_lhs.rows(); } + int _cols() const { return m_lhs.cols(); } + + Scalar _read(int row, int col) const + { + return m_lhs.read(row, col) + m_rhs.read(row, col); + } + + protected: + const LhsRef m_lhs; + const RhsRef m_rhs; }; -EIGEN_MAKE_MATRIX_OP_XPR(Sum, +) -EIGEN_MAKE_MATRIX_OP_XPR(Difference, -) +template<typename Lhs, typename Rhs> class MatrixDifference + : public EigenBase<typename Lhs::Scalar, MatrixDifference<Lhs, Rhs> > +{ + public: + typedef typename Lhs::Scalar Scalar; + typedef typename Lhs::Ref LhsRef; + typedef typename Rhs::Ref RhsRef; + friend class EigenBase<Scalar, MatrixDifference>; + typedef MatrixDifference Ref; + + MatrixDifference(const LhsRef& lhs, const RhsRef& rhs) + : m_lhs(lhs), m_rhs(rhs) + { + assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); + } -#undef EIGEN_MAKE_MATRIX_OP_XPR + MatrixDifference(const MatrixDifference& other) + : m_lhs(other.m_lhs), m_rhs(other.m_rhs) {} + + INHERIT_ASSIGNMENT_OPERATORS(MatrixDifference) + + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_lhs.rows(); } + int _cols() const { return m_lhs.cols(); } + + Scalar _read(int row, int col) const + { + return m_lhs.read(row, col) - m_rhs.read(row, col); + } + + protected: + const LhsRef m_lhs; + const RhsRef m_rhs; +}; template<typename Lhs, typename Rhs> class MatrixProduct + : public EigenBase<typename Lhs::Scalar, MatrixProduct<Lhs, Rhs> > { public: typedef typename Lhs::Scalar Scalar; + typedef typename Lhs::Ref LhsRef; + typedef typename Rhs::Ref RhsRef; + friend class EigenBase<Scalar, MatrixProduct>; + typedef MatrixProduct Ref; + + static const int RowsAtCompileTime = Lhs::RowsAtCompileTime, + ColsAtCompileTime = Rhs::ColsAtCompileTime; - MatrixProduct(const Lhs& lhs, const Rhs& rhs) + MatrixProduct(const LhsRef& lhs, const RhsRef& rhs) : m_lhs(lhs), m_rhs(rhs) { assert(lhs.cols() == rhs.rows()); @@ -75,143 +123,64 @@ template<typename Lhs, typename Rhs> class MatrixProduct MatrixProduct(const MatrixProduct& other) : m_lhs(other.m_lhs), m_rhs(other.m_rhs) {} - int rows() const { return m_lhs.rows(); } - int cols() const { return m_rhs.cols(); } + INHERIT_ASSIGNMENT_OPERATORS(MatrixProduct) - Scalar read(int row, int col) const + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_lhs.rows(); } + int _cols() const { return m_rhs.cols(); } + + Scalar _read(int row, int col) const { Scalar x = static_cast<Scalar>(0); for(int i = 0; i < m_lhs.cols(); i++) x += m_lhs.read(row, i) * m_rhs.read(i, col); return x; } - + protected: - const Lhs m_lhs; - const Rhs m_rhs; + const LhsRef m_lhs; + const RhsRef m_rhs; }; -#define EIGEN_MAKE_MATRIX_OP(NAME, SYMBOL) \ -template<typename Content1, typename Content2> \ -MatrixXpr< \ - Matrix##NAME< \ - MatrixXpr<Content1>, \ - MatrixXpr<Content2> \ - > \ -> \ -operator SYMBOL(const MatrixXpr<Content1> &xpr1, const MatrixXpr<Content2> &xpr2) \ -{ \ - typedef Matrix##NAME< \ - MatrixXpr<Content1>, \ - MatrixXpr<Content2> \ - > ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(xpr1, xpr2)); \ -} \ -\ -template<typename Derived, typename Content> \ -MatrixXpr< \ - Matrix##NAME< \ - MatrixRef<MatrixBase<Derived> >, \ - MatrixXpr<Content> \ - > \ -> \ -operator SYMBOL(MatrixBase<Derived> &mat, const MatrixXpr<Content> &xpr) \ -{ \ - typedef Matrix##NAME< \ - MatrixRef<MatrixBase<Derived> >, \ - MatrixXpr<Content> \ - > ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(mat.ref(), xpr)); \ -} \ -\ -template<typename Content, typename Derived> \ -MatrixXpr< \ - Matrix##NAME< \ - MatrixXpr<Content>, \ - MatrixRef<MatrixBase<Derived> > \ - > \ -> \ -operator SYMBOL(const MatrixXpr<Content> &xpr, MatrixBase<Derived> &mat) \ -{ \ - typedef Matrix##NAME< \ - MatrixXpr<Content>, \ - MatrixRef<MatrixBase<Derived> > \ - > ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(xpr, mat.ref())); \ -} \ -\ -template<typename Derived1, typename Derived2> \ -MatrixXpr< \ - Matrix##NAME< \ - MatrixRef<MatrixBase<Derived1> >, \ - MatrixRef<MatrixBase<Derived2> > \ - > \ -> \ -operator SYMBOL(MatrixBase<Derived1> &mat1, MatrixBase<Derived2> &mat2) \ -{ \ - typedef Matrix##NAME< \ - MatrixRef<MatrixBase<Derived1> >, \ - MatrixRef<MatrixBase<Derived2> > \ - > ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(mat1.ref(), \ - mat2.ref())); \ +template<typename Scalar, typename Derived1, typename Derived2> +MatrixProduct<Derived1, Derived2> +operator*(const EigenBase<Scalar, Derived1> &mat1, const EigenBase<Scalar, Derived2> &mat2) +{ + return MatrixProduct<Derived1, Derived2>(mat1.ref(), mat2.ref()); +} + +template<typename Scalar, typename Derived1, typename Derived2> +MatrixSum<Derived1, Derived2> +operator+(const EigenBase<Scalar, Derived1> &mat1, const EigenBase<Scalar, Derived2> &mat2) +{ + return MatrixSum<Derived1, Derived2>(mat1.ref(), mat2.ref()); } -EIGEN_MAKE_MATRIX_OP(Sum, +) -EIGEN_MAKE_MATRIX_OP(Difference, -) -EIGEN_MAKE_MATRIX_OP(Product, *) - -#undef EIGEN_MAKE_MATRIX_OP - -#define EIGEN_MAKE_MATRIX_OP_EQ(SYMBOL) \ -template<typename Derived1> \ -template<typename Derived2> \ -MatrixBase<Derived1> & \ -MatrixBase<Derived1>::operator SYMBOL##=(MatrixBase<Derived2> &mat2) \ -{ \ - return *this = *this SYMBOL mat2; \ -} \ -\ -template<typename Derived> \ -template<typename Content> \ -MatrixBase<Derived> & \ -MatrixBase<Derived>::operator SYMBOL##=(const MatrixXpr<Content> &xpr) \ -{ \ - return *this = *this SYMBOL xpr; \ -} \ -\ -template<typename Content> \ -template<typename Derived> \ -MatrixXpr<Content> & \ -MatrixXpr<Content>::operator SYMBOL##=(MatrixBase<Derived> &mat) \ -{ \ - assert(rows() == mat.rows() && cols() == mat.cols()); \ - for(int i = 0; i < rows(); i++) \ - for(int j = 0; j < cols(); j++) \ - write(i, j) SYMBOL##= mat.read(i, j); \ - return *this; \ -} \ -\ -template<typename Content1> \ -template<typename Content2> \ -MatrixXpr<Content1> & \ -MatrixXpr<Content1>::operator SYMBOL##=(const MatrixXpr<Content2> &other) \ -{ \ - assert(rows() == other.rows() && cols() == other.cols()); \ - for(int i = 0; i < rows(); i++) \ - for(int j = 0; j < cols(); j++) \ - write(i, j) SYMBOL##= other.read(i, j); \ - return *this; \ +template<typename Scalar, typename Derived1, typename Derived2> +MatrixDifference<Derived1, Derived2> +operator-(const EigenBase<Scalar, Derived1> &mat1, const EigenBase<Scalar, Derived2> &mat2) +{ + return MatrixDifference<Derived1, Derived2>(mat1.ref(), mat2.ref()); } -EIGEN_MAKE_MATRIX_OP_EQ(+) -EIGEN_MAKE_MATRIX_OP_EQ(-) +template<typename Scalar, typename Derived> +template<typename OtherDerived> +Derived & +EigenBase<Scalar, Derived>::operator+=(const EigenBase<Scalar, OtherDerived>& other) +{ + *this = *this + other; + return *static_cast<Derived*>(this); +} -#undef EIGEN_MAKE_MATRIX_OP_EQ +template<typename Scalar, typename Derived> +template<typename OtherDerived> +Derived & +EigenBase<Scalar, Derived>::operator-=(const EigenBase<Scalar, OtherDerived> &other) +{ + *this = *this - other; + return *static_cast<Derived*>(this); +} } // namespace Eigen diff --git a/src/internal/MatrixRef.h b/src/internal/MatrixRef.h index 0123c535c..d074adf2e 100644 --- a/src/internal/MatrixRef.h +++ b/src/internal/MatrixRef.h @@ -30,43 +30,32 @@ namespace Eigen { template<typename MatrixType> class MatrixRef + : public EigenBase<typename MatrixType::Scalar, MatrixRef<MatrixType> > { public: - typedef typename ForwardDecl<MatrixType>::Scalar Scalar; - typedef MatrixXpr<MatrixRef<MatrixType> > Xpr; + typedef typename MatrixType::Scalar Scalar; + friend class EigenBase<Scalar, MatrixRef>; MatrixRef(MatrixType& matrix) : m_matrix(matrix) {} MatrixRef(const MatrixRef& other) : m_matrix(other.m_matrix) {} ~MatrixRef() {} - static bool hasDynamicNumRows() - { - return MatrixType::hasDynamicNumRows(); - } + INHERIT_ASSIGNMENT_OPERATORS(MatrixRef) - static bool hasDynamicNumCols() - { - return MatrixType::hasDynamicNumCols(); - } - - int rows() const { return m_matrix.rows(); } - int cols() const { return m_matrix.cols(); } + private: + int _rows() const { return m_matrix.rows(); } + int _cols() const { return m_matrix.cols(); } - const Scalar& read(int row, int col) const + Scalar _read(int row, int col) const { return m_matrix.read(row, col); } - Scalar& write(int row, int col) + Scalar& _write(int row, int col) { return m_matrix.write(row, col); } - Xpr xpr() - { - return Xpr(*this); - } - protected: MatrixType& m_matrix; }; diff --git a/src/internal/MatrixStorage.h b/src/internal/MatrixStorage.h new file mode 100644 index 000000000..8dee4cebf --- /dev/null +++ b/src/internal/MatrixStorage.h @@ -0,0 +1,130 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> +// +// Eigen is free software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along +// with Eigen; if not, write to the Free Software Foundation, Inc., 51 +// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. This exception does not invalidate any other reasons why a work +// based on this file might be covered by the GNU General Public License. + +#ifndef EIGEN_MATRIXSTORAGE_H +#define EIGEN_MATRIXSTORAGE_H + +namespace Eigen { + +template<typename Scalar, + int RowsAtCompileTime, + int ColsAtCompileTime> +class MatrixStorage +{ + protected: + Scalar m_array[RowsAtCompileTime * RowsAtCompileTime]; + + void resize(int rows, int cols) + { assert(rows == RowsAtCompileTime && cols == ColsAtCompileTime); } + + int _rows() const + { return RowsAtCompileTime; } + + int _cols() const + { return ColsAtCompileTime; } + + public: + MatrixStorage(int rows, int cols) + { + EIGEN_UNUSED(rows); + EIGEN_UNUSED(cols); + assert(RowsAtCompileTime > 0 && ColsAtCompileTime > 0); + } + + ~MatrixStorage() {}; +}; + +template<typename Scalar> +class MatrixStorage<Scalar, DynamicSize, 1> +{ + protected: + int m_rows; + Scalar *m_array; + + void resize(int rows, int cols) + { assert(rows > 0 && cols == 1); + if(rows > m_rows) { + delete[] m_array; + m_array = new Scalar[rows]; + } + m_rows = rows; + } + + int _rows() const + { return m_rows; } + + int _cols() const + { return 1; } + + public: + MatrixStorage(int rows, int cols) : m_rows(rows) + { + assert(m_rows > 0 && cols == 1); + m_array = new Scalar[m_rows]; + } + + ~MatrixStorage() + { delete[] m_array; } +}; + +template<typename Scalar> +class MatrixStorage<Scalar, DynamicSize, DynamicSize> +{ + protected: + int m_rows, m_cols; + Scalar *m_array; + + void resize(int rows, int cols) + { + assert(rows > 0 && cols > 0); + if(rows * cols > m_rows * m_cols) + { + delete[] m_array; + m_array = new Scalar[rows * cols]; + } + m_rows = rows; + m_cols = cols; + } + + int _rows() const + { return m_rows; } + + int _cols() const + { return m_cols; } + + public: + MatrixStorage(int rows, int cols) : m_rows(rows), m_cols(cols) + { + assert(m_rows > 0 && m_cols > 0); + m_array = new Scalar[m_rows * m_cols]; + } + + ~MatrixStorage() + { delete[] m_array; } +}; + +} // namespace Eigen + +#endif // EIGEN_MATRIXSTORAGE_H diff --git a/src/internal/Minor.h b/src/internal/Minor.h index da0d759de..05873f1f1 100644 --- a/src/internal/Minor.h +++ b/src/internal/Minor.h @@ -29,11 +29,16 @@ namespace Eigen { template<typename MatrixType> class MatrixMinor + : public EigenBase<typename MatrixType::Scalar, MatrixMinor<MatrixType> > { public: typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + friend class EigenBase<Scalar, MatrixMinor<MatrixType> >; + typedef MatrixMinor Ref; - MatrixMinor(const MatrixType& matrix, int row, int col = 0) + MatrixMinor(const MatRef& matrix, + int row, int col = 0) : m_matrix(matrix), m_row(row), m_col(col) { EIGEN_CHECK_RANGES(matrix, row, col); @@ -42,54 +47,35 @@ template<typename MatrixType> class MatrixMinor MatrixMinor(const MatrixMinor& other) : m_matrix(other.m_matrix), m_row(other.m_row), m_col(other.m_col) {} - int rows() const { return m_matrix.rows() - 1; } - int cols() const { return m_matrix.cols() - 1; } + INHERIT_ASSIGNMENT_OPERATORS(MatrixMinor) - Scalar& write(int row, int col=0) + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_matrix.rows() - 1; } + int _cols() const { return m_matrix.cols() - 1; } + + Scalar& _write(int row, int col=0) { return m_matrix.write(row + (row >= m_row), col + (col >= m_col)); } - Scalar read(int row, int col=0) const + Scalar _read(int row, int col=0) const { return m_matrix.read(row + (row >= m_row), col + (col >= m_col)); } protected: - MatrixType m_matrix; + MatRef m_matrix; const int m_row, m_col; }; -template<typename Derived> -MatrixXpr< - MatrixMinor< - MatrixRef< - MatrixBase<Derived> - > - > -> -MatrixBase<Derived>::minor(int row, int col) +template<typename Scalar, typename Derived> +MatrixMinor<EigenBase<Scalar, Derived> > +EigenBase<Scalar, Derived>::minor(int row, int col) { - typedef MatrixMinor<Ref> ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(ref(), row, col)); + return MatrixMinor<EigenBase>(ref(), row, col); } -template<typename Content> -MatrixXpr< - MatrixMinor< - MatrixXpr<Content> - > -> -MatrixXpr<Content>::minor(int row, int col) -{ - typedef MatrixMinor< - MatrixXpr<Content> - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(*this, row, col)); -} - -} +} // namespace Eigen #endif // EIGEN_MINOR_H diff --git a/src/internal/RowAndCol.h b/src/internal/RowAndCol.h index 5da3cfa23..d7e3f73b0 100644 --- a/src/internal/RowAndCol.h +++ b/src/internal/RowAndCol.h @@ -29,11 +29,15 @@ namespace Eigen { template<typename MatrixType> class MatrixRow + : public EigenBase<typename MatrixType::Scalar, MatrixRow<MatrixType> > { public: typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + friend class EigenBase<Scalar, MatrixRow<MatrixType> >; + typedef MatrixRow Ref; - MatrixRow(const MatrixType& matrix, int row) + MatrixRow(const MatRef& matrix, int row) : m_matrix(matrix), m_row(row) { EIGEN_CHECK_ROW_RANGE(matrix, row); @@ -42,17 +46,28 @@ template<typename MatrixType> class MatrixRow MatrixRow(const MatrixRow& other) : m_matrix(other.m_matrix), m_row(other.m_row) {} - int rows() const { return m_matrix.cols(); } - int cols() const { return 1; } + template<typename OtherDerived> + MatrixRow& operator=(const EigenBase<Scalar, OtherDerived>& other) + { + return EigenBase<Scalar, MatrixRow<MatrixType> >::operator=(other); + } + + INHERIT_ASSIGNMENT_OPERATORS(MatrixRow) + + private: + const Ref& _ref() const { return *this; } - Scalar& write(int row, int col=0) + int _rows() const { return m_matrix.cols(); } + int _cols() const { return 1; } + + Scalar& _write(int row, int col=0) { EIGEN_UNUSED(col); EIGEN_CHECK_ROW_RANGE(*this, row); return m_matrix.write(m_row, row); } - Scalar read(int row, int col=0) const + Scalar _read(int row, int col=0) const { EIGEN_UNUSED(col); EIGEN_CHECK_ROW_RANGE(*this, row); @@ -60,16 +75,20 @@ template<typename MatrixType> class MatrixRow } protected: - MatrixType m_matrix; + MatRef m_matrix; const int m_row; }; template<typename MatrixType> class MatrixCol + : public EigenBase<typename MatrixType::Scalar, MatrixCol<MatrixType> > { public: typedef typename MatrixType::Scalar Scalar; - - MatrixCol(const MatrixType& matrix, int col) + typedef typename MatrixType::Ref MatRef; + friend class EigenBase<Scalar, MatrixCol<MatrixType> >; + typedef MatrixCol Ref; + + MatrixCol(const MatRef& matrix, int col) : m_matrix(matrix), m_col(col) { EIGEN_CHECK_COL_RANGE(matrix, col); @@ -78,17 +97,21 @@ template<typename MatrixType> class MatrixCol MatrixCol(const MatrixCol& other) : m_matrix(other.m_matrix), m_col(other.m_col) {} - int rows() const { return m_matrix.rows(); } - int cols() const { return 1; } + INHERIT_ASSIGNMENT_OPERATORS(MatrixCol) - Scalar& write(int row, int col=0) + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_matrix.rows(); } + int _cols() const { return 1; } + + Scalar& _write(int row, int col=0) { EIGEN_UNUSED(col); EIGEN_CHECK_ROW_RANGE(*this, row); return m_matrix.write(row, m_col); } - Scalar read(int row, int col=0) const + Scalar _read(int row, int col=0) const { EIGEN_UNUSED(col); EIGEN_CHECK_ROW_RANGE(*this, row); @@ -96,46 +119,24 @@ template<typename MatrixType> class MatrixCol } protected: - MatrixType m_matrix; + MatRef m_matrix; const int m_col; }; -#define EIGEN_MAKE_ROW_COL_FUNCTIONS(func, Func) \ -template<typename Derived> \ -MatrixXpr< \ - Matrix##Func< \ - MatrixRef< \ - MatrixBase<Derived> \ - > \ - > \ -> \ -MatrixBase<Derived>::func(int i)\ -{ \ - typedef Matrix##Func<Ref> ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(ref(), i)); \ -} \ -\ -template<typename Content> \ -MatrixXpr< \ - Matrix##Func< \ - MatrixXpr<Content> \ - > \ -> \ -MatrixXpr<Content>::func(int i)\ -{ \ - typedef Matrix##Func< \ - MatrixXpr<Content> \ - > ProductType; \ - typedef MatrixXpr<ProductType> XprType; \ - return XprType(ProductType(*this, i)); \ +template<typename Scalar, typename Derived> +MatrixRow<EigenBase<Scalar, Derived> > +EigenBase<Scalar, Derived>::row(int i) +{ + return MatrixRow<EigenBase>(ref(), i); } -EIGEN_MAKE_ROW_COL_FUNCTIONS(row, Row) -EIGEN_MAKE_ROW_COL_FUNCTIONS(col, Col) - -#undef EIGEN_MAKE_ROW_COL_FUNCTIONS - +template<typename Scalar, typename Derived> +MatrixCol<EigenBase<Scalar, Derived> > +EigenBase<Scalar, Derived>::col(int i) +{ + return MatrixCol<EigenBase>(ref(), i); } +} // namespace Eigen + #endif // EIGEN_ROWANDCOL_H diff --git a/src/internal/ScalarOps.h b/src/internal/ScalarOps.h index 01772569a..de2cad770 100644 --- a/src/internal/ScalarOps.h +++ b/src/internal/ScalarOps.h @@ -29,113 +29,57 @@ namespace Eigen { template<typename MatrixType> class ScalarProduct + : public EigenBase<typename MatrixType::Scalar, ScalarProduct<MatrixType> > { public: typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + typedef ScalarProduct Ref; + friend class EigenBase<typename MatrixType::Scalar, ScalarProduct<MatrixType> >; - ScalarProduct(const MatrixType& matrix, Scalar scalar) + ScalarProduct(const MatRef& matrix, Scalar scalar) : m_matrix(matrix), m_scalar(scalar) {} ScalarProduct(const ScalarProduct& other) : m_matrix(other.m_matrix), m_scalar(other.m_scalar) {} - int rows() const { return m_matrix.rows(); } - int cols() const { return m_matrix.cols(); } + INHERIT_ASSIGNMENT_OPERATORS(ScalarProduct) - Scalar read(int row, int col) const + private: + const Ref& _ref() const { return *this; } + int _rows() const { return m_matrix.rows(); } + int _cols() const { return m_matrix.cols(); } + + Scalar _read(int row, int col) const { return m_matrix.read(row, col) * m_scalar; } protected: - const MatrixType m_matrix; - const Scalar m_scalar; + const MatRef m_matrix; + const Scalar m_scalar; }; -template<typename Content> -MatrixXpr< - ScalarProduct< - MatrixXpr<Content> - > -> -operator *(const MatrixXpr<Content>& xpr, - typename Content::Scalar scalar) -{ - typedef ScalarProduct< - MatrixXpr<Content> - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(xpr, scalar)); -} - -template<typename Content> -MatrixXpr< - ScalarProduct< - MatrixXpr<Content> - > -> -operator *(typename Content::Scalar scalar, - const MatrixXpr<Content>& xpr) -{ - typedef ScalarProduct< - MatrixXpr<Content> - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(xpr, scalar)); -} - -template<typename Derived> -MatrixXpr< - ScalarProduct< - MatrixRef<MatrixBase<Derived> > - > -> -operator *(MatrixBase<Derived>& matrix, - typename Derived::Scalar scalar) -{ - typedef ScalarProduct< - MatrixRef<MatrixBase<Derived> > - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(matrix.ref(), scalar)); -} - -template<typename Derived> -MatrixXpr< - ScalarProduct< - MatrixRef<MatrixBase<Derived> > - > -> -operator *(typename Derived::Scalar scalar, - MatrixBase<Derived>& matrix) +template<typename Scalar, typename Derived> +ScalarProduct<Derived> +operator*(const EigenBase<Scalar, Derived>& matrix, + Scalar scalar) { - typedef ScalarProduct< - MatrixRef<MatrixBase<Derived> > - > ProductType; - typedef MatrixXpr<ProductType> XprType; - return XprType(ProductType(matrix.ref(), scalar)); + return ScalarProduct<Derived>(matrix.ref(), scalar); } -template<typename Content> -MatrixXpr< - ScalarProduct< - MatrixXpr<Content> - > -> -operator /(MatrixXpr<Content>& xpr, - typename Content::Scalar scalar) +template<typename Scalar, typename Derived> +ScalarProduct<Derived> +operator*(Scalar scalar, + const EigenBase<Scalar, Derived>& matrix) { - return xpr * (static_cast<typename Content::Scalar>(1) / scalar); + return ScalarProduct<Derived>(matrix.ref(), scalar); } -template<typename Derived> -MatrixXpr< - ScalarProduct< - MatrixRef<MatrixBase<Derived> > - > -> -operator /(MatrixBase<Derived>& matrix, - typename Derived::Scalar scalar) +template<typename Scalar, typename Derived> +ScalarProduct<Derived> +operator/(const EigenBase<Scalar, Derived>& matrix, + Scalar scalar) { return matrix * (static_cast<typename Derived::Scalar>(1) / scalar); } diff --git a/src/internal/Util.h b/src/internal/Util.h index 31b94b421..9bba7297e 100644 --- a/src/internal/Util.h +++ b/src/internal/Util.h @@ -27,6 +27,7 @@ #define EIGEN_UTIL_H #include <iostream> +#include <complex> #include <cassert> #undef minor @@ -43,40 +44,52 @@ namespace Eigen { //forward declarations -template<typename T, int Rows, int Cols> class Matrix; -template<typename T> class MatrixX; -template<typename T, int Size> class Vector; -template<typename T> class VectorX; -template<typename Derived> class MatrixBase; -template<typename Derived> class MatrixAlias; +template<typename _Scalar, int _Rows, int _Cols> class Matrix; +template<typename MatrixType> class MatrixAlias; +template<typename MatrixType> class MatrixRef; +template<typename MatrixType> class MatrixRow; +template<typename MatrixType> class MatrixCol; +template<typename MatrixType> class MatrixMinor; +template<typename MatrixType> class MatrixBlock; +template<typename Lhs, typename Rhs> class MatrixSum; +template<typename Lhs, typename Rhs> class MatrixDifference; +template<typename Lhs, typename Rhs> class MatrixProduct; +template<typename MatrixType> class ScalarProduct; -template<typename T> struct ForwardDecl; -template<typename T, int Rows, int Cols> struct ForwardDecl< Matrix<T, Rows, Cols> > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< MatrixX<T> > -{ typedef T Scalar; }; -template<typename T, int Size> struct ForwardDecl< Vector<T, Size> > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< VectorX<T> > -{ typedef T Scalar; }; -template<typename T, int Rows, int Cols> struct ForwardDecl< MatrixBase<Matrix<T, Rows, Cols> > > -{ typedef T Scalar; }; -template<typename T, int Rows, int Cols> struct ForwardDecl< MatrixAlias<Matrix<T, Rows, Cols> > > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< MatrixBase<MatrixX<T> > > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< MatrixAlias<MatrixX<T> > > -{ typedef T Scalar; }; -template<typename T, int Size> struct ForwardDecl< MatrixBase<Vector<T, Size> > > -{ typedef T Scalar; }; -template<typename T, int Size> struct ForwardDecl< MatrixAlias<Vector<T, Size> > > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< MatrixBase<VectorX<T> > > -{ typedef T Scalar; }; -template<typename T> struct ForwardDecl< MatrixAlias<VectorX<T> > > -{ typedef T Scalar; }; +template<typename T> struct ForwardDecl +{ + typedef T Ref; +}; -template<typename MatrixType> class MatrixRef; +template<typename _Scalar, int _Rows, int _Cols> struct ForwardDecl<Matrix<_Scalar, _Rows, _Cols> > +{ + typedef MatrixRef<Matrix<_Scalar, _Rows, _Cols> > Ref; +}; + +template<typename MatrixType> struct ForwardDecl<MatrixAlias<MatrixType> > +{ + typedef MatrixRef<MatrixAlias<MatrixType> > Ref; +}; + +const int DynamicSize = -1; + +#define EIGEN_UNUSED(x) (void)x + +#define INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ +template<typename OtherScalar, typename OtherDerived> \ +Derived& operator Op(const EigenBase<OtherScalar, OtherDerived>& other) \ +{ \ + return EigenBase<OtherScalar, Derived>::operator Op(other); \ +} \ +Derived& operator Op(const Derived& other) \ +{ \ + return EigenBase<Scalar, Derived>::operator Op(other); \ +} + +#define INHERIT_ASSIGNMENT_OPERATORS(Derived) \ +INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ +INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ +INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) } // namespace Eigen diff --git a/src/internal/Vector.h b/src/internal/Vector.h deleted file mode 100644 index 0d1c719c5..000000000 --- a/src/internal/Vector.h +++ /dev/null @@ -1,190 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. Eigen itself is part of the KDE project. -// -// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr> -// -// Eigen is free software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along -// with Eigen; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. This exception does not invalidate any other reasons why a work -// based on this file might be covered by the GNU General Public License. - -/** \file Matrix.h - * \brief Matrix and MatrixX class templates - */ - -#ifndef EIGEN_VECTOR_H -#define EIGEN_VECTOR_H - -#include "MatrixBase.h" - -namespace Eigen -{ - -template<typename T, int Size> -class Vector: public MatrixBase<Vector<T, Size> > -{ - friend class MatrixBase<Vector<T, Size> >; - typedef class MatrixBase<Vector<T, Size> > Base; - - public: - typedef T Scalar; - - private: - - static bool _hasDynamicNumRows() - { return false; } - - static bool _hasDynamicNumCols() - { return false; } - - int _rows() const - { return Size; } - - int _cols() const - { return 1; } - - void _resize( int rows, int cols ) const - { - assert( rows == Size && cols == 1 ); - } - - public: - - Vector() - { - assert(Size > 0); - } - - explicit Vector(int rows, int cols = 1) - { - assert(Size > 0 && rows == Size && cols == 1); - } - - Vector(const Vector& other) : Base() - { - *this = other; - } - - void operator=(const Vector & other) - { Base::operator=(other); } - - template<typename XprContent> - void operator=(const MatrixXpr<XprContent> &xpr) - { - Base::operator=(xpr); - } - - template<typename XprContent> - explicit Vector(const MatrixXpr<XprContent>& xpr) - { - *this = xpr; - } - - int size() const { return _rows(); } - - protected: - - T m_array[Size]; - -}; - -template<typename T> -class VectorX : public MatrixBase<VectorX<T> > -{ - friend class MatrixBase<VectorX<T> >; - typedef class MatrixBase<VectorX<T> > Base; - - public: - - typedef T Scalar; - - explicit VectorX(int rows, int cols = 1) - { - assert(cols == 1); - _init(rows); - } - - VectorX(const VectorX& other) : Base() - { - _init(other.size()); - *this = other; - } - - void operator=(const VectorX& other) - { - Base::operator=(other); - } - - template<typename XprContent> - void operator=(const MatrixXpr<XprContent> &xpr) - { - Base::operator=(xpr); - } - - template<typename XprContent> - explicit VectorX(const MatrixXpr<XprContent>& xpr) - { - _init(xpr.rows()); - *this = xpr; - } - - ~VectorX() - { - delete[] m_array; } - - int size() const { return _rows(); } - - protected: - - int m_size; - T *m_array; - - private: - - int _rows() const { return m_size; } - int _cols() const { return 1; } - - static bool _hasDynamicNumRows() - { return true; } - - static bool _hasDynamicNumCols() - { return false; } - - void _resize(int rows, int cols) - { - assert(rows > 0 && cols == 1); - if(rows > m_size) - { - delete[] m_array; - m_array = new T[rows]; - } - m_size = rows; - } - - void _init(int size) - { - assert(size > 0); - m_size = size; - m_array = new T[m_size]; - } - -}; - -} // namespace Eigen - -#endif // EIGEN_VECTOR_H diff --git a/test/matrixmanip.cpp b/test/matrixmanip.cpp index 90ddcaca9..b5bdd21c6 100644 --- a/test/matrixmanip.cpp +++ b/test/matrixmanip.cpp @@ -38,7 +38,7 @@ template<typename MatrixType> void matrixManip(const MatrixType& m) a.row(i) = b.row(i); a.row(i) += b.row(i); a.minor(i, j) = b.block(1, rows-1, 1, cols-1); - a.alias().minor(i, j) -= a.block(1, rows-1, 1, cols-1); + //a.alias().minor(i, j) -= a.block(1, rows-1, 1, cols-1); } void EigenTest::testMatrixManip() @@ -46,7 +46,7 @@ void EigenTest::testMatrixManip() matrixManip(Matrix<int, 2, 3>()); matrixManip(Matrix<double, 3, 3>()); matrixManip(Matrix<complex<float>, 4,3>()); - matrixManip(MatrixX<int>(2, 2)); - matrixManip(MatrixX<double>(3, 5)); - matrixManip(MatrixX<complex<float> >(4, 4)); + matrixManip(MatrixXi(2, 2)); + matrixManip(MatrixXd(3, 5)); + matrixManip(MatrixXcf(4, 4)); } diff --git a/test/matrixops.cpp b/test/matrixops.cpp index b8fd122c3..1a70dcf5d 100644 --- a/test/matrixops.cpp +++ b/test/matrixops.cpp @@ -47,7 +47,7 @@ template<typename MatrixType1, a.alias() = a + b; a += b; - a.alias().xpr() += b; + a.alias() += b; a -= b + b; MatrixType1 d(rows1, cols1); @@ -61,10 +61,10 @@ void EigenTest::testMatrixOps() matrixOps(Matrix<int, 2, 3>(), Matrix<int, 3, 1>()); matrixOps(Matrix<double, 3, 3>(), Matrix<double, 3, 3>()); matrixOps(Matrix<complex<float>, 4,3>(), Matrix<complex<float>, 3,4>()); - matrixOps(MatrixX<float>(1, 1), MatrixX<float>(1, 3)); - matrixOps(MatrixX<int>(2, 2), MatrixX<int>(2, 2)); - matrixOps(MatrixX<double>(3, 5), MatrixX<double>(5, 1)); - matrixOps(MatrixX<complex<float> >(4, 4), MatrixX<complex<float> >(4, 4)); - matrixOps(MatrixX<double>(3, 5), Matrix<double, 5, 1>()); - matrixOps(Matrix<complex<float>, 4, 4>(), MatrixX<complex<float> >(4, 4)); + /*matrixOps(MatrixXf(1, 1), MatrixXf(1, 3)); + matrixOps(MatrixXi(2, 2), MatrixXi(2, 2)); + matrixOps(MatrixXd(3, 5), MatrixXd(5, 1)); + matrixOps(MatrixXcf(4, 4), MatrixXcf(4, 4)); + matrixOps(MatrixXd(3, 5), Matrix<double, 5, 1>()); + matrixOps(Matrix4cf(), MatrixXcf(4, 4));*/ } diff --git a/test/vectorops.cpp b/test/vectorops.cpp index 33aa72178..5f6331bf1 100644 --- a/test/vectorops.cpp +++ b/test/vectorops.cpp @@ -46,19 +46,16 @@ template<typename VectorType> void vectorOps(const VectorType& v) a += b; a += b + b; - a.xpr() -= b; - a.xpr() -= b + b; a.alias() += a + a; } void EigenTest::testVectorOps() { - vectorOps(Vector<float, 1>()); - vectorOps(Vector<int, 2>()); - vectorOps(Vector<double, 3>()); - vectorOps(Vector<complex<float>, 4>()); - vectorOps(VectorX<float>(1)); - vectorOps(VectorX<int>(2)); - vectorOps(VectorX<double>(3)); - vectorOps(VectorX<complex<float> >(4)); + vectorOps(Vector2i()); + vectorOps(Vector3d()); + vectorOps(Vector4cf()); + /*vectorOps(VectorXf(1)); + vectorOps(VectorXi(2)); + vectorOps(VectorXd(3)); + vectorOps(VectorXcf(4));*/ } |