nullary.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2010-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
5 // Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #include "main.h"
12 
13 template<typename MatrixType>
15 {
16  typedef typename MatrixType::Scalar Scalar;
17  Scalar zero = static_cast<Scalar>(0);
18 
19  bool offDiagOK = true;
20  for (Index i = 0; i < A.rows(); ++i) {
21  for (Index j = i+1; j < A.cols(); ++j) {
22  offDiagOK = offDiagOK && (A(i,j) == zero);
23  }
24  }
25  for (Index i = 0; i < A.rows(); ++i) {
26  for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {
27  offDiagOK = offDiagOK && (A(i,j) == zero);
28  }
29  }
30 
31  bool diagOK = (A.diagonal().array() == 1).all();
32  return offDiagOK && diagOK;
33 
34 }
35 
36 template<typename VectorType>
37 void check_extremity_accuracy(const VectorType &v, const typename VectorType::Scalar &low, const typename VectorType::Scalar &high)
38 {
39  typedef typename VectorType::Scalar Scalar;
40  typedef typename VectorType::RealScalar RealScalar;
41 
43  Index size = v.size();
44 
45  if(size<20)
46  return;
47 
48  for (int i=0; i<size; ++i)
49  {
50  if(i<5 || i>size-6)
51  {
52  Scalar ref = (low*RealScalar(size-i-1))/RealScalar(size-1) + (high*RealScalar(i))/RealScalar(size-1);
53  if(std::abs(ref)>1)
54  {
55  if(!internal::isApprox(v(i), ref, prec))
56  std::cout << v(i) << " != " << ref << " ; relative error: " << std::abs((v(i)-ref)/ref) << " ; required precision: " << prec << " ; range: " << low << "," << high << " ; i: " << i << "\n";
57  VERIFY(internal::isApprox(v(i), (low*RealScalar(size-i-1))/RealScalar(size-1) + (high*RealScalar(i))/RealScalar(size-1), prec));
58  }
59  }
60  }
61 }
62 
63 template<typename VectorType>
65 {
66  typedef typename VectorType::Scalar Scalar;
67  typedef typename VectorType::RealScalar RealScalar;
68 
69  const Index size = base.size();
70 
71  Scalar high = internal::random<Scalar>(-500,500);
72  Scalar low = (size == 1 ? high : internal::random<Scalar>(-500,500));
73  if (numext::real(low)>numext::real(high)) std::swap(low,high);
74 
75  // check low==high
76  if(internal::random<float>(0.f,1.f)<0.05f)
77  low = high;
78  // check abs(low) >> abs(high)
79  else if(size>2 && std::numeric_limits<RealScalar>::max_exponent10>0 && internal::random<float>(0.f,1.f)<0.1f)
80  low = -internal::random<Scalar>(1,2) * RealScalar(std::pow(RealScalar(10),std::numeric_limits<RealScalar>::max_exponent10/2));
81 
82  const Scalar step = ((size == 1) ? 1 : (high-low)/RealScalar(size-1));
83 
84  // check whether the result yields what we expect it to do
85  VectorType m(base);
86  m.setLinSpaced(size,low,high);
87 
89  {
90  VectorType n(size);
91  for (int i=0; i<size; ++i)
92  n(i) = low+RealScalar(i)*step;
93  VERIFY_IS_APPROX(m,n);
94 
95  CALL_SUBTEST( check_extremity_accuracy(m, low, high) );
96  }
97 
98  RealScalar range_length = numext::real(high-low);
99  if((!NumTraits<Scalar>::IsInteger) || (range_length>=size && (Index(range_length)%(size-1))==0) || (Index(range_length+1)<size && (size%Index(range_length+1))==0))
100  {
101  VectorType n(size);
102  if((!NumTraits<Scalar>::IsInteger) || (range_length>=size))
103  for (int i=0; i<size; ++i)
104  n(i) = size==1 ? low : (low + ((high-low)*Scalar(i))/RealScalar(size-1));
105  else
106  for (int i=0; i<size; ++i)
107  n(i) = size==1 ? low : low + Scalar((double(range_length+1)*double(i))/double(size));
108  VERIFY_IS_APPROX(m,n);
109 
110  // random access version
111  m = VectorType::LinSpaced(size,low,high);
112  VERIFY_IS_APPROX(m,n);
113  VERIFY( internal::isApprox(m(m.size()-1),high) );
114  VERIFY( size==1 || internal::isApprox(m(0),low) );
115  VERIFY_IS_EQUAL(m(m.size()-1) , high);
117  CALL_SUBTEST( check_extremity_accuracy(m, low, high) );
118  }
119 
120  VERIFY( numext::real(m(m.size()-1)) <= numext::real(high) );
121  VERIFY( (m.array().real() <= numext::real(high)).all() );
122  VERIFY( (m.array().real() >= numext::real(low)).all() );
123 
124 
125  VERIFY( numext::real(m(m.size()-1)) >= numext::real(low) );
126  if(size>=1)
127  {
128  VERIFY( internal::isApprox(m(0),low) );
129  VERIFY_IS_EQUAL(m(0) , low);
130  }
131 
132  // check whether everything works with row and col major vectors
133  Matrix<Scalar,Dynamic,1> row_vector(size);
134  Matrix<Scalar,1,Dynamic> col_vector(size);
135  row_vector.setLinSpaced(size,low,high);
136  col_vector.setLinSpaced(size,low,high);
137  // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit
138  // when computing the squared sum in isApprox, thus the 2x factor.
139  VERIFY( row_vector.isApprox(col_vector.transpose(), RealScalar(2)*NumTraits<Scalar>::epsilon()));
140 
141  Matrix<Scalar,Dynamic,1> size_changer(size+50);
142  size_changer.setLinSpaced(size,low,high);
143  VERIFY( size_changer.size() == size );
144 
145  typedef Matrix<Scalar,1,1> ScalarMatrix;
146  ScalarMatrix scalar;
147  scalar.setLinSpaced(1,low,high);
148  VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );
149  VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );
150 
151  // regression test for bug 526 (linear vectorized transversal)
152  if (size > 1 && (!NumTraits<Scalar>::IsInteger)) {
153  m.tail(size-1).setLinSpaced(low, high);
154  VERIFY_IS_APPROX(m(size-1), high);
155  }
156 
157  // regression test for bug 1383 (LinSpaced with empty size/range)
158  {
159  Index n0 = VectorType::SizeAtCompileTime==Dynamic ? 0 : VectorType::SizeAtCompileTime;
160  low = internal::random<Scalar>();
161  m = VectorType::LinSpaced(n0,low,low-RealScalar(1));
162  VERIFY(m.size()==n0);
163 
164  if(VectorType::SizeAtCompileTime==Dynamic)
165  {
166  VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,0,Scalar(n0-1)).sum(),Scalar(0));
167  VERIFY_IS_EQUAL(VectorType::LinSpaced(n0,low,low-RealScalar(1)).sum(),Scalar(0));
168  }
169 
170  m.setLinSpaced(n0,0,Scalar(n0-1));
171  VERIFY(m.size()==n0);
172  m.setLinSpaced(n0,low,low-RealScalar(1));
173  VERIFY(m.size()==n0);
174 
175  // empty range only:
176  VERIFY_IS_APPROX(VectorType::LinSpaced(size,low,low),VectorType::Constant(size,low));
177  m.setLinSpaced(size,low,low);
178  VERIFY_IS_APPROX(m,VectorType::Constant(size,low));
179 
181  {
182  VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,low+Scalar(size-1)), VectorType::LinSpaced(size,low+Scalar(size-1),low).reverse() );
183 
184  if(VectorType::SizeAtCompileTime==Dynamic)
185  {
186  // Check negative multiplicator path:
187  for(Index k=1; k<5; ++k)
188  VERIFY_IS_APPROX( VectorType::LinSpaced(size,low,low+Scalar((size-1)*k)), VectorType::LinSpaced(size,low+Scalar((size-1)*k),low).reverse() );
189  // Check negative divisor path:
190  for(Index k=1; k<5; ++k)
191  VERIFY_IS_APPROX( VectorType::LinSpaced(size*k,low,low+Scalar(size-1)), VectorType::LinSpaced(size*k,low+Scalar(size-1),low).reverse() );
192  }
193  }
194  }
195 
196  // test setUnit()
197  if(m.size()>0)
198  {
199  for(Index k=0; k<10; ++k)
200  {
201  Index i = internal::random<Index>(0,m.size()-1);
202  m.setUnit(i);
203  VERIFY_IS_APPROX( m, VectorType::Unit(m.size(), i) );
204  }
205  if(VectorType::SizeAtCompileTime==Dynamic)
206  {
207  Index i = internal::random<Index>(0,2*m.size()-1);
208  m.setUnit(2*m.size(),i);
209  VERIFY_IS_APPROX( m, VectorType::Unit(m.size(),i) );
210  }
211  }
212 
213 }
214 
215 template<typename MatrixType>
217 {
218  using std::abs;
219  const Index rows = m.rows();
220  const Index cols = m.cols();
221  typedef typename MatrixType::Scalar Scalar;
222  typedef typename MatrixType::RealScalar RealScalar;
223 
224  Scalar s1;
225  do {
226  s1 = internal::random<Scalar>();
227  } while(abs(s1)<RealScalar(1e-5) && (!NumTraits<Scalar>::IsInteger));
228 
229  MatrixType A;
230  A.setIdentity(rows, cols);
232  VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
233 
234 
235  A = MatrixType::Constant(rows,cols,s1);
236  Index i = internal::random<Index>(0,rows-1);
237  Index j = internal::random<Index>(0,cols-1);
238  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1)(i,j), s1 );
239  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1).coeff(i,j), s1 );
240  VERIFY_IS_APPROX( A(i,j), s1 );
241 }
242 
243 template<int>
244 void bug79()
245 {
246  // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
247  VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<double>::epsilon() );
248 }
249 
250 template<int>
251 void bug1630()
252 {
253  Array4d x4 = Array4d::LinSpaced(0.0, 1.0);
254  Array3d x3(Array4d::LinSpaced(0.0, 1.0).head(3));
255  VERIFY_IS_APPROX(x4.head(3), x3);
256 }
257 
258 template<int>
260 {
261  // Check possible overflow issue
262  int n = 60000;
263  ArrayXi a1(n), a2(n);
264  a1.setLinSpaced(n, 0, n-1);
265  for(int i=0; i<n; ++i)
266  a2(i) = i;
267  VERIFY_IS_APPROX(a1,a2);
268 }
269 
270 template<int>
272 {
273  // check some internal logic
274  VERIFY(( internal::has_nullary_operator<internal::scalar_constant_op<double> >::value ));
275  VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<double> >::value ));
276  VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<double> >::value ));
277  VERIFY(( internal::functor_has_linear_access<internal::scalar_constant_op<double> >::ret ));
278 
279  VERIFY(( !internal::has_nullary_operator<internal::scalar_identity_op<double> >::value ));
280  VERIFY(( !internal::has_unary_operator<internal::scalar_identity_op<double> >::value ));
281  VERIFY(( internal::has_binary_operator<internal::scalar_identity_op<double> >::value ));
282  VERIFY(( !internal::functor_has_linear_access<internal::scalar_identity_op<double> >::ret ));
283 
284  VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<float> >::value ));
285  VERIFY(( internal::has_unary_operator<internal::linspaced_op<float> >::value ));
286  VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float> >::value ));
287  VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<float> >::ret ));
288 
289  // Regression unit test for a weird MSVC bug.
290  // Search "nullary_wrapper_workaround_msvc" in CoreEvaluators.h for the details.
291  // See also traits<Ref>::match.
292  {
293  MatrixXf A = MatrixXf::Random(3,3);
294  Ref<const MatrixXf> R = 2.0*A;
295  VERIFY_IS_APPROX(R, A+A);
296 
297  Ref<const MatrixXf> R1 = MatrixXf::Random(3,3)+A;
298 
299  VectorXi V = VectorXi::Random(3);
300  Ref<const VectorXi> R2 = VectorXi::LinSpaced(3,1,3)+V;
301  VERIFY_IS_APPROX(R2, V+Vector3i(1,2,3));
302 
303  VERIFY(( internal::has_nullary_operator<internal::scalar_constant_op<float> >::value ));
304  VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<float> >::value ));
305  VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<float> >::value ));
306  VERIFY(( internal::functor_has_linear_access<internal::scalar_constant_op<float> >::ret ));
307 
308  VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<int> >::value ));
309  VERIFY(( internal::has_unary_operator<internal::linspaced_op<int> >::value ));
310  VERIFY(( !internal::has_binary_operator<internal::linspaced_op<int> >::value ));
311  VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<int> >::ret ));
312  }
313 }
314 
316 {
317  CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
318  CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
319  CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
320 
321  for(int i = 0; i < g_repeat*10; i++) {
322  CALL_SUBTEST_3( testVectorType(VectorXcd(internal::random<int>(1,30000))) );
323  CALL_SUBTEST_4( testVectorType(VectorXd(internal::random<int>(1,30000))) );
324  CALL_SUBTEST_5( testVectorType(Vector4d()) ); // regression test for bug 232
325  CALL_SUBTEST_6( testVectorType(Vector3d()) );
326  CALL_SUBTEST_7( testVectorType(VectorXf(internal::random<int>(1,30000))) );
327  CALL_SUBTEST_8( testVectorType(Vector3f()) );
328  CALL_SUBTEST_8( testVectorType(Vector4f()) );
331 
332  CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,10))) );
333  CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(9,300))) );
335  }
336 
337  CALL_SUBTEST_6( bug79<0>() );
338  CALL_SUBTEST_6( bug1630<0>() );
339  CALL_SUBTEST_9( nullary_overflow<0>() );
340  CALL_SUBTEST_10( nullary_internal_logic<0>() );
341 }
Point2 a1
Definition: testPose2.cpp:769
Matrix3f m
def step(data, isam, result, truth, currPoseIndex)
Definition: visual_isam.py:82
void bug79()
Definition: nullary.cpp:244
SCALAR Scalar
Definition: bench_gemm.cpp:46
#define CALL_SUBTEST_9(FUNC)
#define CALL_SUBTEST_6(FUNC)
#define CALL_SUBTEST_4(FUNC)
float real
Definition: datatypes.h:10
static const Eigen::internal::all_t all
#define min(a, b)
Definition: datatypes.h:19
#define CALL_SUBTEST_3(FUNC)
EIGEN_DONT_INLINE Scalar zero()
Definition: svd_common.h:296
#define CALL_SUBTEST_7(FUNC)
int n
Rot2 R(Rot2::fromAngle(0.1))
MatrixXf MatrixType
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
void bug1630()
Definition: nullary.cpp:251
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:48
void check_extremity_accuracy(const VectorType &v, const typename VectorType::Scalar &low, const typename VectorType::Scalar &high)
Definition: nullary.cpp:37
static double epsilon
Definition: testRot3.cpp:37
#define CALL_SUBTEST_10(FUNC)
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
#define VERIFY_IS_APPROX(a, b)
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:386
bool equalsIdentity(const MatrixType &A)
Definition: nullary.cpp:14
#define CALL_SUBTEST_1(FUNC)
static int g_repeat
Definition: main.h:169
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
void testMatrixType(const MatrixType &m)
Definition: nullary.cpp:216
Array< int, Dynamic, 1 > v
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define CALL_SUBTEST_8(FUNC)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EIGEN_DECLARE_TEST(nullary)
Definition: nullary.cpp:315
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:47
Reference counting helper.
Definition: object.h:67
Pose3 x3(Rot3::Ypr(M_PI/4.0, 0.0, 0.0), l2)
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
DenseIndex ret
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:281
Point2 a2
Definition: testPose2.cpp:770
#define CALL_SUBTEST_5(FUNC)
#define CALL_SUBTEST(FUNC)
Definition: main.h:399
#define VERIFY(a)
Definition: main.h:380
void reverse(const MatrixType &m)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE FixedSegmentReturnType< internal::get_fixed_value< NType >::value >::Type head(NType n)
void nullary_overflow()
Definition: nullary.cpp:259
#define CALL_SUBTEST_2(FUNC)
void nullary_internal_logic()
Definition: nullary.cpp:271
Annotation indicating that a class derives from another given type.
Definition: attr.h:61
const int Dynamic
Definition: Constants.h:22
Jet< T, N > pow(const Jet< T, N > &f, double g)
Definition: jet.h:570
static string x4("x4")
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
#define abs(x)
Definition: datatypes.h:17
mxArray * scalar(mxClassID classid)
Definition: matlab.h:82
std::ptrdiff_t j
void testVectorType(const VectorType &base)
Definition: nullary.cpp:64


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:58