1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
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/.
9
10 #define EIGEN_NO_STATIC_ASSERT
11
12 #include "main.h"
13
14 #undef VERIFY_IS_APPROX
15 #define VERIFY_IS_APPROX(a, b) VERIFY((a)==(b));
16 #undef VERIFY_IS_NOT_APPROX
17 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY((a)!=(b));
18
signed_integer_type_tests(const MatrixType & m)19 template<typename MatrixType> void signed_integer_type_tests(const MatrixType& m)
20 {
21 typedef typename MatrixType::Scalar Scalar;
22
23 enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
24 VERIFY(is_signed == 1);
25
26 Index rows = m.rows();
27 Index cols = m.cols();
28
29 MatrixType m1(rows, cols),
30 m2 = MatrixType::Random(rows, cols),
31 mzero = MatrixType::Zero(rows, cols);
32
33 do {
34 m1 = MatrixType::Random(rows, cols);
35 } while(m1 == mzero || m1 == m2);
36
37 // check linear structure
38
39 Scalar s1;
40 do {
41 s1 = internal::random<Scalar>();
42 } while(s1 == 0);
43
44 VERIFY_IS_EQUAL(-(-m1), m1);
45 VERIFY_IS_EQUAL(-m2+m1+m2, m1);
46 VERIFY_IS_EQUAL((-m1+m2)*s1, -s1*m1+s1*m2);
47 }
48
integer_type_tests(const MatrixType & m)49 template<typename MatrixType> void integer_type_tests(const MatrixType& m)
50 {
51 typedef typename MatrixType::Scalar Scalar;
52
53 VERIFY(NumTraits<Scalar>::IsInteger);
54 enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
55 VERIFY(int(NumTraits<Scalar>::IsSigned) == is_signed);
56
57 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
58
59 Index rows = m.rows();
60 Index cols = m.cols();
61
62 // this test relies a lot on Random.h, and there's not much more that we can do
63 // to test it, hence I consider that we will have tested Random.h
64 MatrixType m1(rows, cols),
65 m2 = MatrixType::Random(rows, cols),
66 m3(rows, cols),
67 mzero = MatrixType::Zero(rows, cols);
68
69 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
70 SquareMatrixType identity = SquareMatrixType::Identity(rows, rows),
71 square = SquareMatrixType::Random(rows, rows);
72 VectorType v1(rows),
73 v2 = VectorType::Random(rows),
74 vzero = VectorType::Zero(rows);
75
76 do {
77 m1 = MatrixType::Random(rows, cols);
78 } while(m1 == mzero || m1 == m2);
79
80 do {
81 v1 = VectorType::Random(rows);
82 } while(v1 == vzero || v1 == v2);
83
84 VERIFY_IS_APPROX( v1, v1);
85 VERIFY_IS_NOT_APPROX( v1, 2*v1);
86 VERIFY_IS_APPROX( vzero, v1-v1);
87 VERIFY_IS_APPROX( m1, m1);
88 VERIFY_IS_NOT_APPROX( m1, 2*m1);
89 VERIFY_IS_APPROX( mzero, m1-m1);
90
91 VERIFY_IS_APPROX(m3 = m1,m1);
92 MatrixType m4;
93 VERIFY_IS_APPROX(m4 = m1,m1);
94
95 m3.real() = m1.real();
96 VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
97 VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());
98
99 // check == / != operators
100 VERIFY(m1==m1);
101 VERIFY(m1!=m2);
102 VERIFY(!(m1==m2));
103 VERIFY(!(m1!=m1));
104 m1 = m2;
105 VERIFY(m1==m2);
106 VERIFY(!(m1!=m2));
107
108 // check linear structure
109
110 Scalar s1;
111 do {
112 s1 = internal::random<Scalar>();
113 } while(s1 == 0);
114
115 VERIFY_IS_EQUAL(m1+m1, 2*m1);
116 VERIFY_IS_EQUAL(m1+m2-m1, m2);
117 VERIFY_IS_EQUAL(m1*s1, s1*m1);
118 VERIFY_IS_EQUAL((m1+m2)*s1, s1*m1+s1*m2);
119 m3 = m2; m3 += m1;
120 VERIFY_IS_EQUAL(m3, m1+m2);
121 m3 = m2; m3 -= m1;
122 VERIFY_IS_EQUAL(m3, m2-m1);
123 m3 = m2; m3 *= s1;
124 VERIFY_IS_EQUAL(m3, s1*m2);
125
126 // check matrix product.
127
128 VERIFY_IS_APPROX(identity * m1, m1);
129 VERIFY_IS_APPROX(square * (m1 + m2), square * m1 + square * m2);
130 VERIFY_IS_APPROX((m1 + m2).transpose() * square, m1.transpose() * square + m2.transpose() * square);
131 VERIFY_IS_APPROX((m1 * m2.transpose()) * m1, m1 * (m2.transpose() * m1));
132 }
133
134 template<int>
integer_types_extra()135 void integer_types_extra()
136 {
137 VERIFY_IS_EQUAL(int(internal::scalar_div_cost<int>::value), 8);
138 VERIFY_IS_EQUAL(int(internal::scalar_div_cost<unsigned int>::value), 8);
139 if(sizeof(long)>sizeof(int)) {
140 VERIFY(int(internal::scalar_div_cost<long>::value) > int(internal::scalar_div_cost<int>::value));
141 VERIFY(int(internal::scalar_div_cost<unsigned long>::value) > int(internal::scalar_div_cost<int>::value));
142 }
143 }
144
EIGEN_DECLARE_TEST(integer_types)145 EIGEN_DECLARE_TEST(integer_types)
146 {
147 for(int i = 0; i < g_repeat; i++) {
148 CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned int, 1, 1>()) );
149 CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned long, 3, 4>()) );
150
151 CALL_SUBTEST_2( integer_type_tests(Matrix<long, 2, 2>()) );
152 CALL_SUBTEST_2( signed_integer_type_tests(Matrix<long, 2, 2>()) );
153
154 CALL_SUBTEST_3( integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)) );
155 CALL_SUBTEST_3( signed_integer_type_tests(Matrix<signed char, 2, Dynamic>(2, 10)) );
156
157 CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, 3, 3>()) );
158 CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)) );
159
160 CALL_SUBTEST_5( integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
161 CALL_SUBTEST_5( signed_integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );
162
163 CALL_SUBTEST_6( integer_type_tests(Matrix<unsigned short, 4, 4>()) );
164
165 #if EIGEN_HAS_CXX11
166 CALL_SUBTEST_7( integer_type_tests(Matrix<long long, 11, 13>()) );
167 CALL_SUBTEST_7( signed_integer_type_tests(Matrix<long long, 11, 13>()) );
168
169 CALL_SUBTEST_8( integer_type_tests(Matrix<unsigned long long, Dynamic, 5>(1, 5)) );
170 #endif
171 }
172 CALL_SUBTEST_9( integer_types_extra<0>() );
173 }
174