1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 template<typename Scalar
, int Size
, int OtherSize
> void symm(int size
= Size
, int othersize
= OtherSize
)
14 typedef Matrix
<Scalar
, Size
, Size
> MatrixType
;
15 typedef Matrix
<Scalar
, Size
, OtherSize
> Rhs1
;
16 typedef Matrix
<Scalar
, OtherSize
, Size
> Rhs2
;
17 enum { order
= OtherSize
==1 ? 0 : RowMajor
};
18 typedef Matrix
<Scalar
, Size
, OtherSize
,order
> Rhs3
;
19 typedef typename
MatrixType::Index Index
;
24 MatrixType m1
= MatrixType::Random(rows
, cols
),
25 m2
= MatrixType::Random(rows
, cols
), m3
;
27 m1
= (m1
+m1
.adjoint()).eval();
29 Rhs1 rhs1
= Rhs1::Random(cols
, othersize
), rhs12(cols
, othersize
), rhs13(cols
, othersize
);
30 Rhs2 rhs2
= Rhs2::Random(othersize
, rows
), rhs22(othersize
, rows
), rhs23(othersize
, rows
);
31 Rhs3 rhs3
= Rhs3::Random(cols
, othersize
), rhs32(cols
, othersize
), rhs33(cols
, othersize
);
33 Scalar s1
= internal::random
<Scalar
>(),
34 s2
= internal::random
<Scalar
>();
36 m2
= m1
.template triangularView
<Lower
>();
37 m3
= m2
.template selfadjointView
<Lower
>();
38 VERIFY_IS_EQUAL(m1
, m3
);
39 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Lower
>() * (s2
*rhs1
),
40 rhs13
= (s1
*m1
) * (s2
*rhs1
));
42 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).transpose().template selfadjointView
<Upper
>() * (s2
*rhs1
),
43 rhs13
= (s1
*m1
.transpose()) * (s2
*rhs1
));
45 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Lower
>().transpose() * (s2
*rhs1
),
46 rhs13
= (s1
*m1
.transpose()) * (s2
*rhs1
));
48 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).conjugate().template selfadjointView
<Lower
>() * (s2
*rhs1
),
49 rhs13
= (s1
*m1
).conjugate() * (s2
*rhs1
));
51 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Lower
>().conjugate() * (s2
*rhs1
),
52 rhs13
= (s1
*m1
).conjugate() * (s2
*rhs1
));
54 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).adjoint().template selfadjointView
<Upper
>() * (s2
*rhs1
),
55 rhs13
= (s1
*m1
).adjoint() * (s2
*rhs1
));
57 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Lower
>().adjoint() * (s2
*rhs1
),
58 rhs13
= (s1
*m1
).adjoint() * (s2
*rhs1
));
60 m2
= m1
.template triangularView
<Upper
>(); rhs12
.setRandom(); rhs13
= rhs12
;
61 m3
= m2
.template selfadjointView
<Upper
>();
62 VERIFY_IS_EQUAL(m1
, m3
);
63 VERIFY_IS_APPROX(rhs12
+= (s1
*m2
).template selfadjointView
<Upper
>() * (s2
*rhs1
),
64 rhs13
+= (s1
*m1
) * (s2
*rhs1
));
66 m2
= m1
.template triangularView
<Lower
>();
67 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Lower
>() * (s2
*rhs2
.adjoint()),
68 rhs13
= (s1
*m1
) * (s2
*rhs2
.adjoint()));
70 m2
= m1
.template triangularView
<Upper
>();
71 VERIFY_IS_APPROX(rhs12
= (s1
*m2
).template selfadjointView
<Upper
>() * (s2
*rhs2
.adjoint()),
72 rhs13
= (s1
*m1
) * (s2
*rhs2
.adjoint()));
74 m2
= m1
.template triangularView
<Upper
>();
75 VERIFY_IS_APPROX(rhs12
= (s1
*m2
.adjoint()).template selfadjointView
<Lower
>() * (s2
*rhs2
.adjoint()),
76 rhs13
= (s1
*m1
.adjoint()) * (s2
*rhs2
.adjoint()));
78 // test row major = <...>
79 m2
= m1
.template triangularView
<Lower
>(); rhs12
.setRandom(); rhs13
= rhs12
;
80 VERIFY_IS_APPROX(rhs12
-= (s1
*m2
).template selfadjointView
<Lower
>() * (s2
*rhs3
),
81 rhs13
-= (s1
*m1
) * (s2
* rhs3
));
83 m2
= m1
.template triangularView
<Upper
>();
84 VERIFY_IS_APPROX(rhs12
= (s1
*m2
.adjoint()).template selfadjointView
<Lower
>() * (s2
*rhs3
).conjugate(),
85 rhs13
= (s1
*m1
.adjoint()) * (s2
*rhs3
).conjugate());
88 m2
= m1
.template triangularView
<Upper
>(); rhs13
= rhs12
;
89 VERIFY_IS_APPROX(rhs12
.noalias() += s1
* ((m2
.adjoint()).template selfadjointView
<Lower
>() * (s2
*rhs3
).conjugate()),
90 rhs13
+= (s1
*m1
.adjoint()) * (s2
*rhs3
).conjugate());
92 m2
= m1
.template triangularView
<Lower
>();
93 VERIFY_IS_APPROX(rhs22
= (rhs2
) * (m2
).template selfadjointView
<Lower
>(), rhs23
= (rhs2
) * (m1
));
94 VERIFY_IS_APPROX(rhs22
= (s2
*rhs2
) * (s1
*m2
).template selfadjointView
<Lower
>(), rhs23
= (s2
*rhs2
) * (s1
*m1
));
98 void test_product_symm()
100 for(int i
= 0; i
< g_repeat
; i
++)
102 CALL_SUBTEST_1(( symm
<float,Dynamic
,Dynamic
>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
),internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));
103 CALL_SUBTEST_2(( symm
<double,Dynamic
,Dynamic
>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
),internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));
104 CALL_SUBTEST_3(( symm
<std::complex<float>,Dynamic
,Dynamic
>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/2),internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/2)) ));
105 CALL_SUBTEST_4(( symm
<std::complex<double>,Dynamic
,Dynamic
>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/2),internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
/2)) ));
107 CALL_SUBTEST_5(( symm
<float,Dynamic
,1>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));
108 CALL_SUBTEST_6(( symm
<double,Dynamic
,1>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));
109 CALL_SUBTEST_7(( symm
<std::complex<float>,Dynamic
,1>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));
110 CALL_SUBTEST_8(( symm
<std::complex<double>,Dynamic
,1>(internal::random
<int>(1,EIGEN_TEST_MAX_SIZE
)) ));