Logo ROOT   6.10/09
Reference Guide
testSMatrix.cxx
Go to the documentation of this file.
1 #include <cmath>
2 #include "Math/SVector.h"
3 #include "Math/SMatrix.h"
4 
5 #include <iomanip>
6 #include <iostream>
7 #include <limits>
8 #include <string>
9 #include <vector>
10 
11 using namespace ROOT::Math;
12 
13 using std::cout;
14 using std::endl;
15 
16 //#define TEST_STATIC_CHECK // for testing compiler failures (static check)
17 
18 #define XXX
19 
20 template <typename T>
21 void compare_fail(T a, T b, int ulps, T tolerance, const std::string &what)
22 {
23  cout << std::boolalpha << std::endl << "FAILED COMPARISON: " << what << std::endl << a << " != " << b << std::endl;
24 
25  if (std::is_floating_point<T>::value) {
26  cout << std::scientific << std::setprecision(16) << "difference: " << std::abs(a - b) << " ( "
27  << std::abs(a - b) / tolerance << " ulps)" << std::endl
28  << " tolerance: " << tolerance << " (" << ulps << " ulps)" << std::endl;
29  }
30 }
31 
32 template <typename T>
33 typename std::enable_if<!std::is_floating_point<T>::value, int>::type compare(T a, T b, const std::string &s = "",
34  int ulps = 10)
35 {
36  if (a != b) compare_fail(a, b, T(0), T(0), s);
37  return a == b ? 0 : 1;
38 }
39 
40 template <typename T>
41 typename std::enable_if<std::is_floating_point<T>::value, int>::type compare(T a, T b, const std::string &s = "",
42  int ulps = 10)
43 {
44  using std::abs;
45 
46  if (a == b) return 0;
47 
49 
50  if (abs(a * b) > tol * tol) tol *= T(0.5) * (abs(a) + abs(b));
51 
52  if (abs(a - b) > tol) {
53  compare_fail(a, b, ulps, tol, s);
54  return 1;
55  }
56  return 0;
57 }
58 
59 int test1()
60 {
61 
62  SVector<float, 3> x(4, 5, 6);
63  SVector<float, 2> y(2.0, 3.0);
64  std::cout << "x: " << x << std::endl;
65  std::cout << "y: " << y << std::endl;
66 
67  // float yy1=2.; float yy2 = 3;
68  // SVector<float,2> y2(yy1,yy2);
69 
72 
73  A.Place_in_row(y, 1, 1);
74  A.Place_in_col(x, 1, 0);
75  A.Place_in_col(x + 2, 1, 0);
76  A.Place_in_row(y + 3, 1, 1);
77 
78 #ifndef _WIN32
79  A.Place_at(B, 2, 1);
80 #else
81  // Windows need template parameters
82  A.Place_at<2, 2>(B, 2, 1);
83 #endif
84  std::cout << "A: " << std::endl << A << std::endl;
85 
86  SVector<float, 3> z(x + 2);
87  z.Place_at(y, 1);
88  z.Place_at(y + 3, 1);
89  std::cout << "z: " << std::endl << z << std::endl;
90 
91 #ifdef TEST_STATIC_CHECK
92  // create a vector of size 2 from 3 arguments
93  SVector<float, 2> vbad(1, 2, 3);
94 #endif
95 
96  // test STL interface
97 
98  // float p[2] = {1,2};
99  float m[4] = {1, 2, 3, 4};
100 
101  // SVector<float, 2> sp(p,2);
102  SMatrix<float, 2, 2> sm(m, 4);
103 
104  // std::cout << "sp: " << std::endl << sp << std::endl;
105  std::cout << "sm: " << std::endl << sm << std::endl;
106 
107  // std::vector<float> vp(sp.begin(), sp.end() );
108  std::vector<float> vm(sm.begin(), sm.end());
109 
110  SVector<float, 4> sp1(m, 4);
111  SVector<float, 4> sp2(sm.begin(), sm.end());
112  SMatrix<float, 2, 2> sm2(vm.begin(), vm.end());
113 
114  if (sp1 != sp2) {
115  std::cout << "Test STL interface for SVector failed" << std::endl;
116  return -1;
117  }
118  if (sm2 != sm) {
119  std::cout << "Test STL interface for SMatrix failed" << std::endl;
120  return -1;
121  }
122 
123  // test construction from identity
125 
126  std::cout << "3x3 Identity\n" << i3 << std::endl;
127 
129  std::cout << "2x3 Identity\n" << i23 << std::endl;
130 
132  std::cout << "Sym matrix Identity\n" << is3 << std::endl;
133 
134  // test operator = from identity
135  A = SMatrixIdentity();
136  std::cout << "4x3 Identity\n" << A << std::endl;
137 
138  std::vector<float> v(6);
139  for (int i = 0; i < 6; ++i) v[i] = double(i + 1);
140  SMatrix<float, 3, 3, MatRepSym<float, 3>> s3(v.begin(), v.end());
141  std::cout << s3 << std::endl;
142 
143  return 0;
144 }
145 
146 int test2()
147 {
148 #ifdef XXX
150  A(0, 0) = A(1, 0) = 1;
151  A(0, 1) = 3;
152  A(1, 1) = A(2, 2) = 2;
153  std::cout << "A: " << std::endl << A << std::endl;
154 
155  SVector<double, 3> x = A.Row(0);
156  std::cout << "x: " << x << std::endl;
157 
158  SVector<double, 3> y = A.Col(1);
159  std::cout << "y: " << y << std::endl;
160 
161  return 0;
162 #endif
163 }
164 
165 int test3()
166 {
167 #ifdef XXX
169  A(0, 0) = A(0, 1) = A(1, 0) = 1;
170  A(1, 1) = A(2, 2) = 2;
171 
172  SMatrix<double, 3> B = A; // save A in B
173  std::cout << "A: " << std::endl << A << std::endl;
174 
175  double det = 0.;
176  A.Det(det);
177  std::cout << "Determinant: " << det << std::endl;
178  // WARNING: A has changed!!
179  std::cout << "A again: " << std::endl << A << std::endl;
180  A = B;
181 
182  A.Invert();
183  std::cout << "A^-1: " << std::endl << A << std::endl;
184 
185  // check if this is really the inverse:
186  std::cout << "A^-1 * B: " << std::endl << A * B << std::endl;
187 
188  return 0;
189 #endif
190 }
191 
192 int test4()
193 {
194 #ifdef XXX
196  A(0, 0) = A(0, 1) = A(1, 0) = 1;
197  A(1, 1) = A(2, 2) = 2;
198  std::cout << " A: " << std::endl << A << std::endl;
199 
200  SVector<double, 3> x(1, 2, 3);
201  std::cout << "x: " << x << std::endl;
202 
203  // we add 1 to each component of x and A
204  std::cout << " (x+1)^T * (A+1) * (x+1): " << Similarity(x + 1, A + 1) << std::endl;
205 
206  return 0;
207 #endif
208 }
209 
210 int test5()
211 {
212 #ifdef XXX
214  A(0, 0) = A(0, 1) = A(1, 1) = A(2, 2) = 4.;
215  A(2, 3) = 1.;
216  std::cout << "A: " << std::endl << A << std::endl;
217  SVector<float, 4> x(1, 2, 3, 4);
218  std::cout << " x: " << x << std::endl;
219  SVector<float, 3> a(1, 2, 3);
220  std::cout << " a: " << a << std::endl;
221  SVector<float, 4> y = x + A * a;
222  // SVector<float,4> y = A * a;
223  std::cout << " y: " << y << std::endl;
224 
225  SVector<float, 3> b = (x + 1) * (A + 1);
226  std::cout << " b: " << b << std::endl;
227 
228  return 0;
229 #endif
230 }
231 
232 int test6()
233 {
234 #ifdef XXX
236  A(0, 0) = A(0, 1) = A(1, 1) = A(2, 0) = A(3, 1) = 4.;
237  std::cout << "A: " << std::endl << A << std::endl;
238 
240  S(0, 0) = S(0, 1) = S(1, 1) = S(0, 2) = 1.;
241  std::cout << " S: " << std::endl << S << std::endl;
242 
243  SMatrix<float, 4, 3> C = A * S;
244  std::cout << " C: " << std::endl << C << std::endl;
245 
246  return 0;
247 #endif
248 }
249 
250 int test7()
251 {
252 #ifdef XXX
253  SVector<float, 3> xv(4, 4, 4);
254  SVector<float, 3> yv(5, 5, 5);
255  SVector<float, 2> zv(64, 64);
257  x.Place_in_row(xv, 0, 0);
258  x.Place_in_row(xv, 1, 0);
260  y.Place_in_row(yv, 0, 0);
261  y.Place_in_row(yv, 1, 0);
263  z.Place_in_col(zv, 0, 0);
264  z.Place_in_col(zv, 0, 1);
265  z.Place_in_col(zv, 0, 2);
266 
267  std::cout << "x\n" << x << "y\n" << y << "z\n" << z << std::endl;
268 
269  // element wise multiplication
270  std::cout << "x * (- y) : " << std::endl << Times(x, -y) << std::endl;
271 
272  x += z - y;
273  std::cout << "x += z - y: " << std::endl << x << std::endl;
274 
275  // element wise square root
276  std::cout << "sqrt(z): " << std::endl << sqrt(z) << std::endl;
277 
278  // element wise multiplication with constant
279  std::cout << "2 * y: " << std::endl << 2 * y << std::endl;
280 
281 // a more complex expression (failure on Win32)
282 #ifndef _WIN32
283  // std::cout << "fabs(-z + 3*x): " << std::endl << fabs(-z + 3*x) << std::endl;
284  std::cout << "fabs(3*x -z): " << std::endl << fabs(3 * x - z) << std::endl;
285 #else
286  // doing directly gives internal compiler error on windows
287  SMatrix<float, 2, 3> ztmp = 3 * x - z;
288  std::cout << " fabs(-z+3*x) " << std::endl << fabs(ztmp) << std::endl;
289 #endif
290 
291  return 0;
292 #endif
293 }
294 
295 int test8()
296 {
297 #ifdef XXX
299  SVector<float, 3> av1(5., 15., 5.);
300  SVector<float, 3> av2(15., 5., 15.);
301  A.Place_in_row(av1, 0, 0);
302  A.Place_in_row(av2, 1, 0);
303 
304  std::cout << "A: " << std::endl << A << std::endl;
305 
306  SVector<float, 3> x(1, 2, 3);
307  SVector<float, 3> y(4, 5, 6);
308 
309  std::cout << "dot(x,y): " << Dot(x, y) << std::endl;
310 
311  std::cout << "mag(x): " << Mag(x) << std::endl;
312 
313  std::cout << "cross(x,y): " << Cross(x, y) << std::endl;
314 
315  std::cout << "unit(x): " << Unit(x) << std::endl;
316 
317  SVector<float, 3> z(4, 16, 64);
318  std::cout << "x + y: " << x + y << std::endl;
319 
320  std::cout << "x + y(0) " << (x + y)(0) << std::endl;
321 
322  std::cout << "x * -y: " << x * -y << std::endl;
323  x += z - y;
324  std::cout << "x += z - y: " << x << std::endl;
325 
326  // element wise square root
327  std::cout << "sqrt(z): " << sqrt(z) << std::endl;
328 
329  // element wise multiplication with constant
330  std::cout << "2 * y: " << 2 * y << std::endl;
331 
332  // a more complex expression
333  std::cout << "fabs(-z + 3*x): " << fabs(-z + 3 * x) << std::endl;
334 
336  SVector<float, 2> b(1, 2);
337  a.Place_at(b, 2);
338  std::cout << "a: " << a << std::endl;
339 #endif
340 
342  std::cout << x2 << std::endl;
343 
344  return 0;
345 }
346 
347 int test9()
348 {
349  // test non mutating inversions
351  A(0, 0) = A(0, 1) = A(1, 0) = 1;
352  A(1, 1) = A(2, 2) = 2;
353 
354  double det = 0.;
355  A.Det2(det);
356  std::cout << "Determinant: " << det << std::endl;
357 
358  int ifail;
359  SMatrix<double, 3> Ainv = A.Inverse(ifail);
360  if (ifail) {
361  std::cout << "inversion failed\n";
362  return -1;
363  }
364  std::cout << "A^-1: " << std::endl << Ainv << std::endl;
365 
366  // check if this is really the inverse:
367  std::cout << "A^-1 * A: " << std::endl << Ainv * A << std::endl;
368 
369  return 0;
370 }
371 
372 int test10()
373 {
374  // test slices
375  int iret = 0;
376  double d[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
377  SMatrix<double, 3> A(d, d + 9);
378 
379  std::cout << "A: " << A << std::endl;
380 
383 
384  std::cout << " v23 = " << v23 << " \tv69 = " << v69 << std::endl;
385  iret |= compare(Dot(v23, v69), double(2 * 6 + 3 * 9));
386 
387  // SMatrix<double,2,2> subA1 = A.Sub<2,2>( 1,0);
388  // SMatrix<double,2,3> subA2 = A.Sub<2,3>( 0,0);
391  std::cout << " subA1 = " << subA1 << " \nsubA2 = " << subA2 << std::endl;
392  iret |= compare(subA1(0, 0), subA2(1, 0));
393  iret |= compare(subA1(0, 1), subA2(1, 1));
394 
395  SVector<double, 3> diag = A.Diagonal();
396  std::cout << " diagonal = " << diag << std::endl;
397  iret |= compare(Mag2(diag), double(1 + 5 * 5 + 9 * 9));
398  iret |= compare(A.Trace(), double(1 + 5 + 9));
399 
401  std::cout << " B = " << B << std::endl;
402 
403 #ifdef UNSUPPORTED_TEMPLATE_EXPRESSION
404  // in this case function is templated. Need to pass the 6
406  SVector<double, 6> vL = B.LowerBlock<SVector<double, 6>>();
407 #else
408  // standards
410  SVector<double, 6> vL = B.LowerBlock();
411 #endif
412  std::cout << " vU = " << vU << " \tvL = " << vL << std::endl;
413  // need to test mag since order can change
414  iret |= compare(Mag(vU), Mag(vL));
415 
416  // test subvector
418  std::cout << " sub vU = " << subV << std::endl;
419 
420  iret |= compare(vU[2], subV[1]);
421 
422  // test constructor from subVectors
423  SMatrix<double, 3> C(vU, false);
424  SMatrix<double, 3> D(vL, true);
425 
426  // std::cout << " C = " << C << std::endl;
427  // std::cout << " D = " << D << std::endl;
428 
429  iret |= compare(static_cast<int>(C == D), 1);
430 
433 
434  iret |= compare(static_cast<int>(C == C2), 1);
435  iret |= compare(static_cast<int>(D == D2), 1);
436 
437  return iret;
438 }
439 
440 int test11()
441 {
442 
443  int iret = 0;
444  double dSym[15] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
445  double d3[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
446  double d2[10] = {10, 1, 4, 5, 8, 2, 3, 6, 7, 9};
447 
448  SVector<double, 15> vsym(dSym, 15);
449 
450  SMatrix<double, 5, 5> m1(vsym);
451  SMatrix<double, 2, 5> m2(d2, d2 + 10);
452  SMatrix<double, 5, 2> m3(d3, d3 + 10);
453  // SMatrix<double,5,5> I;
454 
455  SMatrix<double, 5, 5> m32 = m3 * m2;
456 
457  SMatrix<double, 5, 5> m4 = m1 - m32 * m1;
458  SMatrix<double, 5, 5> m5 = m3 * m2;
459 
460  // now thanks to the IsInUse() function this should work
461  m5 = m1 - m5 * m1;
462 
463  // this works probably becuse here multiplication is done first
464 
465  SMatrix<double, 5, 5> m6 = m3 * m2;
466  // m6 = - m6 * m1 + m1;
467  // this does not work if use reference in binary and unary operators , better this
468  m6 = -m32 * m1 + m1;
469 
470  std::cout << m4 << std::endl;
471  std::cout << m5 << std::endl;
472  std::cout << m6 << std::endl;
473 
474  // this is test will now work
475  iret |= compare(m4 == m5, true);
476  iret |= compare(m4 == m6, true);
477 
478  return iret;
479 }
480 
481 int test12()
482 {
483  // test of symmetric matrices
484 
485  int iret = 0;
487  S(0, 0) = 1.233;
488  S(0, 1) = 2.33;
489  S(1, 1) = 3.45;
490  std::cout << "S\n" << S << std::endl;
491 
492  double a = 3;
493  std::cout << "S\n" << a * S << std::endl;
494 
495  // test inversion
496  int ifail1 = 0;
497  // int ifail2 = 0;
499  // SMatrix<double,2,2,MatRepSym<double,2> > Sinv2 = S.Sinverse(ifail2);
500  // std::cout << "Inverse: S-1 " << Sinv1 << "\nifail=" << ifail1 << std::endl;
501  // std::cout << "Sinverse: S-1" << Sinv2 << "\nifail=" << ifail2 << std::endl;
502 
503  SMatrix<double, 2> IS1 = S * Sinv1;
504  // SMatrix<double,2> IS2 = S*Sinv2;
505  double d1 = std::sqrt(IS1(1, 0) * IS1(1, 0) + IS1(0, 1) * IS1(0, 1));
506  // double d2 = std::sqrt( IS2(1,0)*IS2(1,0) + IS2(0,1)*IS2(0,1) );
507 
508  iret |= compare(d1 < 1E-6, true, "inversion1");
509  // iret |= compare( d2 < 1E-6,true,"inversion2" );
510 
512  M1(0, 1) = 1;
513  M1(1, 0) = 1;
514  M1(0, 2) = 1;
515  M1(1, 2) = 1;
518  // S2 -= M1*Transpose(M2); // this should fails to compile
519  SMatrix<double, 2> mS2(S2);
520  mS2 -= M1 * Transpose(M2);
521  // std::cout << "S2=S-M1*M2T\n" << mS2 << std::endl;
522  iret |= compare(mS2(0, 1), S(0, 1) - 1);
523  mS2 += M1 * Transpose(M2);
524  iret |= compare(mS2(0, 1), S(0, 1));
525 
526  // std::cout << "S2+=M1*M2T\n" << mS2 << std::endl;
527 
530  // std::cout << " Symmetric matrix size: " << sizeof(mSym) << std::endl;
531  // std::cout << " Normal matrix size: " << sizeof( m ) << std::endl;
532 
534  // std::cout << " Symmetric matrix size: " << sizeof(mSym2) << std::endl;
535 
536  return iret;
537 }
538 
539 int test13()
540 {
541  // test of operation with a constant;
542 
543  int iret = 0;
544 
545  int a = 2;
546  float b = 3;
547 
548  SVector<double, 2> v(1, 2);
549  SVector<double, 2> v2 = v + a;
550  iret |= compare(v2[1], v[1] + a);
551  SVector<double, 2> v3 = a + v;
552  iret |= compare(v3[1], v[1] + a);
553  iret |= compare(v3[0], v2[0]);
554 
555  v2 = v - a;
556  iret |= compare(v2[1], v[1] - a);
557  v3 = a - v;
558  iret |= compare(v3[1], a - v[1]);
559 
560  // test now with expression
561  v2 = b * v + a;
562  iret |= compare(v2[1], b * v[1] + a);
563  v3 = a + v * b;
564  iret |= compare(v3[1], b * v[1] + a);
565  v2 = v * b - a;
566  iret |= compare(v2[1], b * v[1] - a);
567  v3 = a - b * v;
568  iret |= compare(v3[1], a - b * v[1]);
569 
570  v2 = a * v / b;
571  iret |= compare(v2[1], a * v[1] / b);
572 
573  SVector<double, 2> p(1, 2);
574  SVector<double, 2> q(3, 4);
575  v = p + q;
576  v2 = a * (p + q);
577  iret |= compare(v2[1], a * v[1]);
578  v3 = (p + q) * b;
579  iret |= compare(v3[1], b * v[1]);
580  v2 = (p + q) / b;
581  iret |= compare(v2[1], v[1] / b);
582 
583  // std::cout << "tested vector -constant operations : v2 = " << v2 << " v3 = " << v3 << std::endl;
584 
585  // now test the matrix (normal)
586 
588  m.Place_in_row(p, 0, 0);
589  m.Place_in_row(q, 1, 0);
590 
591  SMatrix<double, 2, 2> m2, m3;
592 
593  m2 = m + a;
594  iret |= compare(m2(1, 0), m(1, 0) + a);
595  m3 = a + m;
596  iret |= compare(m3(1, 0), m(1, 0) + a);
597  iret |= compare(m3(0, 0), m2(0, 0));
598 
599  m2 = m - a;
600  iret |= compare(m2(1, 0), m(1, 0) - a);
601  m3 = a - m;
602  iret |= compare(m3(1, 0), a - m(1, 0));
603 
604  // test now with expression
605  m2 = b * m + a;
606  iret |= compare(m2(1, 0), b * m(1, 0) + a);
607  m3 = a + m * b;
608  iret |= compare(m3(1, 0), b * m(1, 0) + a);
609  m2 = m * b - a;
610  iret |= compare(m2(1, 0), b * m(1, 0) - a);
611  m3 = a - b * m;
612  iret |= compare(m3(1, 0), a - b * m(1, 0));
613 
614  m2 = a * m / b;
615  iret |= compare(m2(1, 0), a * m(1, 0) / b);
616 
617  SMatrix<double, 2> u = m;
619  w(0, 0) = 5;
620  w(0, 1) = 6;
621  w(1, 0) = 7;
622  w(1, 1) = 8;
623 
624  m = u + w;
625  m2 = a * (u + w);
626  iret |= compare(m2(1, 0), a * m(1, 0));
627  m3 = (u + w) * b;
628  iret |= compare(m3(1, 0), b * m(1, 0));
629  m2 = (u + w) / b;
630  iret |= compare(m2(1, 0), m(1, 0) / b);
631 
632  // std::cout << "tested general matrix -constant operations :\nm2 =\n" << m2 << "\nm3 =\n" << m3 << std::endl;
633 
634  // now test the symmetric matrix
635 
637  s(0, 0) = 1;
638  s(1, 0) = 2;
639  s(1, 1) = 3;
640 
642 
643  s2 = s + a;
644  iret |= compare(s2(1, 0), s(1, 0) + a);
645  s3 = a + s;
646  iret |= compare(s3(1, 0), s(1, 0) + a);
647  iret |= compare(s3(0, 0), s2(0, 0));
648 
649  s2 = s - a;
650  iret |= compare(s2(1, 0), s(1, 0) - a);
651  s3 = a - s;
652  iret |= compare(s3(1, 0), a - s(1, 0));
653 
654  // test now with expression
655  s2 = b * s + a;
656  iret |= compare(s2(1, 0), b * s(1, 0) + a);
657  s3 = a + s * b;
658  iret |= compare(s3(1, 0), b * s(1, 0) + a);
659  s2 = s * b - a;
660  iret |= compare(s2(1, 0), b * s(1, 0) - a);
661  s3 = a - b * s;
662  iret |= compare(s3(1, 0), a - b * s(1, 0));
663 
664  s2 = a * s / b;
665  iret |= compare(s2(1, 0), a * s(1, 0) / b);
666 
669  t(0, 0) = 4;
670  t(0, 1) = 5;
671  t(1, 1) = 6;
672 
673  s = r + t;
674  s2 = a * (r + t);
675  iret |= compare(s2(1, 0), a * s(1, 0), "a*(r+t)");
676  s3 = (t + r) * b;
677  iret |= compare(s3(1, 0), b * s(1, 0), "(t+r)*b");
678  s2 = (r + t) / b;
679  iret |= compare(s2(1, 0), s(1, 0) / b, "(r+t)/b");
680 
681  // std::cout << "tested sym matrix -constant operations :\ns2 =\n" << s2 << "\ns3 =\n" << s3 << std::endl;
682 
683  return iret;
684 }
685 
686 int test14()
687 {
688  // test place_at (insertion) of all type of matrices
689 
690  int iret = 0;
691 
692  // test place at with sym matrices
693 
695  S(0, 0) = 1;
696  S(0, 1) = 2;
697  S(1, 1) = 3;
698 
699  double u[6] = {1, 2, 3, 4, 5, 6};
701 
702  // place general matrix in general matrix
704  A.Place_at(U, 1, 0);
705  // std::cout << "Test general matrix placed in general at 1,0 :\nA=\n" << A << std::endl;
706  iret |= compare(A(1, 0), U(0, 0));
707  iret |= compare(A(1, 1), U(0, 1));
708  iret |= compare(A(2, 1), U(1, 1));
709  iret |= compare(A(2, 2), U(1, 2));
710 
711  A.Place_at(-2 * U, 1, 0);
712  iret |= compare(A(1, 0), -2 * U(0, 0));
713  iret |= compare(A(1, 1), -2 * U(0, 1));
714  iret |= compare(A(2, 1), -2 * U(1, 1));
715  iret |= compare(A(2, 2), -2 * U(1, 2));
716 
717  // place symmetric in general (should work always)
718  A.Place_at(S, 0, 0);
719  // std::cout << "Test symmetric matrix placed in general at 0,0:\nA=\n" << A << std::endl;
720  iret |= compare(A(0, 0), S(0, 0));
721  iret |= compare(A(1, 0), S(0, 1));
722  iret |= compare(A(1, 1), S(1, 1));
723 
724  A.Place_at(2 * S, 0, 0);
725  iret |= compare(A(0, 0), 2 * S(0, 0));
726  iret |= compare(A(1, 0), 2 * S(0, 1));
727  iret |= compare(A(1, 1), 2 * S(1, 1));
728 
729  A.Place_at(S, 2, 0);
730  // std::cout << "A=\n" << A << std::endl;
731  iret |= compare(A(2, 0), S(0, 0));
732  iret |= compare(A(3, 0), S(0, 1));
733  iret |= compare(A(3, 1), S(1, 1));
734 
736 
737  // place symmetric in symmetric (OK for col=row)
738  B.Place_at(S, 1, 1);
739  // std::cout << "Test symmetric matrix placed in symmetric at 1,1:\nB=\n" << B << std::endl;
740  iret |= compare(B(1, 1), S(0, 0));
741  iret |= compare(B(2, 1), S(0, 1));
742  iret |= compare(B(2, 2), S(1, 1));
743 
744  B.Place_at(-S, 0, 0);
745  // std::cout << "B=\n" << B << std::endl;
746  iret |= compare(B(0, 0), -S(0, 0));
747  iret |= compare(B(1, 0), -S(0, 1));
748  iret |= compare(B(1, 1), -S(1, 1));
749 
750 // this should assert at run time
751 // B.Place_at(S,1,0);
752 // B.Place_at(2*S,1,0);
753 
754 // place general in symmetric should fail to compiler
755 #ifdef TEST_STATIC_CHECK
756  B.Place_at(U, 0, 0);
757  B.Place_at(-U, 0, 0);
758 #endif
759 
760  // test place vector in matrices
761  SVector<double, 2> v(1, 2);
762 
763  A.Place_in_row(v, 1, 1);
764  iret |= compare(A(1, 1), v[0]);
765  iret |= compare(A(1, 2), v[1]);
766  A.Place_in_row(2 * v, 1, 1);
767  iret |= compare(A(1, 1), 2 * v[0]);
768  iret |= compare(A(1, 2), 2 * v[1]);
769 
770  A.Place_in_col(v, 1, 1);
771  iret |= compare(A(1, 1), v[0]);
772  iret |= compare(A(2, 1), v[1]);
773  A.Place_in_col(2 * v, 1, 1);
774  iret |= compare(A(1, 1), 2 * v[0]);
775  iret |= compare(A(2, 1), 2 * v[1]);
776 
777  // place vector in sym matrices
778  B.Place_in_row(v, 0, 1);
779  // std::cout << "B=\n" << B << std::endl;
780  iret |= compare(B(0, 1), v[0]);
781  iret |= compare(B(1, 0), v[0]);
782  iret |= compare(B(2, 0), v[1]);
783  B.Place_in_row(2 * v, 1, 1);
784  iret |= compare(B(1, 1), 2 * v[0]);
785  iret |= compare(B(2, 1), 2 * v[1]);
786 
787  B.Place_in_col(v, 1, 0);
788  // std::cout << "B=\n" << B << std::endl;
789  iret |= compare(B(0, 1), v[0]);
790  iret |= compare(B(1, 0), v[0]);
791  iret |= compare(B(0, 2), v[1]);
792  B.Place_in_col(2 * v, 1, 1);
793  iret |= compare(B(1, 1), 2 * v[0]);
794  iret |= compare(B(1, 2), 2 * v[1]);
795 
796  // test Sub
798  iret |= compare(sB(0, 0), B(1, 1));
799  iret |= compare(sB(1, 0), B(1, 2));
800  iret |= compare(sB(1, 1), B(2, 2));
801 
803  iret |= compare(sA(0, 0), A(1, 0));
804  iret |= compare(sA(1, 0), A(2, 0));
805  iret |= compare(sA(1, 1), A(2, 1));
806  iret |= compare(sA(1, 2), A(2, 2));
807 
809  iret |= compare(sA(0, 0), B(0, 0));
810  iret |= compare(sA(1, 0), B(1, 0));
811  iret |= compare(sA(0, 1), B(0, 1));
812  iret |= compare(sA(1, 1), B(1, 1));
813  iret |= compare(sA(1, 2), B(1, 2));
814 
815 // this should run assert
816 // sA = A.Sub<SMatrix<double,2,3,MatRepStd<double,2,3> > > (0,2);
817 // sB = B.Sub<SMatrix<double,2,2,MatRepSym<double,2> > > (0,1);
818 
819 #ifdef TEST_STATIC_CHECK
823 #endif
824 
825 // test setDiagonal
826 
827 #ifdef TEST_STATIC_CHECK
828  SVector<double, 3> w(-1, -2, 3);
829  sA.SetDiagonal(w);
830  sB.SetDiagonal(w);
831 #endif
832 
833  sA.SetDiagonal(v);
834  iret |= compare(sA(1, 1), v[1]);
835  sB.SetDiagonal(v);
836  iret |= compare(sB(0, 0), v[0]);
837 
838  // test Trace
839  iret |= compare(sA.Trace(), v[0] + v[1]);
840  iret |= compare(sB.Trace(), v[0] + v[1]);
842  iret |= compare(sAt.Trace(), v[0] + v[1]);
843 
844  return iret;
845 }
846 
847 int test15()
848 {
849  // test using iterators
850  int iret = 0;
851 
852  double u[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
853  double w[6] = {1, 2, 3, 4, 5, 6};
854 
855  SMatrix<double, 3, 4> A1(u, 12);
856  iret |= compare(A1(0, 0), u[0]);
857  iret |= compare(A1(1, 2), u[6]);
858  iret |= compare(A1(2, 3), u[11]);
859  // std::cout << A1 << std::endl;
860 
861  SMatrix<double, 3, 4> A2(w, 6, true, true);
862  iret |= compare(A2(0, 0), w[0]);
863  iret |= compare(A2(1, 0), w[1]);
864  iret |= compare(A2(2, 0), w[3]);
865  iret |= compare(A2(2, 2), w[5]);
866  // std::cout << A2 << std::endl;
867 
868  // upper diagonal (needs 9 elements)
869  SMatrix<double, 3, 4> A3(u, 9, true, false);
870  iret |= compare(A3(0, 0), u[0]);
871  iret |= compare(A3(0, 1), u[1]);
872  iret |= compare(A3(0, 2), u[2]);
873  iret |= compare(A3(1, 2), u[5]);
874  iret |= compare(A3(2, 3), u[8]);
875  // std::cout << A3 << std::endl;
876 
877  // std::cout << "test sym matrix " << std::endl;
879  iret |= compare(S1(0, 0), w[0]);
880  iret |= compare(S1(1, 0), w[1]);
881  iret |= compare(S1(1, 1), w[2]);
882  iret |= compare(S1(2, 0), w[3]);
883  iret |= compare(S1(2, 1), w[4]);
884  iret |= compare(S1(2, 2), w[5]);
885 
886  SMatrix<double, 3, 3, MatRepSym<double, 3>> S2(w, 6, true, false);
887  iret |= compare(S2(0, 0), w[0]);
888  iret |= compare(S2(1, 0), w[1]);
889  iret |= compare(S2(2, 0), w[2]);
890  iret |= compare(S2(1, 1), w[3]);
891  iret |= compare(S2(2, 1), w[4]);
892  iret |= compare(S2(2, 2), w[5]);
893 
894  // check retrieve
895  double *pA1 = A1.begin();
896  for (int i = 0; i < 12; ++i) iret |= compare(pA1[i], u[i]);
897 
898  double *pS1 = S1.begin();
899  for (int i = 0; i < 6; ++i) iret |= compare(pS1[i], w[i]);
900 
901  // check with SetElements
902  std::vector<double> vu(u, u + 12);
903  std::vector<double> vw(w, w + 6);
905  B1.SetElements(vu.begin(), 10);
906  iret |= compare(B1(0, 0), u[0]);
907  iret |= compare(B1(1, 2), u[6]);
908  iret |= compare(B1(2, 3), 0.0);
909 
910  B1.SetElements(vu.begin(), vu.end());
911  iret |= compare(B1(0, 0), vu[0]);
912  iret |= compare(B1(1, 2), vu[6]);
913  iret |= compare(B1(2, 3), vu[11]);
914 
915  B1.SetElements(vw.begin(), vw.end(), true, true);
916  iret |= compare(B1(0, 0), w[0]);
917  iret |= compare(B1(1, 0), w[1]);
918  iret |= compare(B1(2, 0), w[3]);
919  iret |= compare(B1(2, 2), w[5]);
920 
922  v1.SetElements(vu.begin(), vu.end());
923  for (unsigned int i = 0; i < v1.kSize; ++i) iret |= compare(v1[i], vu[i]);
924 
925  // v1.SetElements(vw.begin(),vw.end() ); // this assert at run-time
926  v1.SetElements(vw.begin(), vw.size());
927  for (unsigned int i = 0; i < vw.size(); ++i) iret |= compare(v1[i], vw[i]);
928 
929  return iret;
930 }
931 
932 int test16()
933 {
934  // test IsInUse() function to create automatically temporaries
935  int iret = 0;
936 
937  double a[6] = {1, 2, 3, 4, 5, 6};
938  double w[9] = {10, 2, 3, 4, 50, 6, 7, 8, 90};
939 
942  // SMatrix<double,3,3,MatRepSym<double,3> > C;
943 
944  B = Transpose(A);
945  A = Transpose(A);
946  iret |= compare(A == B, true, "transp");
947 
948  SMatrix<double, 3> W(w, w + 9);
949  SMatrix<double, 3> Y = W.Inverse(iret);
951  Z = W * Y;
952  Y = W * Y;
953 #ifndef _WIN32
954  // this fails on Windows (bad calculations)
955  iret |= compare(Z == Y, true, "mult");
956 #else
957  for (int i = 0; i < 9; ++i) {
958  // avoid small value of a
959  double a = Z.apply(i);
961  if (a < eps) a = 0;
962  iret |= compare(a, Y.apply(i), "index");
963  }
964 #endif
965 
966  Z = (A + W) * (B + Y);
967  Y = (A + W) * (B + Y);
968 
969  iret |= compare(Z == Y, true, "complex mult");
970 
971  // test of assign sym
972  // AssignSym::Evaluate(A, W * A * Transpose(W) );
973  // AssignSym::Evaluate(B, W * A * Transpose(W) );
974  // iret |= compare( A==B,true,"assignsym");
975 
976  return iret;
977 }
978 
979 int test17()
980 {
981  int iret = 0;
982  // tets tensor product
983  SVector<double, 2> v1(1, 2);
984  SVector<double, 3> v2(1, 2, 3);
985 
987  for (int i = 0; i < m.kRows; ++i)
988  for (int j = 0; j < m.kCols; ++j) iret |= compare(m(i, j), v1(i) * v2(j));
989  // std::cout << "Tensor Product \n" << m << std::endl;
990 
991  SVector<double, 4> a1(2, -1, 3, 4);
992  SVector<double, 4> a2(5, 6, 1, -2);
993 
994  SMatrix<double, 4> A = TensorProd(a1, a2);
995  double r1 = Dot(a1, A * a2);
996  double r2 = Dot(a1, a1) * Dot(a2, a2);
997  iret |= compare(r1, r2, "tensor prod");
998 
999  A = TensorProd(2. * a1, a2);
1000  r1 = Dot(a1, A * a2) / 2;
1001  r2 = Dot(a1, a1) * Dot(a2, a2);
1002  iret |= compare(r1, r2, "tensor prod");
1003 
1004  A = TensorProd(a1, 2 * a2);
1005  r1 = Dot(a1, A * a2) / 2;
1006  r2 = Dot(a1, a1) * Dot(a2, a2);
1007  iret |= compare(r1, r2, "tensor prod");
1008 
1009  A = TensorProd(0.5 * a1, 2 * a2);
1010  r1 = Dot(a1, A * a2);
1011  r2 = Dot(a1, a1) * Dot(a2, a2);
1012  iret |= compare(r1, r2, "tensor prod");
1013 
1014  return iret;
1015 }
1016 
1017 // test inverison of large matrix (double)
1018 int test18()
1019 {
1020  int iret = 0;
1021  // data for a 7x7 sym matrix to invert
1023  for (int i = 0; i < 7; ++i) {
1024  for (int j = 0; j <= i; ++j) {
1025  if (i == j)
1026  S(i, j) = 10 * double(std::rand()) / (RAND_MAX); // generate between 0,10
1027  else
1028  S(i, j) = 2 * double(std::rand()) / (RAND_MAX)-1; // generate between -1,1
1029  }
1030  }
1031  int ifail = 0;
1033  iret |= compare(ifail, 0, "sym7x7 inversion");
1034  SMatrix<double, 7> Id = S * Sinv;
1035 
1036  for (int i = 0; i < 7; ++i)
1037  for (int j = 0; j < 7; ++j)
1038  // The tolerance below is high because matrix inversion leads to large errors.
1039  // The comparisons below eventually fail with any value less than ~10000 ulps.
1040  iret |= compare(Id(i, j), i == j ? 1.0 : 0.0, "sym7x7 inversion result", 50000);
1041 
1042  // now test inversion of general
1044  for (int i = 0; i < 7; ++i) {
1045  for (int j = 0; j < 7; ++j) {
1046  if (i == j)
1047  M(i, j) = 10 * double(std::rand()) / (RAND_MAX); // generate between 0,10
1048  else
1049  M(i, j) = 2 * double(std::rand()) / (RAND_MAX)-1; // generate between -1,1
1050  }
1051  }
1052  ifail = 0;
1053  SMatrix<double, 7> Minv = M.Inverse(ifail);
1054  iret |= compare(ifail, 0, "7x7 inversion");
1055  Id = M * Minv;
1056 
1057  for (int i = 0; i < 7; ++i)
1058  for (int j = 0; j < 7; ++j)
1059  // The tolerance below is high because matrix inversion leads to large errors.
1060  // The comparisons below eventually fail with any value less than ~10000 ulps.
1061  iret |= compare(Id(i, j), i == j ? 1.0 : 0.0, "sym7x7 inversion result", 50000);
1062 
1063  return iret;
1064 }
1065 
1066 // test inversion of large matrices (float)
1067 int test19()
1068 {
1069  int iret = 0;
1070  // data for a 7x7 sym matrix to invert
1072  for (int i = 0; i < 7; ++i) {
1073  for (int j = 0; j <= i; ++j) {
1074  if (i == j)
1075  S(i, j) = 10 * float(std::rand()) / (RAND_MAX); // generate between 0,10
1076  else
1077  S(i, j) = 2 * float(std::rand()) / (RAND_MAX)-1; // generate between -1,1
1078  }
1079  }
1080  int ifail = 0;
1082  iret |= compare(ifail, 0, "sym7x7 inversion");
1083  SMatrix<float, 7> Id = S * Sinv;
1084 
1085  // std::cout << S << "\n" << Sinv << "\n" << Id << "\n";
1086 
1087  for (int i = 0; i < 7; ++i)
1088  for (int j = 0; j < 7; ++j)
1089  // The tolerance below is high because matrix inversion leads to large errors.
1090  // The comparisons below eventually fail with any value less than ~10000 ulps.
1091  iret |= compare(Id(i, j), i == j ? 1.0f : 0.0f, "sym7x7 inversion result", 50000);
1092 
1093  // now test inversion of general
1095  for (int i = 0; i < 7; ++i) {
1096  for (int j = 0; j < 7; ++j) {
1097  if (i == j)
1098  M(i, j) = 10 * float(std::rand()) / (RAND_MAX); // generate between 0,10
1099  else
1100  M(i, j) = 2 * float(std::rand()) / (RAND_MAX)-1; // generate between -1,1
1101  }
1102  }
1103  ifail = 0;
1104  SMatrix<float, 7> Minv = M.Inverse(ifail);
1105  iret |= compare(ifail, 0, "7x7 inversion");
1106  Id = M * Minv;
1107 
1108  // std::cout << M << "\n" << Minv << "\n" << Id << "\n";
1109 
1110  for (int i = 0; i < 7; ++i)
1111  for (int j = 0; j < 7; ++j)
1112  // The tolerance below is high because matrix inversion leads to large errors.
1113  // The comparisons below eventually fail with any value less than ~10000 ulps.
1114  iret |= compare(Id(i, j), i == j ? 1.0f : 0.0f, "sym7x7 inversion result", 50000);
1115 
1116  return iret;
1117 }
1118 
1119 int test20()
1120 {
1121  // test operator += , -=
1122  int iret = 0;
1123  // std::cout.precision(18);
1124 
1125  double d1[6] = {1, 2, 3, 4, 5, 6};
1126  double d2[6] = {1, 2, 5, 3, 4, 6};
1127 
1128  SMatrix<double, 2> m1_0(d1, 4);
1129  SMatrix<double, 2> m2_0(d2, 4);
1130  SMatrix<double, 2> m1 = m1_0;
1131  SMatrix<double, 2> m2 = m2_0;
1132  SMatrix<double, 2> m3;
1133 
1134  m3 = m1 + m2;
1135  m1 += m2;
1136 
1137  if (iret) std::cout << "m1+= m2" << m1 << std::endl;
1138 
1139  iret |= compare(m1 == m3, true);
1140 
1141  m3 = m1 + 3;
1142  m1 += 3;
1143  iret |= compare(m1 == m3, true);
1144  if (iret) std::cout << "m1 + 3\n" << m1 << " \n " << m3 << std::endl;
1145 
1146  m3 = m1 - m2;
1147  m1 -= m2;
1148  iret |= compare(m1 == m3, true);
1149  if (iret) std::cout << "m1-= m2\n" << m1 << " \n " << m3 << std::endl;
1150 
1151  m3 = m1 - 3;
1152  m1 -= 3;
1153  iret |= compare(m1 == m3, true);
1154  if (iret) std::cout << "m1-= 3\n" << m1 << " \n " << m3 << std::endl;
1155 
1156  m3 = m1 * 2;
1157  m1 *= 2;
1158  iret |= compare(m1 == m3, true);
1159  if (iret) std::cout << "m1*= 2\n" << m1 << "\n" << m3 << std::endl;
1160 
1161  // matrix multiplication (*= works only for squared matrix mult.)
1162  m3 = m1 * m2;
1163  m1 *= m2;
1164  iret |= compare(m1 == m3, true);
1165  if (iret) std::cout << "m1*= m2\n" << m1 << " \n " << m3 << std::endl;
1166 
1167  m3 = m1 / 2;
1168  m1 /= 2;
1169  iret |= compare(m1 == m3, true);
1170  if (iret) std::cout << "m1/=2\n" << m1 << " \n " << m3 << std::endl;
1171 
1172  // test mixed with a scalar
1173  double a = 2;
1174  m3 = m2 + a * m1;
1175  m2 += a * m1;
1176  iret |= compare(m2 == m3, true);
1177  if (iret) std::cout << "m2 += a*m1\n" << m2 << "\n " << m3 << std::endl;
1178 
1179  // more complex op (passing expressions)
1180 
1181  m1 = m1_0;
1182  m2 = m2_0;
1183 
1184  m3 = m1 + (m1 * m2);
1185  m1 += m1 * m2;
1186  iret |= compare(m1 == m3, true);
1187  if (iret) std::cout << "m1 += m1*m2\n" << m1 << "\n " << m3 << std::endl;
1188 
1189  m3 = m1 - (m1 * m2);
1190  m1 -= m1 * m2;
1191  iret |= compare(m1 == m3, true);
1192  if (iret) std::cout << "m1 -= m1*m2\n" << m1 << " \n " << m3 << std::endl;
1193 
1194  m3 = m1 * (m1 * m2);
1195  m1 *= m1 * m2;
1196  iret |= compare(m1 == m3, true);
1197  if (iret) std::cout << "m1 *= m1*m2\n" << m1 << "\n " << m3 << std::endl;
1198 
1199  // test operation involving 2 expressions
1200  // (check bug 35076)
1201 
1202  // reset initial matrices to avoid numerical problems
1203  m1 = m1_0;
1204  m2 = m2_0;
1205 
1206  m3 = m1 + m2;
1207  SMatrix<double, 2> m4;
1208  SMatrix<double, 2> m5;
1209  m4 = (m1 * m2) + (m1 * m3);
1210  m5 = m1 * m2;
1211  m5 += m1 * m3;
1212  iret |= compare(m4 == m5, true);
1213  if (iret) std::cout << "m5 = m1*m3\n" << m4 << "\n " << m5 << std::endl;
1214 
1215  m4 = (m1 * m2) - (m1 * m3);
1216  m5 = m1 * m2;
1217  m5 -= m1 * m3;
1218  iret |= compare(m4 == m5, true);
1219  if (iret) std::cout << "m5 -= m1*m3\n" << m4 << "\n " << m5 << std::endl;
1220 
1221  m4 = (m1 + m2) * (m1 - m3);
1222  m5 = m1 + m2;
1223  m5 = m5 * (m1 - m3);
1224  iret |= compare(m4 == m5, true);
1225 
1226  if (iret) std::cout << "m5= m5*(m1-m3) \n" << m4 << " \n " << m5 << std::endl;
1227 
1228  // test with vectors
1229  SVector<double, 4> v1(d1, 4);
1230  SVector<double, 4> v2(d2, 4);
1231  SVector<double, 4> v3;
1232 
1233  v3 = v1 + v2;
1234  v1 += v2;
1235  iret |= compare(v1 == v3, true);
1236 
1237  v3 = v1 + 2;
1238  v1 += 2;
1239  iret |= compare(v1 == v3, true);
1240 
1241  v3 = v1 + (v1 + v2);
1242  v1 += v1 + v2;
1243  iret |= compare(v1 == v3, true);
1244 
1245  v3 = v1 - v2;
1246  v1 -= v2;
1247  iret |= compare(v1 == v3, true);
1248 
1249  v3 = v1 - 2;
1250  v1 -= 2;
1251  iret |= compare(v1 == v3, true);
1252 
1253  v3 = v1 - (v1 + v2);
1254  v1 -= v1 + v2;
1255  iret |= compare(v1 == v3, true);
1256 
1257  v3 = v1 * 2;
1258  v1 *= 2;
1259  iret |= compare(v1 == v3, true);
1260 
1261  v3 = v1 / 2;
1262  v1 /= 2;
1263  iret |= compare(v1 == v3, true);
1264 
1265  // test with symmetric matrices
1266 
1267  // double d1[6]={1,2,3,4,5,6};
1269  SMatrix<double, 3, 3, MatRepSym<double, 3>> ms2(d1, d1 + 6, true, false);
1272 
1273  // using complex expressions
1274  ms3 = ms1 + (ms1 + ms2);
1275  ms1 += ms1 + ms2;
1276  iret |= compare(ms1 == ms3, true);
1277 
1278  ms3 = ms1 - (ms1 + ms2);
1279  ms1 -= ms1 + ms2;
1280  iret |= compare(ms1 == ms3, true);
1281 
1282  a = 2;
1283  ms3 = ms1 + a * ms2;
1284 
1285  ms4 = ms1;
1286  ms4 += a * ms2;
1287 
1288  iret |= compare(ms3 == ms4, true);
1289 
1290  ms3 = ms1 - a * ms2;
1291  ms4 = ms1;
1292  ms4 -= a * ms2;
1293  iret |= compare(ms3 == ms4, true);
1294 
1295  return iret;
1296 }
1297 
1298 int test21()
1299 {
1300 
1301  // test global matrix function (element-wise operations)
1302 
1303  int iret = 0;
1304 
1305  double d1[4] = {4, 6, 3, 4};
1306  double d2[4] = {2, 3, 1, 4};
1307 
1308  SMatrix<double, 2> m1(d1, 4);
1309  SMatrix<double, 2> m2(d2, 4);
1310  SMatrix<double, 2> m3;
1311 
1312  // test element-wise multiplication
1313  m3 = Times(m1, m2);
1314  for (int i = 0; i < 4; ++i) iret |= compare(m3.apply(i), m1.apply(i) * m2.apply(i));
1315 
1316  // matrix division is element-wise division
1317  m3 = Div(m1, m2);
1318  for (int i = 0; i < 4; ++i) iret |= compare(m3.apply(i), m1.apply(i) / m2.apply(i));
1319 
1320  return iret;
1321 }
1322 
1323 int test22()
1324 {
1325 
1326  // test conversion to scalar for size 1 matrix and vectors
1327 
1328  int iret = 0;
1329  SMatrix<double, 1> m1(2);
1330  iret |= compare(m1(0, 0), 2.);
1331 
1332  SVector<double, 1> v1;
1333  v1 = 2;
1334  iret |= compare(m1(0, 0), 2.);
1335 
1336  return iret;
1337 }
1338 
1339 int test23()
1340 {
1341  // test cholesky inversion and solving
1342  int iret = 0;
1343 
1344  double m[] = {100, .15, 2.3, 0.01, .01, 1.};
1346 
1347  // std::cout << "Perform inversion of matrix \n" << smat << std::endl;
1348 
1349  int ifail = 0;
1351  iret |= compare(ifail == 0, true, "inversion");
1352 
1353  // test max deviations from identity for m = imat * smat
1354 
1355  SMatrix<double, 3> mid = imat * smat;
1356  int n = 3;
1357  double prod = 1;
1358  double vmax = 0;
1359  for (int i = 0; i < n; ++i) {
1360  for (int j = 0; j < n; ++j) {
1361  if (i == j)
1362  prod *= mid(i, i);
1363  else {
1364  if (std::abs(mid(i, j)) > vmax) vmax = std::abs(mid(i, j));
1365  }
1366  }
1367  }
1368  iret |= compare(prod, 1., "max dev diagonal");
1369  iret |= compare(vmax, 0., "max dev offdiag ", 10);
1370 
1371  // test now solving of linear system
1372  SVector<double, 3> vec(1, 2, 3);
1373 
1374  SVector<double, 3> x = SolveChol(smat, vec, ifail);
1375 
1376  // std::cout << "linear system solution " << x << std::endl;
1377 
1378  iret |= compare((ifail == 0), true, "solve chol");
1379 
1380  SVector<double, 3> v2 = smat * x;
1381 
1382  for (int i = 0; i < 3; ++i) iret |= compare(v2[i], vec[i], "v2 ==vec");
1383 
1384  return iret;
1385 }
1386 
1387 int test24()
1388 {
1389  // add transpose test
1390  // see bug #65531
1391  double a[9] = {1, -2, 3, 4, -5, 6, -7, 8, 9};
1392  double b[9] = {1, -1, 0, 0, 2, 0, -1, 0, 3};
1393 
1394  SMatrix<double, 3> A(a, a + 9);
1395  SMatrix<double, 3> B(b, b + 9);
1396 
1397  SMatrix<double, 3> R = A * B * Transpose(A);
1398 
1399  SMatrix<double, 3> temp1 = A * B;
1400  SMatrix<double, 3> R1 = temp1 * Transpose(A);
1401 
1402  SMatrix<double, 3> temp2 = B * Transpose(A);
1403  SMatrix<double, 3> R2 = A * temp2;
1404 
1405  int iret = 0;
1406  iret |= compare(R1 == R2, true);
1407  iret |= compare(R == R1, true);
1408  return iret;
1409 }
1410 
1411 int test25()
1412 {
1413  // add test of vector * matrix multiplication with aliasing
1414  // bug #6157
1416  m(0, 0) = 10;
1417  m(0, 1) = 7;
1418  m(0, 2) = 5;
1419  m(1, 1) = 9;
1420  m(1, 2) = 6;
1421  m(2, 2) = 8;
1422 
1423  ROOT::Math::SVector<double, 3> v1(1, 2, 3), v2;
1424 
1425  v2 = m * v1;
1426  v1 = m * v1;
1427 
1428  int iret = 0;
1429  iret |= compare(v1 == v2, true);
1430 
1431  return iret;
1432 }
1433 
1434 #define TEST(N) \
1435  itest = N; \
1436  if (test##N() == 0) \
1437  std::cerr << " Test " << itest << " OK " << std::endl; \
1438  else { \
1439  std::cerr << " Test " << itest << " FAILED " << std::endl; \
1440  iret += 1; \
1441  };
1442 
1444 {
1445 
1446  int iret = 0;
1447  int itest;
1448  TEST(1);
1449  TEST(2);
1450  TEST(3);
1451  TEST(4);
1452  TEST(5);
1453  TEST(6);
1454  TEST(7);
1455  TEST(8);
1456  TEST(9);
1457  TEST(10);
1458  TEST(11);
1459  TEST(12);
1460  TEST(13);
1461  TEST(14);
1462  TEST(15);
1463  TEST(16);
1464  TEST(17);
1465  TEST(18);
1466  TEST(19);
1467  TEST(20);
1468  TEST(21);
1469  TEST(22);
1470  TEST(23);
1471  TEST(24);
1472  TEST(25);
1473 
1474  return iret;
1475 }
1476 
1477 int main()
1478 {
1479  int ret = testSMatrix();
1480  if (ret)
1481  std::cerr << "test SMatrix:\t FAILED !!! " << std::endl;
1482  else
1483  std::cerr << "test SMatrix: \t OK " << std::endl;
1484  return ret;
1485 }
SMatrix< T, D1, D2, R > InverseChol(int &ifail) const
Invert of a symmetric positive defined Matrix using Choleski decomposition.
Definition: SMatrix.icc:446
T Dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Vector dot product.
Definition: Functions.h:164
int test2()
T Similarity(const SMatrix< T, D, D, R > &lhs, const SVector< T, D > &rhs)
Similarity Vector - Matrix Product: v^T * A * v returning a scalar value of type T ...
int test19()
static double B[]
int test7()
void SetDiagonal(const Vector &v)
Set the diagonal elements from a Vector Require that vector implements kSize since a check (staticall...
Definition: SMatrix.icc:764
int test17()
return no. of matrix rows
Definition: SMatrix.h:257
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t mid
Definition: TRolke.cxx:630
int test8()
int main()
int test25()
double T(double x)
Definition: ChebyshevPol.h:34
int test6()
int test24()
T Mag(const SVector< T, D > &rhs)
Vector magnitude (Euclidian norm) Compute : .
Definition: Functions.h:252
int test22()
Expr< BinaryOp< MulOp< T >, SMatrix< T, D, D2, R1 >, SMatrix< T, D, D2, R2 >, T >, T, D, D2, typename AddPolicy< T, D, D2, R1, R2 >::RepType > Times(const SMatrix< T, D, D2, R1 > &lhs, const SMatrix< T, D, D2, R2 > &rhs)
Element by element matrix multiplication C(i,j) = A(i,j)*B(i,j) returning a matrix expression...
Expr< TransposeOp< SMatrix< T, D1, D2, R >, T, D1, D2 >, T, D2, D1, typename TranspPolicy< T, D1, D2, R >::RepType > Transpose(const SMatrix< T, D1, D2, R > &rhs)
Matrix Transpose B(i,j) = A(j,i) returning a matrix expression.
int testSMatrix()
bool Invert()
Invert a square Matrix ( this method changes the current matrix).
Definition: SMatrix.icc:406
bool SolveChol(SMatrix< T, D, D, MatRepSym< T, D > > &mat, SVector< T, D > &vec)
TArc * a
Definition: textangle.C:12
SVector< T, D2 > Row(unsigned int therow) const
return a full Matrix row as a vector (copy the content in a new vector)
Definition: SMatrix.icc:569
return vector size
Definition: SVector.h:172
static double A[]
SubVector SubCol(unsigned int thecol, unsigned int row0=0) const
return a slice of the column as a vector starting at the row value row0 until row0+Dsub.
Definition: SMatrix.icc:722
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
SubVector SubRow(unsigned int therow, unsigned int col0=0) const
return a slice of therow as a vector starting at the colum value col0 until col0+N, where N is the size of the vector (SubVector::kSize ) Condition col0+N <= D2
Definition: SMatrix.icc:706
double sqrt(double)
bool Det(T &det)
determinant of square Matrix via Dfact.
Definition: SMatrix.icc:460
static const double x2[5]
int test13()
Double_t x[n]
Definition: legend1.C:17
SMatrix: a generic fixed size D1 x D2 Matrix class.
int test21()
int test11()
return no. of matrix columns
Definition: SMatrix.h:259
int test23()
int test10()
RooArgSet S(const RooAbsArg &v1)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
const double tol
static double C[]
TRandom2 r(17)
SVector< double, 2 > v
Definition: Dict.h:5
void SetElements(InputIterator begin, InputIterator end)
set vector elements copying the values iterator size must match vector size
Definition: SVector.icc:559
iterator begin()
STL iterator interface.
Definition: SMatrix.icc:664
SubVector Sub(unsigned int row) const
return a subvector of size N starting at the value row where N is the size of the returned vector (Su...
Definition: SVector.icc:608
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
int test14()
SVector< T, D1 > Diagonal() const
return diagonal elements of a matrix as a Vector.
Definition: SMatrix.icc:749
SMatrix< T, D1, D2, R > & Place_in_row(const SVector< T, D > &rhs, unsigned int row, unsigned int col)
place a vector in a Matrix row
Definition: SMatrix.icc:478
TMarker * m
Definition: textangle.C:8
Expr< TensorMulOp< SVector< T, D1 >, SVector< T, D2 > >, T, D1, D2 > TensorProd(const SVector< T, D1 > &lhs, const SVector< T, D2 > &rhs)
Tensor Vector Product : M(i,j) = v(i) * v(j) returning a matrix expression.
int test16()
T Mag2(const SVector< T, D > &rhs)
Vector magnitude square Template to compute .
Definition: Functions.h:229
bool Det2(T &det) const
determinant of square Matrix via Dfact.
Definition: SMatrix.icc:467
SMatrix< T, D1, D2, R > Inverse(int &ifail) const
Invert a square Matrix and returns a new matrix.
Definition: SMatrix.icc:413
REAL epsilon
Definition: triangle.c:617
constexpr Double_t E()
Definition: TMath.h:74
int test1()
Definition: testSMatrix.cxx:59
int test12()
SubMatrix Sub(unsigned int row0, unsigned int col0) const
return a submatrix with the upper left corner at the values (row0, col0) and with sizes N1...
Definition: SMatrix.icc:739
SVector< T, 3 > Cross(const SVector< T, 3 > &lhs, const SVector< T, 3 > &rhs)
Vector Cross Product (only for 3-dim vectors) .
Definition: Functions.h:322
Expr< BinaryOp< DivOp< T >, SMatrix< T, D, D2, R1 >, SMatrix< T, D, D2, R2 >, T >, T, D, D2, typename AddPolicy< T, D, D2, R1, R2 >::RepType > Div(const SMatrix< T, D, D2, R1 > &lhs, const SMatrix< T, D, D2, R2 > &rhs)
Division (element wise) of two matrices of the same dimensions: C(i,j) = A(i,j) / B(i...
double f(double x)
T apply(unsigned int i) const
access the parse tree with the index starting from zero and following the C convention for the order ...
Definition: SMatrix.icc:621
T Trace() const
return the trace of a matrix Sum of the diagonal elements
Definition: SMatrix.icc:778
int type
Definition: TGX11.cxx:120
SVector< T, D > & Place_at(const SVector< T, D2 > &rhs, unsigned int row)
place a sub-vector starting from the given position
Definition: SVector.icc:486
Double_t y[n]
Definition: legend1.C:17
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
int test9()
int test15()
int test5()
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
SMatrix< T, D1, D2, R > & Place_at(const SMatrix< T, D3, D4, R2 > &rhs, unsigned int row, unsigned int col)
place a matrix in this matrix
Definition: SMatrix.icc:546
const T Square(const T &x)
square Template function to compute , for any type T returning a type T
Definition: Functions.h:73
SVector< T, D > Unit(const SVector< T, D > &rhs)
Unit.
Definition: Functions.h:381
int test4()
std::enable_if<!std::is_floating_point< T >::value, int >::type compare(T a, T b, const std::string &s="", int ulps=10)
Definition: testSMatrix.cxx:33
SMatrix< T, D1, D2, R > & Place_in_col(const SVector< T, D > &rhs, unsigned int row, unsigned int col)
place a vector in a Matrix column
Definition: SMatrix.icc:512
float * q
Definition: THbookFile.cxx:87
void SetElements(InputIterator begin, InputIterator end, bool triang=false, bool lower=true)
Set matrix elements with STL iterator interface.
Definition: SMatrix.icc:686
int test3()
SVector< T, D1 *(D2+1)/2 > UpperBlock() const
return the upper Triangular block of the matrices (including the diagonal) as a vector of sizes N = D...
Definition: SMatrix.icc:791
void compare_fail(T a, T b, int ulps, T tolerance, const std::string &what)
Definition: testSMatrix.cxx:21
const Int_t n
Definition: legend1.C:16
int test18()
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28
SVector< T, D1 > Col(unsigned int thecol) const
return a full Matrix column as a vector (copy the content in a new vector)
Definition: SMatrix.icc:584
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
#define TEST(N)
SVector: a generic fixed size Vector class.
int test20()
iterator end()
STL iterator interface.
Definition: SMatrix.icc:669