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