mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-12 19:20:36 +08:00
Extended the comma initializer to support xpr on the right side:
Matrix3i mat; Vector2i vec(33,66); mat << vec.transpose(), 99, vec, Matrix2i::random();
This commit is contained in:
parent
721626dfc5
commit
f64311e07d
@ -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;
|
||||
}
|
||||
|
||||
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++;
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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)) );
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user