xref: /aosp_15_r20/external/eigen/test/nesting_ops.cpp (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li // for linear algebra.
3*bf2c3715SXin Li //
4*bf2c3715SXin Li // Copyright (C) 2010 Hauke Heibel <[email protected]>
5*bf2c3715SXin Li // Copyright (C) 2015 Gael Guennebaud <[email protected]>
6*bf2c3715SXin Li //
7*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla
8*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed
9*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10*bf2c3715SXin Li 
11*bf2c3715SXin Li #define TEST_ENABLE_TEMPORARY_TRACKING
12*bf2c3715SXin Li 
13*bf2c3715SXin Li #include "main.h"
14*bf2c3715SXin Li 
15*bf2c3715SXin Li template <int N, typename XprType>
use_n_times(const XprType & xpr)16*bf2c3715SXin Li void use_n_times(const XprType &xpr)
17*bf2c3715SXin Li {
18*bf2c3715SXin Li   typename internal::nested_eval<XprType,N>::type mat(xpr);
19*bf2c3715SXin Li   typename XprType::PlainObject res(mat.rows(), mat.cols());
20*bf2c3715SXin Li   nb_temporaries--; // remove res
21*bf2c3715SXin Li   res.setZero();
22*bf2c3715SXin Li   for(int i=0; i<N; ++i)
23*bf2c3715SXin Li     res += mat;
24*bf2c3715SXin Li }
25*bf2c3715SXin Li 
26*bf2c3715SXin Li template <int N, typename ReferenceType, typename XprType>
verify_eval_type(const XprType &,const ReferenceType &)27*bf2c3715SXin Li bool verify_eval_type(const XprType &, const ReferenceType&)
28*bf2c3715SXin Li {
29*bf2c3715SXin Li   typedef typename internal::nested_eval<XprType,N>::type EvalType;
30*bf2c3715SXin Li   return internal::is_same<typename internal::remove_all<EvalType>::type, typename internal::remove_all<ReferenceType>::type>::value;
31*bf2c3715SXin Li }
32*bf2c3715SXin Li 
run_nesting_ops_1(const MatrixType & _m)33*bf2c3715SXin Li template <typename MatrixType> void run_nesting_ops_1(const MatrixType& _m)
34*bf2c3715SXin Li {
35*bf2c3715SXin Li   typename internal::nested_eval<MatrixType,2>::type m(_m);
36*bf2c3715SXin Li 
37*bf2c3715SXin Li   // Make really sure that we are in debug mode!
38*bf2c3715SXin Li   VERIFY_RAISES_ASSERT(eigen_assert(false));
39*bf2c3715SXin Li 
40*bf2c3715SXin Li   // The only intention of these tests is to ensure that this code does
41*bf2c3715SXin Li   // not trigger any asserts or segmentation faults... more to come.
42*bf2c3715SXin Li   VERIFY_IS_APPROX( (m.transpose() * m).diagonal().sum(), (m.transpose() * m).diagonal().sum() );
43*bf2c3715SXin Li   VERIFY_IS_APPROX( (m.transpose() * m).diagonal().array().abs().sum(), (m.transpose() * m).diagonal().array().abs().sum() );
44*bf2c3715SXin Li 
45*bf2c3715SXin Li   VERIFY_IS_APPROX( (m.transpose() * m).array().abs().sum(), (m.transpose() * m).array().abs().sum() );
46*bf2c3715SXin Li }
47*bf2c3715SXin Li 
run_nesting_ops_2(const MatrixType & _m)48*bf2c3715SXin Li template <typename MatrixType> void run_nesting_ops_2(const MatrixType& _m)
49*bf2c3715SXin Li {
50*bf2c3715SXin Li   typedef typename MatrixType::Scalar Scalar;
51*bf2c3715SXin Li   Index rows = _m.rows();
52*bf2c3715SXin Li   Index cols = _m.cols();
53*bf2c3715SXin Li   MatrixType m1 = MatrixType::Random(rows,cols);
54*bf2c3715SXin Li   Matrix<Scalar,MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime,ColMajor> m2;
55*bf2c3715SXin Li 
56*bf2c3715SXin Li   if((MatrixType::SizeAtCompileTime==Dynamic))
57*bf2c3715SXin Li   {
58*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<1>(m1 + m1*m1), 1 );
59*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<10>(m1 + m1*m1), 1 );
60*bf2c3715SXin Li 
61*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<1>(m1.template triangularView<Lower>().solve(m1.col(0))), 1 );
62*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<10>(m1.template triangularView<Lower>().solve(m1.col(0))), 1 );
63*bf2c3715SXin Li 
64*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<1>(Scalar(2)*m1.template triangularView<Lower>().solve(m1.col(0))), 2 ); // FIXME could be one by applying the scaling in-place on the solve result
65*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<1>(m1.col(0)+m1.template triangularView<Lower>().solve(m1.col(0))), 2 ); // FIXME could be one by adding m1.col() inplace
66*bf2c3715SXin Li     VERIFY_EVALUATION_COUNT( use_n_times<10>(m1.col(0)+m1.template triangularView<Lower>().solve(m1.col(0))), 2 );
67*bf2c3715SXin Li   }
68*bf2c3715SXin Li 
69*bf2c3715SXin Li   {
70*bf2c3715SXin Li     VERIFY( verify_eval_type<10>(m1, m1) );
71*bf2c3715SXin Li     if(!NumTraits<Scalar>::IsComplex)
72*bf2c3715SXin Li     {
73*bf2c3715SXin Li       VERIFY( verify_eval_type<3>(2*m1, 2*m1) );
74*bf2c3715SXin Li       VERIFY( verify_eval_type<4>(2*m1, m1) );
75*bf2c3715SXin Li     }
76*bf2c3715SXin Li     else
77*bf2c3715SXin Li     {
78*bf2c3715SXin Li       VERIFY( verify_eval_type<2>(2*m1, 2*m1) );
79*bf2c3715SXin Li       VERIFY( verify_eval_type<3>(2*m1, m1) );
80*bf2c3715SXin Li     }
81*bf2c3715SXin Li     VERIFY( verify_eval_type<2>(m1+m1, m1+m1) );
82*bf2c3715SXin Li     VERIFY( verify_eval_type<3>(m1+m1, m1) );
83*bf2c3715SXin Li     VERIFY( verify_eval_type<1>(m1*m1.transpose(), m2) );
84*bf2c3715SXin Li     VERIFY( verify_eval_type<1>(m1*(m1+m1).transpose(), m2) );
85*bf2c3715SXin Li     VERIFY( verify_eval_type<2>(m1*m1.transpose(), m2) );
86*bf2c3715SXin Li     VERIFY( verify_eval_type<1>(m1+m1*m1, m1) );
87*bf2c3715SXin Li 
88*bf2c3715SXin Li     VERIFY( verify_eval_type<1>(m1.template triangularView<Lower>().solve(m1), m1) );
89*bf2c3715SXin Li     VERIFY( verify_eval_type<1>(m1+m1.template triangularView<Lower>().solve(m1), m1) );
90*bf2c3715SXin Li   }
91*bf2c3715SXin Li }
92*bf2c3715SXin Li 
93*bf2c3715SXin Li 
EIGEN_DECLARE_TEST(nesting_ops)94*bf2c3715SXin Li EIGEN_DECLARE_TEST(nesting_ops)
95*bf2c3715SXin Li {
96*bf2c3715SXin Li   CALL_SUBTEST_1(run_nesting_ops_1(MatrixXf::Random(25,25)));
97*bf2c3715SXin Li   CALL_SUBTEST_2(run_nesting_ops_1(MatrixXcd::Random(25,25)));
98*bf2c3715SXin Li   CALL_SUBTEST_3(run_nesting_ops_1(Matrix4f::Random()));
99*bf2c3715SXin Li   CALL_SUBTEST_4(run_nesting_ops_1(Matrix2d::Random()));
100*bf2c3715SXin Li 
101*bf2c3715SXin Li   Index s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
102*bf2c3715SXin Li   CALL_SUBTEST_1( run_nesting_ops_2(MatrixXf(s,s)) );
103*bf2c3715SXin Li   CALL_SUBTEST_2( run_nesting_ops_2(MatrixXcd(s,s)) );
104*bf2c3715SXin Li   CALL_SUBTEST_3( run_nesting_ops_2(Matrix4f()) );
105*bf2c3715SXin Li   CALL_SUBTEST_4( run_nesting_ops_2(Matrix2d()) );
106*bf2c3715SXin Li   TEST_SET_BUT_UNUSED_VARIABLE(s)
107*bf2c3715SXin Li }
108