mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
various compilation and bug fixes in selfadjoint stuff
This commit is contained in:
@@ -119,8 +119,8 @@ void test_eigensolver_selfadjoint()
|
||||
// very important to test a 3x3 matrix since we provide a special path for it
|
||||
CALL_SUBTEST( selfadjointeigensolver(Matrix3f()) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(Matrix4d()) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(MatrixXf(4,4)) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(MatrixXcd(7,7)) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(MatrixXf(10,10)) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(MatrixXcd(17,17)) );
|
||||
CALL_SUBTEST( selfadjointeigensolver(MatrixXd(19,19)) );
|
||||
|
||||
// some trivial but implementation-wise tricky cases
|
||||
|
||||
@@ -62,13 +62,14 @@ template<typename MatrixType> void product_extra(const MatrixType& m)
|
||||
// all the expressions in this test should be compiled as a single matrix product
|
||||
// TODO: add internal checks to verify that
|
||||
|
||||
VERIFY_IS_APPROX(m1 * m2.adjoint(), m1 * m2.adjoint().eval());
|
||||
VERIFY_IS_APPROX(m1.adjoint() * square.adjoint(), m1.adjoint().eval() * square.adjoint().eval());
|
||||
VERIFY_IS_APPROX(m1.adjoint() * m2, m1.adjoint().eval() * m2);
|
||||
VERIFY_IS_APPROX( (s1 * m1.adjoint()) * m2, (s1 * m1.adjoint()).eval() * m2);
|
||||
VERIFY_IS_APPROX( (- m1.adjoint() * s1) * (s3 * m2), (- m1.adjoint() * s1).eval() * (s3 * m2).eval());
|
||||
VERIFY_IS_APPROX( (s2 * m1.adjoint() * s1) * m2, (s2 * m1.adjoint() * s1).eval() * m2);
|
||||
VERIFY_IS_APPROX( (-m1*s2) * s1*m2.adjoint(), (-m1*s2).eval() * (s1*m2.adjoint()).eval());
|
||||
VERIFY_IS_APPROX(m3 = (m1 * m2.adjoint()).lazy(), m1 * m2.adjoint().eval());
|
||||
VERIFY_IS_APPROX(m3 = (m1.adjoint() * square.adjoint()).lazy(), m1.adjoint().eval() * square.adjoint().eval());
|
||||
VERIFY_IS_APPROX(m3 = (m1.adjoint() * m2).lazy(), m1.adjoint().eval() * m2);
|
||||
VERIFY_IS_APPROX(m3 = ((s1 * m1.adjoint()) * m2).lazy(), (s1 * m1.adjoint()).eval() * m2);
|
||||
VERIFY_IS_APPROX(m3 = ((- m1.adjoint() * s1) * (s3 * m2)).lazy(), (- m1.adjoint() * s1).eval() * (s3 * m2).eval());
|
||||
VERIFY_IS_APPROX(m3 = ((s2 * m1.adjoint() * s1) * m2).lazy(), (s2 * m1.adjoint() * s1).eval() * m2);
|
||||
VERIFY_IS_APPROX(m3 = ((-m1*s2) * s1*m2.adjoint()).lazy(), (-m1*s2).eval() * (s1*m2.adjoint()).eval());
|
||||
|
||||
// a very tricky case where a scale factor has to be automatically conjugated:
|
||||
VERIFY_IS_APPROX( m1.adjoint() * (s1*m2).conjugate(), (m1.adjoint()).eval() * ((s1*m2).conjugate()).eval());
|
||||
|
||||
|
||||
@@ -52,42 +52,23 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
|
||||
|
||||
m1 = (m1.adjoint() + m1).eval();
|
||||
|
||||
// lower
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*v1), (s1*m1) * (s2*v1));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.conjugate()).template selfadjointView<LowerTriangular>() * (s2*v1), (s1*m1.conjugate()) * (s2*v1));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*m4.col(1)), (s1*m1) * (s2*m4.col(1)));
|
||||
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*v1.conjugate()), (s1*m1) * (s2*v1.conjugate()));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.conjugate()).template selfadjointView<LowerTriangular>() * (s2*v1.conjugate()), (s1*m1.conjugate()) * (s2*v1.conjugate()));
|
||||
|
||||
// upper
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2).template selfadjointView<UpperTriangular>() * (s2*v1), (s1*m1) * (s2*v1));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.conjugate()).template selfadjointView<UpperTriangular>() * (s2*v1), (s1*m1.conjugate()) * (s2*v1));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.adjoint()).template selfadjointView<LowerTriangular>() * (s2*v1), (s1*m1.adjoint()) * (s2*v1));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.transpose()).template selfadjointView<LowerTriangular>() * (s2*v1), (s1*m1.transpose()) * (s2*v1));
|
||||
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2).template selfadjointView<UpperTriangular>() * (s2*v1.conjugate()), (s1*m1) * (s2*v1.conjugate()));
|
||||
VERIFY_IS_APPROX(v3 = (s1*m2.conjugate()).template selfadjointView<UpperTriangular>() * (s2*v1.conjugate()), (s1*m1.conjugate()) * (s2*v1.conjugate()));
|
||||
|
||||
// rank2 update
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
m2.template selfadjointView<LowerTriangular>().rank2update(v1,v2);
|
||||
m2.template selfadjointView<LowerTriangular>().rankUpdate(v1,v2);
|
||||
VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<LowerTriangular>().toDense());
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
m2.template selfadjointView<UpperTriangular>().rank2update(-v1,s2*v2,s3);
|
||||
m2.template selfadjointView<UpperTriangular>().rankUpdate(-v1,s2*v2,s3);
|
||||
VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView<UpperTriangular>().toDense());
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
m2.template selfadjointView<UpperTriangular>().rank2update(-r1.adjoint(),r2.adjoint()*s3,s1);
|
||||
m2.template selfadjointView<UpperTriangular>().rankUpdate(-r1.adjoint(),r2.adjoint()*s3,s1);
|
||||
VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView<UpperTriangular>().toDense());
|
||||
|
||||
if (rows>1)
|
||||
{
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rank2update(v1.end(rows-1),v2.start(cols-1));
|
||||
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rankUpdate(v1.end(rows-1),v2.start(cols-1));
|
||||
m3 = m1;
|
||||
m3.block(1,1,rows-1,cols-1) += v1.end(rows-1) * v2.start(cols-1).adjoint()+ v2.start(cols-1) * v1.end(rows-1).adjoint();
|
||||
VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDense());
|
||||
|
||||
@@ -24,25 +24,43 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
template<typename MatrixType> void symm(const MatrixType& m)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic> Rhs1;
|
||||
typedef Matrix<Scalar, Dynamic, MatrixType::RowsAtCompileTime> Rhs2;
|
||||
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic,RowMajor> Rhs3;
|
||||
template<int OtherSize> struct symm_extra {
|
||||
template<typename M1, typename M2, typename Scalar>
|
||||
static void run(M1& m1, M1& m2, M2& rhs2, M2& rhs22, M2& rhs23, Scalar s1, Scalar s2)
|
||||
{
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<LowerTriangular>(),
|
||||
rhs23 = (rhs2) * (m1));
|
||||
VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<LowerTriangular>(),
|
||||
rhs23 = (s2*rhs2) * (s1*m1));
|
||||
}
|
||||
};
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
template<> struct symm_extra<1> {
|
||||
template<typename M1, typename M2, typename Scalar>
|
||||
static void run(M1& m1, M1& m2, M2& rhs2, M2& rhs22, M2& rhs23, Scalar s1, Scalar s2) {}
|
||||
};
|
||||
|
||||
template<typename Scalar, int Size, int OtherSize> void symm(int size = Size, int othersize = OtherSize)
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
typedef Matrix<Scalar, Size, Size> MatrixType;
|
||||
typedef Matrix<Scalar, Size, OtherSize> Rhs1;
|
||||
typedef Matrix<Scalar, OtherSize, Size> Rhs2;
|
||||
typedef Matrix<Scalar, Size, OtherSize,RowMajor> Rhs3;
|
||||
|
||||
int rows = size;
|
||||
int cols = size;
|
||||
|
||||
MatrixType m1 = MatrixType::Random(rows, cols),
|
||||
m2 = MatrixType::Random(rows, cols);
|
||||
|
||||
m1 = (m1+m1.adjoint()).eval();
|
||||
|
||||
Rhs1 rhs1 = Rhs1::Random(cols, ei_random<int>(1,320)), rhs12, rhs13;
|
||||
Rhs2 rhs2 = Rhs2::Random(ei_random<int>(1,320), rows), rhs22, rhs23;
|
||||
Rhs3 rhs3 = Rhs3::Random(cols, ei_random<int>(1,320)), rhs32, rhs33;
|
||||
Rhs1 rhs1 = Rhs1::Random(cols, othersize), rhs12(cols, othersize), rhs13(cols, othersize);
|
||||
Rhs2 rhs2 = Rhs2::Random(othersize, rows), rhs22(othersize, rows), rhs23(othersize, rows);
|
||||
Rhs3 rhs3 = Rhs3::Random(cols, othersize), rhs32(cols, othersize), rhs33(cols, othersize);
|
||||
|
||||
Scalar s1 = ei_random<Scalar>(),
|
||||
s2 = ei_random<Scalar>();
|
||||
@@ -51,46 +69,44 @@ template<typename MatrixType> void symm(const MatrixType& m)
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*rhs1),
|
||||
rhs13 = (s1*m1) * (s2*rhs1));
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<UpperTriangular>() * (s2*rhs1),
|
||||
rhs13 = (s1*m1) * (s2*rhs1));
|
||||
m2 = m1.template triangularView<UpperTriangular>(); rhs12.setRandom(); rhs13 = rhs12;
|
||||
VERIFY_IS_APPROX(rhs12 += (s1*m2).template selfadjointView<UpperTriangular>() * (s2*rhs1),
|
||||
rhs13 += (s1*m1) * (s2*rhs1));
|
||||
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
VERIFY_IS_APPROX(rhs22 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs23 = (s1*m1) * (s2*rhs2.adjoint()));
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs13 = (s1*m1) * (s2*rhs2.adjoint()));
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
VERIFY_IS_APPROX(rhs22 = (s1*m2).template selfadjointView<UpperTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs23 = (s1*m1) * (s2*rhs2.adjoint()));
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<UpperTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs13 = (s1*m1) * (s2*rhs2.adjoint()));
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
VERIFY_IS_APPROX(rhs22 = (s1*m2.adjoint()).template selfadjointView<LowerTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs23 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<LowerTriangular>() * (s2*rhs2.adjoint()),
|
||||
rhs13 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));
|
||||
|
||||
// test row major = <...>
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
VERIFY_IS_APPROX(rhs32 = (s1*m2).template selfadjointView<LowerTriangular>() * (s2*rhs3),
|
||||
rhs33 = (s1*m1) * (s2 * rhs3));
|
||||
m2 = m1.template triangularView<LowerTriangular>(); rhs12.setRandom(); rhs13 = rhs12;
|
||||
VERIFY_IS_APPROX(rhs12 -= (s1*m2).template selfadjointView<LowerTriangular>() * (s2*rhs3),
|
||||
rhs13 -= (s1*m1) * (s2 * rhs3));
|
||||
|
||||
m2 = m1.template triangularView<UpperTriangular>();
|
||||
VERIFY_IS_APPROX(rhs32 = (s1*m2.adjoint()).template selfadjointView<LowerTriangular>() * (s2*rhs3).conjugate(),
|
||||
rhs33 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());
|
||||
VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<LowerTriangular>() * (s2*rhs3).conjugate(),
|
||||
rhs13 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());
|
||||
|
||||
// test matrix * selfadjoint
|
||||
m2 = m1.template triangularView<LowerTriangular>();
|
||||
VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<LowerTriangular>(),
|
||||
rhs23 = (rhs2) * (m1));
|
||||
VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<LowerTriangular>(),
|
||||
rhs23 = (s2*rhs2) * (s1*m1));
|
||||
symm_extra<OtherSize>::run(m1,m2,rhs2,rhs22,rhs23,s1,s2);
|
||||
|
||||
}
|
||||
|
||||
void test_product_symm()
|
||||
{
|
||||
for(int i = 0; i < g_repeat ; i++)
|
||||
{
|
||||
int s;
|
||||
s = ei_random<int>(10,320);
|
||||
CALL_SUBTEST( symm(MatrixXf(s, s)) );
|
||||
s = ei_random<int>(10,320);
|
||||
CALL_SUBTEST( symm(MatrixXcd(s, s)) );
|
||||
CALL_SUBTEST(( symm<float,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
|
||||
|
||||
CALL_SUBTEST(( symm<float,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
CALL_SUBTEST(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,27 +46,27 @@ template<typename MatrixType> void syrk(const MatrixType& m)
|
||||
s2 = ei_random<Scalar>();
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX((m2.template selfadjointView<LowerTriangular>().rankKupdate(rhs2,s1)._expression()),
|
||||
VERIFY_IS_APPROX((m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs2,s1)._expression()),
|
||||
((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<LowerTriangular>().toDense()));
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankKupdate(rhs2,s1)._expression(),
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs2,s1)._expression(),
|
||||
(s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<UpperTriangular>().toDense());
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankKupdate(rhs1.adjoint(),s1)._expression(),
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
|
||||
(s1 * rhs1.adjoint() * rhs1).eval().template triangularView<LowerTriangular>().toDense());
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankKupdate(rhs1.adjoint(),s1)._expression(),
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
|
||||
(s1 * rhs1.adjoint() * rhs1).eval().template triangularView<UpperTriangular>().toDense());
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankKupdate(rhs3.adjoint(),s1)._expression(),
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
|
||||
(s1 * rhs3.adjoint() * rhs3).eval().template triangularView<LowerTriangular>().toDense());
|
||||
|
||||
m2.setZero();
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankKupdate(rhs3.adjoint(),s1)._expression(),
|
||||
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
|
||||
(s1 * rhs3.adjoint() * rhs3).eval().template triangularView<UpperTriangular>().toDense());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user