mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-09-25 07:43:14 +08:00
add transposeInPlace (not optimized yet for rectangular matrix)
This commit is contained in:
parent
48137e28d8
commit
ebe14aae7d
@ -337,6 +337,7 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
Transpose<Derived> transpose();
|
Transpose<Derived> transpose();
|
||||||
const Transpose<Derived> transpose() const;
|
const Transpose<Derived> transpose() const;
|
||||||
|
void transposeInPlace();
|
||||||
const AdjointReturnType adjoint() const;
|
const AdjointReturnType adjoint() const;
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,6 +119,12 @@ template<typename MatrixType, unsigned int Mode> class Part
|
|||||||
const Block<Part, RowsAtCompileTime, 1> col(int i) { return Base::col(i); }
|
const Block<Part, RowsAtCompileTime, 1> col(int i) { return Base::col(i); }
|
||||||
const Block<Part, RowsAtCompileTime, 1> col(int i) const { return Base::col(i); }
|
const Block<Part, RowsAtCompileTime, 1> col(int i) const { return Base::col(i); }
|
||||||
|
|
||||||
|
template<typename OtherDerived/*, int OtherMode*/>
|
||||||
|
void swap(const MatrixBase<OtherDerived>& other)
|
||||||
|
{
|
||||||
|
Part<SwapWrapper<MatrixType>,Mode>(SwapWrapper<MatrixType>(const_cast<MatrixType&>(m_matrix))).lazyAssign(other.derived());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
@ -184,7 +190,7 @@ struct ei_part_assignment_impl
|
|||||||
|| (Mode == Lower && row >= col)
|
|| (Mode == Lower && row >= col)
|
||||||
|| (Mode == StrictlyUpper && row < col)
|
|| (Mode == StrictlyUpper && row < col)
|
||||||
|| (Mode == StrictlyLower && row > col))
|
|| (Mode == StrictlyLower && row > col))
|
||||||
dst.coeffRef(row, col) = src.coeff(row, col);
|
dst.copyCoeff(row, col, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -195,7 +201,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Mode, 1>
|
|||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
if(!(Mode & ZeroDiagBit))
|
if(!(Mode & ZeroDiagBit))
|
||||||
dst.coeffRef(0, 0) = src.coeff(0, 0);
|
dst.copyCoeff(0, 0, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -213,7 +219,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Upper, Dynamic>
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); j++)
|
for(int j = 0; j < dst.cols(); j++)
|
||||||
for(int i = 0; i <= j; i++)
|
for(int i = 0; i <= j; i++)
|
||||||
dst.coeffRef(i, j) = src.coeff(i, j);
|
dst.copyCoeff(i, j, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -224,7 +230,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Lower, Dynamic>
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); j++)
|
for(int j = 0; j < dst.cols(); j++)
|
||||||
for(int i = j; i < dst.rows(); i++)
|
for(int i = j; i < dst.rows(); i++)
|
||||||
dst.coeffRef(i, j) = src.coeff(i, j);
|
dst.copyCoeff(i, j, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,7 +241,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpper, Dynamic>
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); j++)
|
for(int j = 0; j < dst.cols(); j++)
|
||||||
for(int i = 0; i < j; i++)
|
for(int i = 0; i < j; i++)
|
||||||
dst.coeffRef(i, j) = src.coeff(i, j);
|
dst.copyCoeff(i, j, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
@ -245,7 +251,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLower, Dynamic>
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); j++)
|
for(int j = 0; j < dst.cols(); j++)
|
||||||
for(int i = j+1; i < dst.rows(); i++)
|
for(int i = j+1; i < dst.rows(); i++)
|
||||||
dst.coeffRef(i, j) = src.coeff(i, j);
|
dst.copyCoeff(i, j, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
|
@ -156,4 +156,49 @@ MatrixBase<Derived>::adjoint() const
|
|||||||
return conjugate().nestByValue();
|
return conjugate().nestByValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* "in place" transpose implementation
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
template<typename MatrixType,
|
||||||
|
bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
|
||||||
|
struct ei_inplace_transpose_selector;
|
||||||
|
|
||||||
|
template<typename MatrixType>
|
||||||
|
struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix
|
||||||
|
static void run(MatrixType& m) {
|
||||||
|
m.template part<StrictlyUpper>().swap(m.transpose());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename MatrixType>
|
||||||
|
struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
|
||||||
|
static void run(MatrixType& m) {
|
||||||
|
if (m.rows()==m.cols())
|
||||||
|
m.template part<StrictlyUpper>().swap(m.transpose());
|
||||||
|
else
|
||||||
|
m.set(m.transpose().eval());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** This is the "in place" version of transpose: it transposes \c *this.
|
||||||
|
*
|
||||||
|
* In most cases it is probably better to simply use the transposed expression
|
||||||
|
* of a matrix. However, when transposing the matrix data itself is really needed,
|
||||||
|
* then this "in-place" version is probably the right choice because it provides
|
||||||
|
* the following additional features:
|
||||||
|
* - less error prone: doing the same operation with .transpose() requires special care:
|
||||||
|
* \code m.set(m.transpose().eval()); \endcode
|
||||||
|
* - no temporary object is created (currently only for squared matrices)
|
||||||
|
* - it allows future optimizations (cache friendliness, etc.)
|
||||||
|
*
|
||||||
|
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||||
|
*
|
||||||
|
* \sa transpose(), adjoint() */
|
||||||
|
template<typename Derived>
|
||||||
|
inline void MatrixBase<Derived>::transposeInPlace()
|
||||||
|
{
|
||||||
|
ei_inplace_transpose_selector<Derived>::run(derived());
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EIGEN_TRANSPOSE_H
|
#endif // EIGEN_TRANSPOSE_H
|
||||||
|
@ -90,6 +90,14 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
|
|||||||
// normalized() in order to produce a consistent result.
|
// normalized() in order to produce a consistent result.
|
||||||
VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
|
VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check inplace transpose
|
||||||
|
m3 = m1;
|
||||||
|
m3.transposeInPlace();
|
||||||
|
VERIFY_IS_APPROX(m3,m1.transpose());
|
||||||
|
m3.transposeInPlace();
|
||||||
|
VERIFY_IS_APPROX(m3,m1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_adjoint()
|
void test_adjoint()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user