Simbody  3.6
Testing.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_TESTING_H_
2 #define SimTK_SimTKCOMMON_TESTING_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2009-15 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 #include "SimTKcommon/basics.h"
28 #include "SimTKcommon/Simmatrix.h"
31 
32 #include <cmath>
33 #include <algorithm>
34 #include <iostream>
35 
41 namespace SimTK {
42 
159 class Test {
164 public:
165  class Subtest;
166  Test(const std::string& name)
167  : startCpuTime(SimTK::cpuTime()),
168  startRealTime(SimTK::realTime()),
169  testName(name)
170  {
171  std::clog << "Starting test " << testName << " ...\n";
172  }
173  ~Test() {
174  const double finalRealTime=SimTK::realTime();
175  const double finalCpuTime=SimTK::cpuTime();
176  std::ostringstream fmt;
177  fmt << std::fixed << std::setprecision(1);
178  fmt << "\n" << testName << " done."
179  << " real/CPU ms: " << (finalRealTime-startRealTime)*1000
180  << " / " << (finalCpuTime-startCpuTime)*1000 <<std::endl;
181  std::clog << fmt.str();
182  }
183 
184  template <class T>
185  static double defTol() {return (double)NTraits<typename CNT<T>::Precision>::getSignificant();}
186 
187  // For dissimilar types, the default tolerance is the narrowest of the two.
188  template <class T1, class T2>
189  static double defTol2() {return std::max(defTol<T1>(), defTol<T2>());}
190 
191  // Scale by the magnitude of the quantities being compared, so that we don't
192  // ask for unreasonable precision. For magnitudes near zero, we'll be satisfied
193  // if both are very small without demanding that they must also be relatively
194  // close. That is, we use a relative tolerance for big numbers and an absolute
195  // tolerance for small ones.
196  static bool numericallyEqual(float v1, float v2, int n, double tol=defTol<float>()) {
197  const float scale = n*std::max(std::max(std::abs(v1), std::abs(v2)), 1.0f);
198  return std::abs(v1-v2) < scale*(float)tol;
199  }
200  static bool numericallyEqual(double v1, double v2, int n, double tol=defTol<double>()) {
201  const double scale = n*std::max(std::max(std::abs(v1), std::abs(v2)), 1.0);
202  return std::abs(v1-v2) < scale*(double)tol;
203  }
204  static bool numericallyEqual(long double v1, long double v2, int n, double tol=defTol<long double>()) {
205  const long double scale = n*std::max(std::max(std::abs(v1), std::abs(v2)), 1.0l);
206  return std::abs(v1-v2) < scale*(long double)tol;
207  }
208 
209  // For integers we ignore tolerance.
210  static bool numericallyEqual(int i1, int i2, int n, double tol=0) {return i1==i2;}
211  static bool numericallyEqual(unsigned u1, unsigned u2, int n, double tol=0) {return u1==u2;}
212 
213  // Mixed floating types use default tolerance for the narrower type.
214  static bool numericallyEqual(float v1, double v2, int n, double tol=defTol<float>())
215  { return numericallyEqual((double)v1, v2, n, tol); }
216  static bool numericallyEqual(double v1, float v2, int n, double tol=defTol<float>())
217  { return numericallyEqual(v1, (double)v2, n, tol); }
218  static bool numericallyEqual(float v1, long double v2, int n, double tol=defTol<float>())
219  { return numericallyEqual((long double)v1, v2, n, tol); }
220  static bool numericallyEqual(long double v1, float v2, int n, double tol=defTol<float>())
221  { return numericallyEqual(v1, (long double)v2, n, tol); }
222  static bool numericallyEqual(double v1, long double v2, int n, double tol=defTol<double>())
223  { return numericallyEqual((long double)v1, v2, n, tol); }
224  static bool numericallyEqual(long double v1, double v2, int n, double tol=defTol<double>())
225  { return numericallyEqual(v1, (long double)v2, n, tol); }
226 
227  // Mixed int/floating just upgrades int to floating type.
228  static bool numericallyEqual(int i1, float f2, int n, double tol=defTol<float>())
229  { return numericallyEqual((float)i1,f2,n,tol); }
230  static bool numericallyEqual(float f1, int i2, int n, double tol=defTol<float>())
231  { return numericallyEqual(f1,(float)i2,n,tol); }
232  static bool numericallyEqual(unsigned i1, float f2, int n, double tol=defTol<float>())
233  { return numericallyEqual((float)i1,f2,n,tol); }
234  static bool numericallyEqual(float f1, unsigned i2, int n, double tol=defTol<float>())
235  { return numericallyEqual(f1,(float)i2,n,tol); }
236  static bool numericallyEqual(int i1, double f2, int n, double tol=defTol<double>())
237  { return numericallyEqual((double)i1,f2,n,tol); }
238  static bool numericallyEqual(double f1, int i2, int n, double tol=defTol<double>())
239  { return numericallyEqual(f1,(double)i2,n,tol); }
240  static bool numericallyEqual(unsigned i1, double f2, int n, double tol=defTol<double>())
241  { return numericallyEqual((double)i1,f2,n,tol); }
242  static bool numericallyEqual(double f1, unsigned i2, int n, double tol=defTol<double>())
243  { return numericallyEqual(f1,(double)i2,n,tol); }
244  static bool numericallyEqual(int i1, long double f2, int n, double tol=defTol<long double>())
245  { return numericallyEqual((long double)i1,f2,n,tol); }
246  static bool numericallyEqual(long double f1, int i2, int n, double tol=defTol<long double>())
247  { return numericallyEqual(f1,(long double)i2,n,tol); }
248  static bool numericallyEqual(unsigned i1, long double f2, int n, double tol=defTol<long double>())
249  { return numericallyEqual((long double)i1,f2,n,tol); }
250  static bool numericallyEqual(long double f1, unsigned i2, int n, double tol=defTol<long double>())
251  { return numericallyEqual(f1,(long double)i2,n,tol); }
252 
253  template <class P>
254  static bool numericallyEqual(const std::complex<P>& v1, const std::complex<P>& v2, int n, double tol=defTol<P>()) {
255  return numericallyEqual(v1.real(), v2.real(), n, tol)
256  && numericallyEqual(v1.imag(), v2.imag(), n, tol);
257  }
258  template <class P>
259  static bool numericallyEqual(const conjugate<P>& v1, const conjugate<P>& v2, int n, double tol=defTol<P>()) {
260  return numericallyEqual(v1.real(), v2.real(), n, tol)
261  && numericallyEqual(v1.imag(), v2.imag(), n, tol);
262  }
263  template <class P>
264  static bool numericallyEqual(const std::complex<P>& v1, const conjugate<P>& v2, int n, double tol=defTol<P>()) {
265  return numericallyEqual(v1.real(), v2.real(), n, tol)
266  && numericallyEqual(v1.imag(), v2.imag(), n, tol);
267  }
268  template <class P>
269  static bool numericallyEqual(const conjugate<P>& v1, const std::complex<P>& v2, int n, double tol=defTol<P>()) {
270  return numericallyEqual(v1.real(), v2.real(), n, tol)
271  && numericallyEqual(v1.imag(), v2.imag(), n, tol);
272  }
273  template <class P>
274  static bool numericallyEqual(const negator<P>& v1, const negator<P>& v2, int n, double tol=defTol<P>()) {
275  return numericallyEqual(-v1, -v2, n, tol); // P, P
276  }
277  template <class P>
278  static bool numericallyEqual(const P& v1, const negator<P>& v2, int n, double tol=defTol<P>()) {
279  return numericallyEqual(-v1, -v2, n, tol); // P, P
280  }
281  template <class P>
282  static bool numericallyEqual(const negator<P>& v1, const P& v2, int n, double tol=defTol<P>()) {
283  return numericallyEqual(-v1, -v2, n, tol); // P, P
284  }
285  template <class P>
286  static bool numericallyEqual(const negator<std::complex<P> >& v1, const conjugate<P>& v2, int n, double tol=defTol<P>()) {
287  return numericallyEqual(-v1, -v2, n, tol); // complex, conjugate
288  }
289  template <class P>
290  static bool numericallyEqual(const negator<conjugate<P> >& v1, const std::complex<P>& v2, int n, double tol=defTol<P>()) {
291  return numericallyEqual(-v1, -v2, n, tol); // conjugate, complex
292  }
293  template <class P>
294  static bool numericallyEqual(const std::complex<P>& v1, const negator<conjugate<P> >& v2, int n, double tol=defTol<P>()) {
295  return numericallyEqual(-v1, -v2, n, tol); // complex, conjugate
296  }
297  template <class P>
298  static bool numericallyEqual(const conjugate<P>& v1, const negator<std::complex<P> >& v2, int n, double tol=defTol<P>()) {
299  return numericallyEqual(-v1, -v2, n, tol); // conjugate, complex
300  }
301  template <int M, class E1, int S1, class E2, int S2>
302  static bool numericallyEqual(const Vec<M,E1,S1>& v1, const Vec<M,E2,S2>& v2, int n, double tol=(defTol2<E1,E2>())) {
303  for (int i=0; i<M; ++i) if (!numericallyEqual(v1[i],v2[i], n, tol)) return false;
304  return true;
305  }
306  template <int N, class E1, int S1, class E2, int S2>
307  static bool numericallyEqual(const Row<N,E1,S1>& v1, const Row<N,E2,S2>& v2, int n, double tol=(defTol2<E1,E2>())) {
308  for (int j=0; j<N; ++j) if (!numericallyEqual(v1[j],v2[j], n, tol)) return false;
309  return true;
310  }
311  template <int M, int N, class E1, int CS1, int RS1, class E2, int CS2, int RS2>
312  static bool numericallyEqual(const Mat<M,N,E1,CS1,RS1>& v1, const Mat<M,N,E2,CS2,RS2>& v2, int n, double tol=(defTol2<E1,E2>())) {
313  for (int j=0; j<N; ++j) if (!numericallyEqual(v1(j),v2(j), n, tol)) return false;
314  return true;
315  }
316  template <int N, class E1, int S1, class E2, int S2>
317  static bool numericallyEqual(const SymMat<N,E1,S1>& v1, const SymMat<N,E2,S2>& v2, int n, double tol=(defTol2<E1,E2>())) {
318  return numericallyEqual(v1.getAsVec(), v2.getAsVec(), n, tol);
319  }
320  template <class E1, class E2>
321  static bool numericallyEqual(const VectorView_<E1>& v1, const VectorView_<E2>& v2, int n, double tol=(defTol2<E1,E2>())) {
322  if (v1.size() != v2.size()) return false;
323  for (int i=0; i < v1.size(); ++i)
324  if (!numericallyEqual(v1[i], v2[i], n, tol)) return false;
325  return true;
326  }
327  template <class E1, class E2>
328  static bool numericallyEqual(const Vector_<E1>& v1, const Vector_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
329  { return numericallyEqual((const VectorView_<E1>&)v1, (const VectorView_<E2>&)v2, n, tol); }
330  template <class E1, class E2>
331  static bool numericallyEqual(const Vector_<E1>& v1, const VectorView_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
332  { return numericallyEqual((const VectorView_<E1>&)v1, (const VectorView_<E2>&)v2, n, tol); }
333  template <class E1, class E2>
334  static bool numericallyEqual(const VectorView_<E1>& v1, const Vector_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
335  { return numericallyEqual((const VectorView_<E1>&)v1, (const VectorView_<E2>&)v2, n, tol); }
336 
337  template <class E1, class E2>
338  static bool numericallyEqual(const RowVectorView_<E1>& v1, const RowVectorView_<E2>& v2, int n, double tol=(defTol2<E1,E2>())) {
339  if (v1.size() != v2.size()) return false;
340  for (int i=0; i < v1.size(); ++i)
341  if (!numericallyEqual(v1[i], v2[i], n, tol)) return false;
342  return true;
343  }
344  template <class E1, class E2>
345  static bool numericallyEqual(const RowVector_<E1>& v1, const RowVector_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
346  { return numericallyEqual((const RowVectorView_<E1>&)v1, (const RowVectorView_<E2>&)v2, n, tol); }
347  template <class E1, class E2>
348  static bool numericallyEqual(const RowVector_<E1>& v1, const RowVectorView_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
349  { return numericallyEqual((const RowVectorView_<E1>&)v1, (const RowVectorView_<E2>&)v2, n, tol); }
350  template <class E1, class E2>
351  static bool numericallyEqual(const RowVectorView_<E1>& v1, const RowVector_<E2>& v2, int n, double tol=(defTol2<E1,E2>()))
352  { return numericallyEqual((const RowVectorView_<E1>&)v1, (const RowVectorView_<E2>&)v2, n, tol); }
353 
354  template <class E1, class E2>
355  static bool numericallyEqual(const MatrixView_<E1>& v1, const MatrixView_<E2>& v2, int n, double tol=(defTol2<E1,E2>())) {
356  if (v1.nrow() != v2.nrow() || v1.ncol() != v2.ncol()) return false;
357  for (int j=0; j < v1.ncol(); ++j)
358  if (!numericallyEqual(v1(j), v2(j), n, tol)) return false;
359  return true;
360  }
361  template <class E1, class E2>
362  static bool numericallyEqual(const Matrix_<E1>& m1, const Matrix_<E2>& m2, int n, double tol=(defTol2<E1,E2>()))
363  { return numericallyEqual((const MatrixView_<E1>&)m1, (const MatrixView_<E2>&)m2, n, tol); }
364  template <class E1, class E2>
365  static bool numericallyEqual(const Matrix_<E1>& m1, const MatrixView_<E2>& m2, int n, double tol=(defTol2<E1,E2>()))
366  { return numericallyEqual((const MatrixView_<E1>&)m1, (const MatrixView_<E2>&)m2, n, tol); }
367  template <class E1, class E2>
368  static bool numericallyEqual(const MatrixView_<E1>& m1, const Matrix_<E2>& m2, int n, double tol=(defTol2<E1,E2>()))
369  { return numericallyEqual((const MatrixView_<E1>&)m1, (const MatrixView_<E2>&)m2, n, tol); }
370 
371  template <class P>
372  static bool numericallyEqual(const Rotation_<P>& R1, const Rotation_<P>& R2, int n, double tol=defTol<P>()) {
373  return R1.isSameRotationToWithinAngle(R2, (Real)(n*tol));
374  }
375 
376  template <class P>
377  static bool numericallyEqual(const Transform_<P>& T1, const Transform_<P>& T2, int n, double tol=defTol<P>()) {
378  return numericallyEqual(T1.R(), T2.R(), n, tol)
379  && numericallyEqual(T1.p(), T2.p(), n, tol);
380  }
381 
382  template <class P>
383  static bool numericallyEqual(const UnitInertia_<P>& G1, const UnitInertia_<P>& G2, int n, double tol=defTol<P>()) {
384  return numericallyEqual(G1.asSymMat33(),G2.asSymMat33(), n, tol);
385  }
386 
387  template <class P>
388  static bool numericallyEqual(const Inertia_<P>& I1, const Inertia_<P>& I2, int n, double tol=defTol<P>()) {
389  return numericallyEqual(I1.asSymMat33(),I2.asSymMat33(), n, tol);
390  }
391 
392  // Random numbers
393  static Real randReal() {
394  static Random::Uniform rand(-1,1);
395  return rand.getValue();
396  }
397  static Complex randComplex() {return Complex(randReal(),randReal());}
399  static float randFloat() {return (float)randReal();}
400  static double randDouble() {return (double)randReal();}
401 
402  template <int M> static Vec<M> randVec()
403  { Vec<M> v; for (int i=0; i<M; ++i) v[i]=randReal(); return v;}
404  template <int N> static Row<N> randRow() {return ~randVec<N>();}
405  template <int M, int N> static Mat<M,N> randMat()
406  { Mat<M,N> m; for (int j=0; j<N; ++j) m(j)=randVec<M>(); return m;}
407  template <int N> static SymMat<N> randSymMat()
408  { SymMat<N> s; s.updAsVec() = randVec<N*(N+1)/2>(); return s; }
409 
410  static Vector randVector(int m)
411  { Vector v(m); for (int i=0; i<m; ++i) v[i]=randReal(); return v;}
412  static Matrix randMatrix(int m, int n)
413  { Matrix M(m,n); for (int j=0; j<n; ++j) M(j)=randVector(m); return M;}
414 
415  static Vec3 randVec3() {return randVec<3>();}
416  static Mat33 randMat33() {return randMat<3,3>();}
417  static SymMat33 randSymMat33() {return randSymMat<3>();}
419  return SpatialVec(randVec3(), randVec3());
420  }
422  return SpatialMat(randMat33(), randMat33(),
423  randMat33(), randMat33());
424  }
426  // Generate random angle and random axis to rotate around.
427  return Rotation((Pi/2)*randReal(), randVec3());
428  }
430  return Transform(randRotation(), randVec3());
431  }
432 private:
433  const double startCpuTime;
434  const double startRealTime;
435  std::string testName;
436 };
437 
440 public:
441  Subtest(const std::string& name)
442  : startCpuTime(SimTK::cpuTime()),
443  startRealTime(SimTK::realTime()),
444  subtestName(name)
445  {
446  std::clog << " " << subtestName << " ...\n" << std::flush;
447  }
449  const double finalRealTime=SimTK::realTime();
450  const double finalCpuTime=SimTK::cpuTime();
451  std::ostringstream fmt;
452  fmt << std::fixed << std::setprecision(1);
453  fmt << " " << subtestName << " done."
454  << " real/CPU ms: " << (finalRealTime-startRealTime)*1000
455  << " / " << (finalCpuTime-startCpuTime)*1000 <<std::endl;
456  std::clog << fmt.str();
457  }
458 private:
459  const double startCpuTime;
460  const double startRealTime;
461  std::string subtestName;
462 };
463 
464 } // namespace SimTK
465 
467 #define SimTK_START_TEST(testName) \
468  SimTK::Test simtk_test_(testName); \
469  try {
470 
472 #define SimTK_END_TEST() \
473  } catch(const std::exception& e) { \
474  std::cerr << "Test failed due to exception: " \
475  << e.what() << std::endl; \
476  return 1; \
477  } catch(...) { \
478  std::cerr << "Test failed due to unrecognized exception.\n"; \
479  return 1; \
480  } \
481  return 0;
482 
485 #define SimTK_SUBTEST(testFunction) \
486  do {SimTK::Test::Subtest sub(#testFunction); (testFunction)();} while(false)
487 #define SimTK_SUBTEST1(testFunction,arg1) \
490  do {SimTK::Test::Subtest sub(#testFunction); (testFunction)(arg1);} while(false)
491 #define SimTK_SUBTEST2(testFunction,arg1,arg2) \
494  do {SimTK::Test::Subtest sub(#testFunction); (testFunction)(arg1,arg2);} while(false)
495 #define SimTK_SUBTEST3(testFunction,arg1,arg2,arg3) \
498  do {SimTK::Test::Subtest sub(#testFunction); (testFunction)(arg1,arg2,arg3);} while(false)
499 #define SimTK_SUBTEST4(testFunction,arg1,arg2,arg3,arg4) \
502  do {SimTK::Test::Subtest sub(#testFunction); (testFunction)(arg1,arg2,arg3,arg4);} while(false)
503 
505 #define SimTK_TEST(cond) {SimTK_ASSERT_ALWAYS((cond), "Test condition failed.");}
506 
509 #define SimTK_TEST_FAILED(msg) {SimTK_ASSERT_ALWAYS(!"Test case failed.", msg);}
510 
514 #define SimTK_TEST_FAILED1(fmt,a1) {SimTK_ASSERT1_ALWAYS(!"Test case failed.",fmt,a1);}
515 
519 #define SimTK_TEST_FAILED2(fmt,a1,a2) {SimTK_ASSERT2_ALWAYS(!"Test case failed.",fmt,a1,a2);}
520 
524 #define SimTK_TEST_EQ(v1,v2) \
525  {SimTK_ASSERT_ALWAYS(SimTK::Test::numericallyEqual((v1),(v2),1), \
526  "Test values should have been numerically equivalent at default tolerance.");}
527 
530 #define SimTK_TEST_EQ_SIZE(v1,v2,n) \
531  {SimTK_ASSERT1_ALWAYS(SimTK::Test::numericallyEqual((v1),(v2),(n)), \
532  "Test values should have been numerically equivalent at size=%d times default tolerance.",(n));}
533 
537 #define SimTK_TEST_EQ_TOL(v1,v2,tol) \
538  {SimTK_ASSERT1_ALWAYS(SimTK::Test::numericallyEqual((v1),(v2),1,(tol)), \
539  "Test values should have been numerically equivalent at tolerance=%g.",(tol));}
540 
544 #define SimTK_TEST_NOTEQ(v1,v2) \
545  {SimTK_ASSERT_ALWAYS(!SimTK::Test::numericallyEqual((v1),(v2),1), \
546  "Test values should NOT have been numerically equivalent (at default tolerance).");}
547 
551 #define SimTK_TEST_NOTEQ_SIZE(v1,v2,n) \
552  {SimTK_ASSERT1_ALWAYS(!SimTK::Test::numericallyEqual((v1),(v2),(n)), \
553  "Test values should NOT have been numerically equivalent at size=%d times default tolerance.",(n));}
554 
558 #define SimTK_TEST_NOTEQ_TOL(v1,v2,tol) \
559  {SimTK_ASSERT1_ALWAYS(!SimTK::Test::numericallyEqual((v1),(v2),1,(tol)), \
560  "Test values should NOT have been numerically equivalent at tolerance=%g.",(tol));}
561 
562 #ifndef SimTK_TEST_SUPPRESS_EXPECTED_THROW
563 
565 #define SimTK_TEST_MUST_THROW(stmt) \
566  do {int threw=0; try {stmt;} \
567  catch(const std::exception&){threw=1;} \
568  catch(...){threw=2;} \
569  if (threw==0) SimTK_TEST_FAILED1("Expected statement\n----\n%s\n----\n to throw an exception but it did not.",#stmt); \
570  if (threw==2) SimTK_TEST_FAILED1("Expected statement\n%s\n to throw an std::exception but it threw something else.",#stmt); \
571  }while(false)
572 
575 #define SimTK_TEST_MUST_THROW_SHOW(stmt) \
576  do {int threw=0; try {stmt;} \
577  catch(const std::exception& e) {threw=1; \
578  std::cout << "(OK) Threw: " << e.what() << std::endl;} \
579  catch(...){threw=2;} \
580  if (threw==0) SimTK_TEST_FAILED1("Expected statement\n----\n%s\n----\n to throw an exception but it did not.",#stmt); \
581  if (threw==2) SimTK_TEST_FAILED1("Expected statement\n%s\n to throw an std::exception but it threw something else.",#stmt); \
582  }while(false)
583 
585 #define SimTK_TEST_MUST_THROW_EXC(stmt,exc) \
586  do {int threw=0; try {stmt;} \
587  catch(const exc&){threw=1;} \
588  catch(...){threw=2;} \
589  if (threw==0) SimTK_TEST_FAILED1("Expected statement\n----\n%s\n----\n to throw an exception but it did not.",#stmt); \
590  if (threw==2) SimTK_TEST_FAILED2("Expected statement\n----\n%s\n----\n to throw exception type %s but it threw something else.",#stmt,#exc); \
591  }while(false)
592 
594 #define SimTK_TEST_MAY_THROW(stmt) \
595  do {int threw=0; try {stmt;} \
596  catch(const std::exception&){threw=1;} \
597  catch(...){threw=2;} \
598  if (threw==2) SimTK_TEST_FAILED1("Expected statement\n%s\n to throw an std::exception but it threw something else.",#stmt); \
599  }while(false)
600 
602 #define SimTK_TEST_MAY_THROW_EXC(stmt,exc) \
603  do {int threw=0; try {stmt;} \
604  catch(const exc&){threw=1;} \
605  catch(...){threw=2;} \
606  if (threw==2) SimTK_TEST_FAILED2("Expected statement\n----\n%s\n----\n to throw exception type %s but it threw something else.",#stmt,#exc); \
607  }while(false)
608 
609 // When we're only required to throw in Debug, we have to suppress the
610 // test case altogether in Release because it may cause damage.
611 #ifdef NDEBUG
612  #define SimTK_TEST_MUST_THROW_DEBUG(stmt)
615  #define SimTK_TEST_MUST_THROW_EXC_DEBUG(stmt,exc)
618 #else
619  #define SimTK_TEST_MUST_THROW_DEBUG(stmt) SimTK_TEST_MUST_THROW(stmt)
622  #define SimTK_TEST_MUST_THROW_EXC_DEBUG(stmt,exc) \
625  SimTK_TEST_MUST_THROW_EXC(stmt,exc)
626 #endif
627 
628 #else // expected throws are suppressed
629 #define SimTK_TEST_MUST_THROW(stmt)
630 #define SimTK_TEST_MUST_THROW_SHOW(stmt)
631 #define SimTK_TEST_MUST_THROW_EXC(stmt,exc)
632 #define SimTK_TEST_MAY_THROW(stmt)
633 #define SimTK_TEST_MAY_THROW_EXC(stmt,exc)
634 #define SimTK_TEST_MUST_THROW_DEBUG(stmt)
635 #define SimTK_TEST_MUST_THROW_EXC_DEBUG(stmt,exc)
636 #endif
637 
638 
639 // End of Regression testing group.
641 
642 #endif // SimTK_SimTKCOMMON_TESTING_H_
static bool numericallyEqual(const Row< N, E1, S1 > &v1, const Row< N, E2, S2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:307
Vec< 2, Vec3 > SpatialVec
Spatial vectors are used for (rotation,translation) quantities and consist of a pair of Vec3 objects...
Definition: MassProperties.h:50
static double defTol2()
Definition: Testing.h:189
static bool numericallyEqual(double v1, long double v2, int n, double tol=defTol< double >())
Definition: Testing.h:222
static Mat< M, N > randMat()
Definition: Testing.h:405
This is a subclass of Random that generates numbers uniformly distributed within a specified range...
Definition: Random.h:96
Subtest(const std::string &name)
Definition: Testing.h:441
static bool numericallyEqual(const negator< conjugate< P > > &v1, const std::complex< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:290
static bool numericallyEqual(const UnitInertia_< P > &G1, const UnitInertia_< P > &G2, int n, double tol=defTol< P >())
Definition: Testing.h:383
This is a small, fixed-size symmetric or Hermitian matrix designed for no-overhead inline computation...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:621
Real getValue() const
Get the next value in the pseudo-random sequence.
This is the vector class intended to appear in user code for large, variable size column vectors...
Definition: BigMatrix.h:171
static bool numericallyEqual(long double v1, long double v2, int n, double tol=defTol< long double >())
Definition: Testing.h:204
static bool numericallyEqual(const conjugate< P > &v1, const conjugate< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:259
static bool numericallyEqual(int i1, double f2, int n, double tol=defTol< double >())
Definition: Testing.h:236
static bool numericallyEqual(double v1, float v2, int n, double tol=defTol< float >())
Definition: Testing.h:216
static bool numericallyEqual(const SymMat< N, E1, S1 > &v1, const SymMat< N, E2, S2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:317
static bool numericallyEqual(double f1, int i2, int n, double tol=defTol< double >())
Definition: Testing.h:238
static Row< N > randRow()
Definition: Testing.h:404
static bool numericallyEqual(const RowVector_< E1 > &v1, const RowVectorView_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:348
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
SimTK::conjugate<R> should be instantiated only for float, double, long double.
Definition: String.h:45
static bool numericallyEqual(long double v1, float v2, int n, double tol=defTol< float >())
Definition: Testing.h:220
static Vec3 randVec3()
Definition: Testing.h:415
static bool numericallyEqual(double v1, double v2, int n, double tol=defTol< double >())
Definition: Testing.h:200
std::complex< Real > Complex
This is the default complex type for SimTK, with precision for the real and imaginary parts set to th...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:609
The Rotation class is a Mat33 that guarantees that the matrix can be interpreted as a legitimate 3x3 ...
Definition: Quaternion.h:40
bool isSameRotationToWithinAngle(const Rotation_ &R, RealP okPointingAngleErrorRads) const
Return true if "this" Rotation is nearly identical to "R" within a specified pointing angle error...
static bool numericallyEqual(float v1, long double v2, int n, double tol=defTol< float >())
Definition: Testing.h:218
static bool numericallyEqual(const negator< P > &v1, const negator< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:274
TAsVec & updAsVec()
Definition: SymMat.h:832
static bool numericallyEqual(const std::complex< P > &v1, const negator< conjugate< P > > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:294
conjugate< Real > Conjugate
Definition: Scalar.h:57
int size() const
Definition: VectorBase.h:396
const SymMat< 3, P > & asSymMat33() const
Obtain a reference to the underlying symmetric matrix type.
Definition: MassProperties.h:397
static bool numericallyEqual(const Mat< M, N, E1, CS1, RS1 > &v1, const Mat< M, N, E2, CS2, RS2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:312
static bool numericallyEqual(float v1, double v2, int n, double tol=defTol< float >())
Definition: Testing.h:214
static bool numericallyEqual(const P &v1, const negator< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:278
negator<N>, where N is a number type (real, complex, conjugate), is represented in memory identically...
Definition: String.h:44
static bool numericallyEqual(const VectorView_< E1 > &v1, const VectorView_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:321
static bool numericallyEqual(const Matrix_< E1 > &m1, const MatrixView_< E2 > &m2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:365
static Vec< M > randVec()
Definition: Testing.h:402
SimTK_Real Real
This is the default compiled-in floating point type for SimTK, either float or double.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:606
static bool numericallyEqual(unsigned u1, unsigned u2, int n, double tol=0)
Definition: Testing.h:211
static bool numericallyEqual(unsigned i1, float f2, int n, double tol=defTol< float >())
Definition: Testing.h:232
double cpuTime()
Return the cumulative CPU time in seconds (both kernel and user time) that has been used so far by an...
Definition: Timing.h:186
static bool numericallyEqual(int i1, long double f2, int n, double tol=defTol< long double >())
Definition: Testing.h:244
static Complex randComplex()
Definition: Testing.h:397
static double randDouble()
Definition: Testing.h:400
static Vector randVector(int m)
Definition: Testing.h:410
(Advanced) This class is identical to RowVector_ except that it has shallow (reference) copy and assi...
Definition: BigMatrix.h:173
static bool numericallyEqual(const RowVectorView_< E1 > &v1, const RowVector_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:351
static bool numericallyEqual(long double f1, unsigned i2, int n, double tol=defTol< long double >())
Definition: Testing.h:250
Rotation_< Real > Rotation
Definition: Rotation.h:47
static SymMat< N > randSymMat()
Definition: Testing.h:407
static bool numericallyEqual(const Matrix_< E1 > &m1, const Matrix_< E2 > &m2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:362
double realTime()
Return current time on the high-resolution interval timer in seconds.
Definition: Timing.h:248
Test(const std::string &name)
Definition: Testing.h:166
static bool numericallyEqual(unsigned i1, double f2, int n, double tol=defTol< double >())
Definition: Testing.h:240
This is a fixed-length column vector designed for no-overhead inline computation. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:618
static bool numericallyEqual(const conjugate< P > &v1, const std::complex< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:269
static bool numericallyEqual(const negator< P > &v1, const P &v2, int n, double tol=defTol< P >())
Definition: Testing.h:282
int nrow() const
Return the number of rows m in the logical shape of this matrix.
Definition: MatrixBase.h:136
static bool numericallyEqual(const RowVector_< E1 > &v1, const RowVector_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:345
const TAsVec & getAsVec() const
Definition: SymMat.h:831
(Advanced) This class is identical to Matrix_ except that it has shallow (reference) copy and assignm...
Definition: BigMatrix.h:167
static bool numericallyEqual(float f1, int i2, int n, double tol=defTol< float >())
Definition: Testing.h:230
static bool numericallyEqual(const RowVectorView_< E1 > &v1, const RowVectorView_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:338
This class represents the rotate-and-shift transform which gives the location and orientation of a ne...
Definition: Transform.h:43
ELEM max(const VectorBase< ELEM > &v)
Definition: VectorMath.h:251
static Real randReal()
Definition: Testing.h:393
static bool numericallyEqual(float v1, float v2, int n, double tol=defTol< float >())
Definition: Testing.h:196
static bool numericallyEqual(const Transform_< P > &T1, const Transform_< P > &T2, int n, double tol=defTol< P >())
Definition: Testing.h:377
static bool numericallyEqual(const MatrixView_< E1 > &m1, const Matrix_< E2 > &m2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:368
int size() const
Definition: RowVectorBase.h:237
static bool numericallyEqual(const negator< std::complex< P > > &v1, const conjugate< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:286
static SymMat33 randSymMat33()
Definition: Testing.h:417
This is the matrix class intended to appear in user code for large, variable size matrices...
Definition: BigMatrix.h:168
const Real Pi
Real(pi)
const Vec< 3, P > & p() const
Return a read-only reference to our translation vector p_BF.
Definition: Transform.h:239
RowVectorBase< typename CNT< ELEM >::TAbs > abs(const RowVectorBase< ELEM > &v)
Definition: VectorMath.h:120
Mat< 2, 2, Mat33 > SpatialMat
Spatial matrices are used to hold 6x6 matrices that are best viewed as 2x2 matrices of 3x3 matrices; ...
Definition: MassProperties.h:72
The physical meaning of an inertia is the distribution of a rigid body&#39;s mass about a particular poin...
Definition: MassProperties.h:82
This is a fixed-length row vector designed for no-overhead inline computation.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:619
A UnitInertia matrix is a unit-mass inertia matrix; you can convert it to an Inertia by multiplying i...
Definition: MassProperties.h:81
static Conjugate randConjugate()
Definition: Testing.h:398
static bool numericallyEqual(const Vector_< E1 > &v1, const VectorView_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:331
Internal utility class for generating test messages for subtests.
Definition: Testing.h:439
static bool numericallyEqual(const Rotation_< P > &R1, const Rotation_< P > &R2, int n, double tol=defTol< P >())
Definition: Testing.h:372
static bool numericallyEqual(long double f1, int i2, int n, double tol=defTol< long double >())
Definition: Testing.h:246
static bool numericallyEqual(const Vec< M, E1, S1 > &v1, const Vec< M, E2, S2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:302
static Transform randTransform()
Definition: Testing.h:429
Represents a variable size row vector; much less common than the column vector type Vector_...
Definition: BigMatrix.h:174
static bool numericallyEqual(int i1, int i2, int n, double tol=0)
Definition: Testing.h:210
~Test()
Definition: Testing.h:173
This file ensures that we have access to the Posix time functions clock_getttime() and nanosleep()...
static bool numericallyEqual(long double v1, double v2, int n, double tol=defTol< double >())
Definition: Testing.h:224
static bool numericallyEqual(const Inertia_< P > &I1, const Inertia_< P > &I2, int n, double tol=defTol< P >())
Definition: Testing.h:388
static bool numericallyEqual(int i1, float f2, int n, double tol=defTol< float >())
Definition: Testing.h:228
static bool numericallyEqual(const VectorView_< E1 > &v1, const Vector_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:334
static bool numericallyEqual(const std::complex< P > &v1, const std::complex< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:254
This class represents a small matrix whose size is known at compile time, containing elements of any ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:620
static Mat33 randMat33()
Definition: Testing.h:416
static SpatialVec randSpatialVec()
Definition: Testing.h:418
static bool numericallyEqual(unsigned i1, long double f2, int n, double tol=defTol< long double >())
Definition: Testing.h:248
This is the header which should be included in user programs that would like to make use of all the S...
int ncol() const
Return the number of columns n in the logical shape of this matrix.
Definition: MatrixBase.h:138
static Matrix randMatrix(int m, int n)
Definition: Testing.h:412
Includes internal headers providing declarations for the basic SimTK Core classes.
static bool numericallyEqual(const Vector_< E1 > &v1, const Vector_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:328
const Rotation_< P > & R() const
Return a read-only reference to the contained rotation R_BF.
Definition: Transform.h:215
static double defTol()
Definition: Testing.h:185
static bool numericallyEqual(const conjugate< P > &v1, const negator< std::complex< P > > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:298
static bool numericallyEqual(const MatrixView_< E1 > &v1, const MatrixView_< E2 > &v2, int n, double tol=(defTol2< E1, E2 >()))
Definition: Testing.h:355
(Advanced) This class is identical to Vector_ except that it has shallow (reference) copy and assignm...
Definition: BigMatrix.h:170
static bool numericallyEqual(const std::complex< P > &v1, const conjugate< P > &v2, int n, double tol=defTol< P >())
Definition: Testing.h:264
static float randFloat()
Definition: Testing.h:399
static Rotation randRotation()
Definition: Testing.h:425
~Subtest()
Definition: Testing.h:448
static bool numericallyEqual(double f1, unsigned i2, int n, double tol=defTol< double >())
Definition: Testing.h:242
Definition: negator.h:64
static SpatialMat randSpatialMat()
Definition: Testing.h:421
Transform_< Real > Transform
Definition: Transform.h:44
static bool numericallyEqual(float f1, unsigned i2, int n, double tol=defTol< float >())
Definition: Testing.h:234