1*bf2c3715SXin Li // This file is triangularView of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2008-2009 Gael Guennebaud <[email protected]>
5*bf2c3715SXin Li //
6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9*bf2c3715SXin Li
10*bf2c3715SXin Li #include "main.h"
11*bf2c3715SXin Li
trmv(const MatrixType & m)12*bf2c3715SXin Li template<typename MatrixType> void trmv(const MatrixType& m)
13*bf2c3715SXin Li {
14*bf2c3715SXin Li typedef typename MatrixType::Scalar Scalar;
15*bf2c3715SXin Li typedef typename NumTraits<Scalar>::Real RealScalar;
16*bf2c3715SXin Li typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
17*bf2c3715SXin Li
18*bf2c3715SXin Li RealScalar largerEps = 10*test_precision<RealScalar>();
19*bf2c3715SXin Li
20*bf2c3715SXin Li Index rows = m.rows();
21*bf2c3715SXin Li Index cols = m.cols();
22*bf2c3715SXin Li
23*bf2c3715SXin Li MatrixType m1 = MatrixType::Random(rows, cols),
24*bf2c3715SXin Li m3(rows, cols);
25*bf2c3715SXin Li VectorType v1 = VectorType::Random(rows);
26*bf2c3715SXin Li
27*bf2c3715SXin Li Scalar s1 = internal::random<Scalar>();
28*bf2c3715SXin Li
29*bf2c3715SXin Li m1 = MatrixType::Random(rows, cols);
30*bf2c3715SXin Li
31*bf2c3715SXin Li // check with a column-major matrix
32*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Lower>();
33*bf2c3715SXin Li VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Lower>() * v1, largerEps));
34*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Upper>();
35*bf2c3715SXin Li VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Upper>() * v1, largerEps));
36*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::UnitLower>();
37*bf2c3715SXin Li VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitLower>() * v1, largerEps));
38*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::UnitUpper>();
39*bf2c3715SXin Li VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitUpper>() * v1, largerEps));
40*bf2c3715SXin Li
41*bf2c3715SXin Li // check conjugated and scalar multiple expressions (col-major)
42*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Lower>();
43*bf2c3715SXin Li VERIFY(((s1*m3).conjugate() * v1).isApprox((s1*m1).conjugate().template triangularView<Eigen::Lower>() * v1, largerEps));
44*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Upper>();
45*bf2c3715SXin Li VERIFY((m3.conjugate() * v1.conjugate()).isApprox(m1.conjugate().template triangularView<Eigen::Upper>() * v1.conjugate(), largerEps));
46*bf2c3715SXin Li
47*bf2c3715SXin Li // check with a row-major matrix
48*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Upper>();
49*bf2c3715SXin Li VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Lower>() * v1, largerEps));
50*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Lower>();
51*bf2c3715SXin Li VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Upper>() * v1, largerEps));
52*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::UnitUpper>();
53*bf2c3715SXin Li VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitLower>() * v1, largerEps));
54*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::UnitLower>();
55*bf2c3715SXin Li VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitUpper>() * v1, largerEps));
56*bf2c3715SXin Li
57*bf2c3715SXin Li // check conjugated and scalar multiple expressions (row-major)
58*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Upper>();
59*bf2c3715SXin Li VERIFY((m3.adjoint() * v1).isApprox(m1.adjoint().template triangularView<Eigen::Lower>() * v1, largerEps));
60*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Lower>();
61*bf2c3715SXin Li VERIFY((m3.adjoint() * (s1*v1.conjugate())).isApprox(m1.adjoint().template triangularView<Eigen::Upper>() * (s1*v1.conjugate()), largerEps));
62*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::UnitUpper>();
63*bf2c3715SXin Li
64*bf2c3715SXin Li // check transposed cases:
65*bf2c3715SXin Li m3 = m1.template triangularView<Eigen::Lower>();
66*bf2c3715SXin Li VERIFY((v1.transpose() * m3).isApprox(v1.transpose() * m1.template triangularView<Eigen::Lower>(), largerEps));
67*bf2c3715SXin Li VERIFY((v1.adjoint() * m3).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>(), largerEps));
68*bf2c3715SXin Li VERIFY((v1.adjoint() * m3.adjoint()).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>().adjoint(), largerEps));
69*bf2c3715SXin Li
70*bf2c3715SXin Li // TODO check with sub-matrices
71*bf2c3715SXin Li }
72*bf2c3715SXin Li
EIGEN_DECLARE_TEST(product_trmv)73*bf2c3715SXin Li EIGEN_DECLARE_TEST(product_trmv)
74*bf2c3715SXin Li {
75*bf2c3715SXin Li int s = 0;
76*bf2c3715SXin Li for(int i = 0; i < g_repeat ; i++) {
77*bf2c3715SXin Li CALL_SUBTEST_1( trmv(Matrix<float, 1, 1>()) );
78*bf2c3715SXin Li CALL_SUBTEST_2( trmv(Matrix<float, 2, 2>()) );
79*bf2c3715SXin Li CALL_SUBTEST_3( trmv(Matrix3d()) );
80*bf2c3715SXin Li
81*bf2c3715SXin Li s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);
82*bf2c3715SXin Li CALL_SUBTEST_4( trmv(MatrixXcf(s,s)) );
83*bf2c3715SXin Li CALL_SUBTEST_5( trmv(MatrixXcd(s,s)) );
84*bf2c3715SXin Li TEST_SET_BUT_UNUSED_VARIABLE(s)
85*bf2c3715SXin Li
86*bf2c3715SXin Li s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
87*bf2c3715SXin Li CALL_SUBTEST_6( trmv(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );
88*bf2c3715SXin Li TEST_SET_BUT_UNUSED_VARIABLE(s)
89*bf2c3715SXin Li }
90*bf2c3715SXin Li }
91