diff options
-rw-r--r-- | Eigen/src/Core/CommaInitializer.h | 63 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 3 | ||||
-rw-r--r-- | doc/snippets/MatrixBase_set.cpp | 9 | ||||
-rw-r--r-- | test/basicstuff.cpp | 22 |
4 files changed, 84 insertions, 13 deletions
diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h index 0e6674be1..ba64f3f40 100644 --- a/Eigen/src/Core/CommaInitializer.h +++ b/Eigen/src/Core/CommaInitializer.h @@ -26,28 +26,66 @@ #ifndef EIGEN_COMMA_INITIALIZER_H #define EIGEN_COMMA_INITIALIZER_H +/** \internal + * Helper class to define the MatrixBase::operator<< + */ template<typename Scalar, typename Derived> struct MatrixBase<Scalar, Derived>::CommaInitializer { - CommaInitializer(Derived& mat) : m_matrix(mat), m_count(1) {} + CommaInitializer(Derived& mat, const Scalar& s) + : m_matrix(mat), m_row(0), m_col(1), m_currentBlockRows(1) + { + m_matrix.coeffRef(0,0) = s; + } + + template<typename OtherDerived> + CommaInitializer(Derived& mat, const MatrixBase<Scalar, OtherDerived>& other) + : m_matrix(mat), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows()) + { + m_matrix.block(0, 0, other.rows(), other.cols()) = other; + } - CommaInitializer& operator,(const Scalar& s) { - assert(m_count<m_matrix.size() && "Too many coefficients passed to Matrix::operator<<"); - m_matrix._coeffRef(m_count/m_matrix.cols(), m_count%m_matrix.cols()) = s; - m_count++; + CommaInitializer& operator,(const Scalar& s) + { + if (m_col==m_matrix.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = 1; + } + assert(m_col<m_matrix.cols() && "Too many coefficients passed to Matrix::operator<<"); + assert(m_currentBlockRows==1); + m_matrix._coeffRef(m_row, m_col++) = s; + return *this; + } + + template<typename OtherDerived> + CommaInitializer& operator,(const MatrixBase<Scalar, OtherDerived>& other) + { + if (m_col==m_matrix.cols()) + { + m_row+=m_currentBlockRows; + m_col = 0; + m_currentBlockRows = other.rows(); + } + assert(m_col<m_matrix.cols() && "Too many coefficients passed to Matrix::operator<<"); + assert(m_currentBlockRows==other.rows()); + m_matrix.block(m_row, m_col, other.rows(), other.cols()) = other; + m_col += other.cols(); return *this; } ~CommaInitializer(void) { - assert(m_count==m_matrix.size() && "Too few coefficients passed to Matrix::operator<<"); + assert((m_row+m_currentBlockRows)==m_matrix.rows() && m_col==m_matrix.cols() && "Too few coefficients passed to Matrix::operator<<"); } Derived& m_matrix; - int m_count; + int m_row; // current row id + int m_col; // current col id + int m_currentBlockRows; // current block height }; - /** Convenient operator to set the coefficients of a matrix. * * The coefficients must be provided in a row major order and exactly match @@ -59,9 +97,14 @@ struct MatrixBase<Scalar, Derived>::CommaInitializer template<typename Scalar, typename Derived> typename MatrixBase<Scalar, Derived>::CommaInitializer MatrixBase<Scalar, Derived>::operator<< (const Scalar& s) { - coeffRef(0,0) = s; - return CommaInitializer(*static_cast<Derived *>(this)); + return CommaInitializer(*static_cast<Derived *>(this), s); } +template<typename Scalar, typename Derived> +template<typename OtherDerived> +typename MatrixBase<Scalar, Derived>::CommaInitializer MatrixBase<Scalar, Derived>::operator<< (const MatrixBase<Scalar, OtherDerived>& other) +{ + return CommaInitializer(*static_cast<Derived *>(this), other); +} #endif // EIGEN_COMMA_INITIALIZER_H diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index e924fa329..b0b5a50a3 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -182,6 +182,9 @@ template<typename Scalar, typename Derived> class MatrixBase CommaInitializer operator<< (const Scalar& s); + template<typename OtherDerived> + CommaInitializer operator<< (const MatrixBase<Scalar, OtherDerived>& other); + /** swaps *this with the expression \a other. * * \note \a other is only marked const because I couln't find another way diff --git a/doc/snippets/MatrixBase_set.cpp b/doc/snippets/MatrixBase_set.cpp index 376efbce5..f6ccb1099 100644 --- a/doc/snippets/MatrixBase_set.cpp +++ b/doc/snippets/MatrixBase_set.cpp @@ -1,8 +1,13 @@ Matrix3i m1; -m1 <<= 1, 2, 3, +m1 << 1, 2, 3, 4, 5, 6, 7, 8, 9; cout << m1 << endl << endl; Matrix3i m2 = Matrix3i::identity(); -m2.block(0,0, 2,2) <<= 10, 11, 12, 13; +m2.block(0,0, 2,2) << 10, 11, 12, 13; +cout << m2 << endl << endl; +Vector2i v1; +v1 << 14, 15; +m2 << v1.transpose(), 16, + v1, m1.block(1,1,2,2); cout << m2 << endl;
\ No newline at end of file diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp index 56f41ed4a..bd009eb0b 100644 --- a/test/basicstuff.cpp +++ b/test/basicstuff.cpp @@ -105,8 +105,28 @@ void EigenTest::testBasicStuff() VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) ); VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ); - m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; + double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + m3 = Matrix3d::random(); + m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; + VERIFY_IS_APPROX(m3, (Matrix<double,3,3,RowMajor>::map(data)) ); + + Vector3d vec[3]; + vec[0] << 1, 4, 7; + vec[1] << 2, 5, 8; + vec[2] << 3, 6, 9; + m3 = Matrix3d::random(); + m3 << vec[0], vec[1], vec[2]; + VERIFY_IS_APPROX(m3, (Matrix<double,3,3,RowMajor>::map(data)) ); + + vec[0] << 1, 2, 3; + vec[1] << 4, 5, 6; + vec[2] << 7, 8, 9; + m3 = Matrix3d::random(); + m3 << vec[0].transpose(), + 4, 5, 6, + vec[2].transpose(); VERIFY_IS_APPROX(m3, (Matrix<double,3,3,RowMajor>::map(data)) ); } } |