matrix.tests.hpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           matrix.tests.cpp  -  description
00003                              -------------------
00004     email                : georg.martius@web.de
00005 ***************************************************************************/
00006 // 
00007 // $Log$
00008 // Revision 1.10  2010-10-20 12:52:59  martius
00009 // pseudoinverse uses lambda only on demand
00010 // secure inverse for square matrices added
00011 //
00012 // Revision 1.9  2010/06/03 09:51:44  martius
00013 // added gsl and eigenvector/values stuff
00014 //
00015 // Revision 1.8  2009/02/02 15:21:52  martius
00016 // added pseudoinverse
00017 //
00018 // Revision 1.7  2008/12/22 14:40:47  martius
00019 // added & operator for multrowwise
00020 //
00021 // Revision 1.6  2008/11/14 09:15:29  martius
00022 // tried some autovectorization but without success
00023 // moved some function to CPP file
00024 //
00025 // Revision 1.5  2008/06/18 13:46:20  martius
00026 // beside and toBeside added
00027 // addColumns and addRows is now based on toAbove and toBeside
00028 // bug fix in removeColumns
00029 //
00030 // Revision 1.4  2007/07/17 07:28:06  martius
00031 // store and restore test
00032 //
00033 // Revision 1.3  2006/07/20 17:14:36  martius
00034 // removed std namespace from matrix.h
00035 // storable interface
00036 // abstract model and invertablemodel as superclasses for networks
00037 //
00038 // Revision 1.2  2006/07/14 12:24:01  martius
00039 // selforg becomes HEAD
00040 //
00041 // Revision 1.1.2.1  2006/07/10 12:01:02  martius
00042 // Matrixlib moved to selforg
00043 //
00044 // Revision 1.15  2005/10/21 11:58:25  martius
00045 // map2 (similar to map but for 2 matrices)
00046 // changed naming of functions to be more consistent.
00047 //  Functions with "to" in front indicate the change of this. (Still not consistent with add, mult ...)
00048 //
00049 // Revision 1.14  2005/10/06 17:10:06  martius
00050 // convertToList
00051 // above and toAbove
00052 //
00053 // Revision 1.13  2005/08/06 20:47:36  martius
00054 // Commented
00055 //
00056 // Revision 1.12  2005/06/17 15:18:09  martius
00057 // 2x2 Inversion tested
00058 //
00059 // Revision 1.11  2005/06/10 08:21:50  martius
00060 // mult???wise are copy operations now!
00061 // toMult???wise are inplace instead
00062 //
00063 // Revision 1.10  2005/06/09 11:52:03  martius
00064 // multMT (M * M^T) and multTM (M^T * M)
00065 //
00066 // Revision 1.9  2005/06/02 22:49:33  martius
00067 // speed tests extended
00068 //
00069 // Revision 1.8  2005/06/02 08:49:26  martius
00070 // mult_row/column_wise
00071 //
00072 // Revision 1.7  2005/05/30 22:40:56  martius
00073 // map becomes toMap and the new map returns a new matrix
00074 // exp becomes toExp
00075 //
00076 // Revision 1.6  2005/05/30 21:46:54  martius
00077 // *** empty log message ***
00078 //
00079 // Revision 1.5  2005/05/30 16:43:02  martius
00080 // map function included (component-wise function application)
00081 //
00082 // Revision 1.4  2005/05/30 10:15:47  martius
00083 // proper log entry in header
00084 //
00085 /***************************************************************************/
00086 
00087 // //////////////////////////////////////////////////////////////////////////////
00088 // ////////////////// UNIT TESTS for matrix lib /////////////////////////////////////////////////
00089 
00090 #ifdef UNITTEST
00091 #include "unit_test.hpp"
00092 
00093 #include "matrixutils.h"
00094 
00095 using namespace matrix;
00096 using namespace std;
00097 
00098 const D EPS=1e-9;
00099 bool comparetoidentity(const Matrix& m, double eps = EPS)  {
00100   int worstdiagonal = 0;
00101   D maxunitydeviation = 0.0;
00102   D currentunitydeviation;
00103   for ( unsigned int i = 0; i < m.getM(); i++ )  {
00104     currentunitydeviation = m.val(i,i) - 1.;
00105     if ( currentunitydeviation < 0) currentunitydeviation *= -1.;
00106     if ( currentunitydeviation > maxunitydeviation )  {
00107       maxunitydeviation = currentunitydeviation;
00108       worstdiagonal = i;
00109     }
00110   }
00111   int worstoffdiagonalrow = 0;
00112   int worstoffdiagonalcolumn = 0;
00113   D maxzerodeviation = 0.0;
00114   D currentzerodeviation ;
00115   for ( unsigned int i = 0; i < m.getM(); i++ )  {
00116     for ( unsigned int j = 0; j < m.getN(); j++ )  {
00117       if ( i == j ) continue;  // we look only at non-diagonal terms
00118       currentzerodeviation = m.val(i,j);
00119       if ( currentzerodeviation < 0) currentzerodeviation *= -1.0;
00120       if ( currentzerodeviation > maxzerodeviation )  {
00121         maxzerodeviation = currentzerodeviation;
00122         worstoffdiagonalrow = i;
00123         worstoffdiagonalcolumn = j;
00124       }
00125 
00126     }
00127   }
00128 //   cout << "\tWorst diagonal value deviation from unity: " 
00129 //        << maxunitydeviation << " at row/column " << worstdiagonal << endl;
00130 //   cout << "\tWorst off-diagonal value deviation from zero: " 
00131 //        << maxzerodeviation << " at row = " << worstoffdiagonalrow 
00132 //        << ", column = " << worstoffdiagonalcolumn << endl;
00133   return (maxunitydeviation < eps && maxzerodeviation < eps); 
00134 }
00135 
00136 bool comparetozero(const Matrix& m, double eps = EPS)  {
00137   D maxdeviation = 0.0;
00138   D currentdeviation;
00139   for ( unsigned int i = 0; i < m.getM(); i++ )  {
00140     for ( unsigned int j = 0; j < m.getN(); j++ )  {
00141       currentdeviation = m.val(i,j);
00142       if ( currentdeviation < 0.0) currentdeviation *= -1.;
00143       if ( currentdeviation > maxdeviation )  {
00144         maxdeviation = currentdeviation;
00145       }
00146     }
00147   }
00148   if(maxdeviation < eps) 
00149     return true;
00150   else {
00151     cout << "\tWorst deviation: " << maxdeviation << endl;
00152     return false;
00153   }
00154 }
00155 
00156 
00157 UNIT_TEST_DEFINES
00158 
00159 DEFINE_TEST( check_creation ) {  
00160   cout << "\n -[ Creation and Access ]-\n";
00161   Matrix M1(3,3);  
00162   D testdata[9]={1,0,0, 0,1,0, 0,0,1};
00163   Matrix M2(3,3);
00164   M2.set(testdata);
00165   M1.toId();
00166   unit_assert( "id=identity_set", M1 == M2 );
00167   D testdata2[12]={1,2,3, 4,5,6, 7,8,9, 10,11,12};
00168   Matrix M3(4,3, testdata2);
00169   unit_assert( "dimension of matrix", M3.getM() == 4 &&  M3.getN() == 3 );
00170   unit_assert( "field check", 
00171                M3.val(0,2) == 3 &&  M3.val(2,1) == 8 &&  M3.val(3,0) == 10 );
00172   Matrix M4(M3);  
00173   unit_assert( "copy constructor", M3 == M4 );
00174   Matrix M5(1,3,testdata2+3);  
00175   unit_assert( "row", M3.row(1) == M5 );
00176 
00177   unit_pass();
00178 }
00179 
00180 DEFINE_TEST( check_vector_operation ) {  
00181   cout << "\n -[ Vector Operations ]-\n";
00182   D testdata[3]={-1,3,2};
00183   const Matrix V1(1,3, testdata);
00184   const Matrix V2(3,1, testdata);  
00185   Matrix V3(V1);  
00186 
00187   V3.toTranspose();
00188   unit_assert( "transpose", V3 == V2 );
00189   V3.toTranspose();
00190   unit_assert( "double transpose", V3 == V1 );
00191   D testdata2[3]={-2,6,4};
00192   Matrix V4(1,3,testdata2);    
00193   V3.add(V1,V1);
00194   unit_assert( "add", V3 == V4 );
00195   D testdata3[3]={1,-3,-2};
00196   Matrix V5(1,3,testdata3);
00197   V4.sub(V1,V3);
00198   unit_assert( "sub", V4 == V5 );
00199 
00200   D testdata4[3]={3,-9,-6};
00201   V5.set(testdata4);
00202   V4.copy(V1);
00203   V4.toMult(-3.0);
00204   unit_assert( "mult with scalar I", V4 == V5 );
00205   V4.mult(V1,-3.0);
00206   unit_assert( "mult with scalar II", V4 == V5 );
00207 
00208   double f = 14;
00209   Matrix V6(1,1,&f);
00210   V3.copy(V1);  
00211   V3.toTranspose();
00212   V4.mult(V1,V3);
00213   unit_assert( "scalarproduct", V4 == V6 );
00214   V4.copy(V1);
00215   unit_assert( "scalarproduct with exp(2)", V4.multMT() == V6 );
00216   V4.mult(V3,V1);
00217   unit_assert( "vector^T*vector=matrix", V4.getM() == 3);
00218   unit_assert( "vector^T*vector=exp(2)", V3.multMT().getM() == 3);
00219     
00220   unit_pass();
00221 }
00222 
00223 DEFINE_TEST( check_matrix_operation ) {  
00224   cout << "\n -[ Matrix Operations ]-\n";
00225   D testdata[6]={1,2,3, 4,5,6 };
00226   const Matrix M1(2,3, testdata);
00227   D testdata2[6]={1,4, 2,5, 3,6 };
00228   const Matrix M2(3,2, testdata2);  
00229   Matrix M3(M1);  
00230 
00231   M3.toTranspose();
00232   unit_assert( "transpose", M3 == M2 );
00233   D testdata3[6]={2,4,6, 8,10,12};
00234   Matrix M4(2,3,testdata3);    
00235   M3.add(M1,M1);
00236   unit_assert( "add", M3 == M4 );
00237 
00238   D testdata4[6]={-0.5, -1, -1.5,  -2, -2.5, -3};
00239   M3.set(testdata4);
00240   M4.copy(M1);
00241   M4.toMult(-0.5);
00242   unit_assert( "mult with scalar", M4 == M3 );
00243 
00244   D testdata5[6] = {2, -1,  0, 3,  2, -2};
00245   D testdata6[4] = {8, -1,  20, -1};
00246   Matrix M5 (3,2, testdata5);
00247   Matrix M6(2,2,testdata6);
00248   M4.mult(M1,M5);
00249   unit_assert( "mult(matrix, matrix)", M4 == M6 );
00250 
00251   M3.copy(M1);  
00252   M4.copy(M1);  
00253   M4.toExp(1);
00254   unit_assert( "exp(1)", M3 == M4 );
00255   M3.toTranspose();
00256   M4.toExp(T);
00257   unit_assert( "exp(T)=transpose", M3 == M4 );
00258   M3.toId();
00259   M4.toExp(0);
00260   unit_assert( "exp(0)=id", M3 == M4 );
00261 
00262   D testdata7[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00263   Matrix M7(4,4,testdata7);
00264   Matrix M8(M7);  
00265   M7.toExp(-1);  
00266   M4.mult(M7,M8);
00267   unit_assert( "exp(-1)*exp(1)=id",   comparetoidentity(M4) );
00268   M7=M8.pseudoInverse(0);
00269   M4.mult(M7,M8);
00270   unit_assert( "pseudoinverse*exp(1)=id",   comparetoidentity(M4) );
00271 
00272   D testdata9[6] = {sin(1.0),sin(2.0),sin(3.0), sin(4.0),sin(5.0),sin(6.0) };
00273   Matrix M9(2,3,testdata9);  
00274   M4.copy(M1);
00275   M4.toMap(sin);
00276   unit_assert( "map(sin)",   M4 == M9 );
00277 
00278   D testdata10[6] = {2,4,6, -0.4,-0.5,-0.6 };
00279   D testdata11[2] = {2,-0.1};
00280   Matrix M10(2,3,testdata10);  
00281   Matrix M11(2,1,testdata11);  
00282   M4.copy(M1);
00283   M4.toMultrowwise(M11);
00284   unit_assert( "multrowwise()",   M4 == M10 );
00285   M4 = M1 & M11;
00286   unit_assert( "rowwise (&)  ",   M4 == M10 );
00287   D testdata12[6] = {2,1,0, 8, 2.5, 0 };
00288   D testdata13[3] = {2, 0.5, 0};
00289   M10.set(2,3,testdata12);  
00290   Matrix M12(3,1,testdata13);  
00291   M4.copy(M1);
00292   M4.toMultcolwise(M12);
00293   unit_assert( "multcolwise()",   M4 == M10 );
00294 
00295   M3.copy(M1);  
00296   M4.copy(M1);
00297   M4.toTranspose();
00298   M5 = M3.multMT();
00299   M6.mult(M1,M4);
00300   unit_assert( "multMT() ",   M5 == M6 );
00301   M5 = M3.multTM();
00302   M6.mult(M4,M1);
00303   unit_assert( "multTM() ",   M5 == M6 );
00304 
00305   D testdata20[12]={1,2,3, 4,5,6, 1,2,3, 4,5,6 };
00306   const Matrix M20(4,3, testdata20);
00307   const Matrix M21 = M1.above(M1);
00308   unit_assert( "above() ",   M20 == M21 );
00309   D testdata22[8]={1,2,3, 7, 4,5,6, 8};
00310   D testdata23[2]={7, 8};
00311   const Matrix M22(2,4, testdata22);
00312   const Matrix M23(2,1, testdata23);
00313   const Matrix M24 = M1.beside(M23);
00314   unit_assert( "beside() ",   M24 == M22 );
00315 
00316   Matrix M30 = M24;
00317   const Matrix M31 = M30.removeColumns(1);
00318   unit_assert( "removeColumns() ",   M31 == M1 );
00319   Matrix M32 = M20;  
00320   const Matrix M33 = M32.removeRows(2);
00321   unit_assert( "removeRows() ",  M33 == M1 );
00322    
00323   unit_pass();
00324 }
00325 
00326 DEFINE_TEST( check_matrix_operators ) {  
00327   cout << "\n -[ Matrix Operators (+ - * ^)]-\n";
00328   D testdata[6]={1,2,3, 4,5,6 };
00329   const Matrix M1(2,3, testdata);
00330   D testdata2[6]={1,4, 2,5, 3,6 };
00331   const Matrix M2(3,2, testdata2);  
00332   unit_assert( "^T ",  (M1^T) == M2 );
00333   D testdata3[6]={2,4,6, 8,10,12};
00334   Matrix M4(2,3,testdata3);    
00335   unit_assert( "+  ", M1+M1 == M4 );
00336   unit_assert( "-  ", M1+M1-M1 == M1 );
00337 
00338   D testdata4[6]={-0.5, -1, -1.5,  -2, -2.5, -3};
00339   Matrix M3(2,3, testdata4);
00340   unit_assert( "* scalar", M1*(-0.5) == M3 );
00341 
00342   D testdata5[6] = {2, -1,  0, 3,  2, -2};
00343   D testdata6[4] = {8, -1,  20, -1};
00344   Matrix M5 (3,2, testdata5);
00345   Matrix M6(2,2,testdata6);
00346   unit_assert( "*  ", M1*M5 == M6 );
00347 
00348   unit_assert( "^1 ", (M1^1) == M1 );
00349   M3.toId();
00350   unit_assert( "^0=id ", (M1^0) == M3 );
00351 
00352   D testdata7[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00353   Matrix M7(4,4,testdata7);
00354   unit_assert( "^1 * ^-1=id ",   comparetoidentity(M7*(M7^-1)) );
00355   unit_pass();
00356 }
00357 
00358 DEFINE_TEST( check_matrix_utils ) {  
00359   cout << "\n -[ Matrix Utils: Eigenvalues and Eigenvectors ]-\n";
00360   D testdata[9]={1,2,3, 4,5,6, 7,8,9};
00361   const Matrix M1(3,3, testdata);
00362   const Matrix SymM1 = M1.multMT();
00363   Matrix eval, evec;
00364   eval = eigenValuesRealSym(SymM1);
00365   D resultval[3]={1.5*(95+sqrt(8881)), 1.5*(95-sqrt(8881)), 0};
00366   const Matrix resultvalM(3,1, resultval);  
00367   //cout << (eval^T) << "\n" << (resultvalM^T) << "   \n";
00368   unit_assert( "Sym Real Eigenvalues ", comparetozero(eval-resultvalM));
00369   eigenValuesVectorsRealSym(SymM1, eval, evec);
00370   D resultvecs[9]={0.21483723836839594,0.8872306883463704,0.4082482904638631,
00371                    0.5205873894647369,0.24964395298829792,-0.816496580927726,
00372                    0.826337540561078,-0.3879427823697746,0.4082482904638631};
00373   const Matrix resultvecsM(3,3, resultvecs);  
00374   //  cout << (evec) << "\n";
00375   //  cout << resultvecsM << "\n";
00376   unit_assert( "Sym Real Eigenvalues and Vectors: Vals", comparetozero(eval-resultvalM));
00377   unit_assert( "Sym Real Eigenvalues and Vectors: Vectors", comparetozero(evec-resultvecsM)); 
00378   // useing vandermonde matrix with (-1, -2, 3, 4), results taken from mathematica
00379   D testdata2[16]={-1., 1., -1., 1., -8., 4., -2., 1., 27., 9., 3., 1., 64., 16., 4., 1.};
00380   const Matrix M2(4,4, testdata2);
00381   Matrix eval_r, eval_i;
00382   eigenValues(M2, eval_r, eval_i);
00383   D resultval_r[4]={-6.413911026270929,5.5455534989094595,5.5455534989094595,
00384    2.3228040284520177};
00385   D resultval_i[4]={0,3.0854497586289216,-3.0854497586289216,0};
00386   const Matrix resultvalM_r(4,1, resultval_r);  
00387   const Matrix resultvalM_i(4,1, resultval_i);  
00388   //cout << (eval^T) << "\n" << (resultvalM^T) << "   \n";
00389   unit_assert( "NonSym Eigenvalues (Complex) ", comparetozero(eval_r-resultvalM_r) 
00390                && comparetozero(eval_i-resultvalM_i));
00391   Matrix evec_r, evec_i;
00392   eigenValuesVectors(M2, eval_r, eval_i, evec_r, evec_i);
00393   D resultvecs_r[16]={
00394     -0.09988217466836526,-0.043500372394264235,-0.043500372394264235, -0.14493294424802267,
00395     -0.11125130967436689,0.06398640593013502, 0.06398640593013502,0.35660144308731107,
00396     0.2925006732813017, -0.5151803514845115,-0.5151803514845115,0.9193688436883699,
00397    0.9445051897206503,-0.8405935042246232,-0.8405935042246232, 0.0811836295983173};
00398   D resultvecs_i[16]={
00399     0,-0.007553928841000267,0.007553928841000267,0,
00400     0,-0.1422404507165189, 0.1422404507165189,0,
00401     0,0.04142240814335418,-0.04142240814335418,0,
00402     0,0.,0.,0};
00403   const Matrix resultvecsM_r(4,4, resultvecs_r);  
00404   const Matrix resultvecsM_i(4,4, resultvecs_i);  
00405 //   cout << (evec_r) << "\n\n";
00406 //   cout << resultvecsM_r << "\n\n";
00407 //   cout << (evec_i) << "\n\n";
00408 //   cout << resultvecsM_i << "\n\n";
00409   unit_assert( "NonSym Eigenvalues and Vectors: Vals",  
00410                comparetozero(eval_r-resultvalM_r) && comparetozero(eval_i-resultvalM_i) );
00411   unit_assert( "NonSym Eigenvalues and Vectors: Vectors", 
00412                comparetozero(evec_r-resultvecsM_r, 0.001) && 
00413                comparetozero(evec_i-resultvecsM_i, 0.002)); 
00414   
00415   unit_pass();
00416 }
00417 
00418 DEFINE_TEST( speed ) {  
00419   cout << "\n -[ Speed: Inverion ]-\n";  
00420 #ifndef NDEBUG
00421   cout << "   DEBUG MODE! use -DNDEBUG -O3 (not -g) to get full performance\n";
00422 #endif
00423   Matrix M1;
00424   srand(time(0));
00425   D testdata0[9] = {1,2, -4,2}; 
00426   Matrix M2(2,2,testdata0);
00427   UNIT_MEASURE_START("2x2 Matrix inversion", 100000)
00428     M1 = (M2^-1);
00429   UNIT_MEASURE_STOP("");
00430   unit_assert( "validation", comparetoidentity(M1*M2));
00431   /* LU version:  555648/s */
00432   /* Explicit  : 1428775/s */
00433   D testdata1[9] = {1,2,3, -4,2,1, 0.3,-0.9}; 
00434   Matrix M3(3,3,testdata1);
00435   UNIT_MEASURE_START("3x3 Matrix inversion", 100000)
00436     M1 = (M3^-1);
00437   UNIT_MEASURE_STOP("");
00438   unit_assert( "validation", comparetoidentity(M1*M3));
00439 
00440   D testdata2[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00441   Matrix M4(4,4,testdata2);
00442   UNIT_MEASURE_START("4x4 Matrix inversion", 100000)
00443     M1 = (M4^-1);
00444   UNIT_MEASURE_STOP("");
00445   unit_assert( "validation", comparetoidentity(M1*M4));
00446 
00447   Matrix M20(20,20); 
00448   for (unsigned int i=0; i < M20.getM(); i++)  // define random values for initial matrix
00449     for (unsigned int j=0; j < M20.getN(); j++) {
00450       M20.val(i,j) = -22+(100. * rand())/RAND_MAX;
00451     }
00452   UNIT_MEASURE_START("20x20 Matrix inversion",1000)
00453     M1 = (M20^-1);  
00454   UNIT_MEASURE_STOP("");
00455   unit_assert( "validation", comparetoidentity(M1*M20));
00456 
00457   Matrix M200(200,200); 
00458   rand();  // eliminates the first (= zero) call
00459   for (unsigned int i=0; i < M200.getM(); i++)  // define random values for initial matrix
00460     for (unsigned int j=0; j < M200.getN(); j++) {
00461       M200.val(i,j) = -22+(100. * rand())/RAND_MAX;
00462     }
00463   UNIT_MEASURE_START("200x200 Matrix inversion",2)
00464     M1 = (M200^-1);  
00465   UNIT_MEASURE_STOP("");
00466   unit_assert( "validation", comparetoidentity(M1*M200));
00467 
00468   cout << "\n -[ Speed: Other Operations ]-\n";    
00469   UNIT_MEASURE_START("20x20 Matrix multiplication with assignment",5000)
00470     M1 = M20*M20;  
00471   UNIT_MEASURE_STOP("");
00472   UNIT_MEASURE_START("20x20 Matrix addition with assignment",100000)
00473     M1= (M1 + M20);  
00474   UNIT_MEASURE_STOP("");
00475   UNIT_MEASURE_START("20x20 Matrix inplace addition",100000)
00476     M1 += M20;  
00477   UNIT_MEASURE_STOP("");
00478   UNIT_MEASURE_START("20x20 Matrix transposition",100000)
00479     M1 += M20;  
00480   UNIT_MEASURE_STOP("");
00481   const Matrix& M20Sym = M20.multMT();
00482   UNIT_MEASURE_START("20x20 Matrix Sym Real Eigenvalues",1000)
00483   Matrix eval, evec;
00484   eigenValuesVectorsRealSym(M20Sym, eval, evec);  
00485   UNIT_MEASURE_STOP("");
00486 
00487 
00488   unit_pass();  
00489 }
00490 
00491 
00492 DEFINE_TEST( store_restore ) {  
00493   cout << "\n -[ Store and Restore ]-\n";  
00494   Matrix M1(32,1);
00495   for(int i =0; i<32; i++){
00496     M1.val(0,0) = (double)rand()/RAND_MAX;
00497   }
00498   Matrix M2(32,2);
00499   for(int i =0; i<64; i++){
00500     M2.val(i%32,i/32) = (double)rand()/RAND_MAX;
00501   }
00502   FILE* f;
00503   f=fopen("test.dat","wb");
00504   M1.store(f);
00505   M2.store(f);
00506   fclose(f);
00507   f=fopen("test.dat","rb");  
00508   Matrix M3,M4;
00509   M3.restore(f); 
00510   M4.restore(f); 
00511   fclose(f);  
00512   unit_assert( "validation", (M1-M3).map(fabs).elementSum()==0);
00513   unit_assert( "validation", (M2-M4).map(fabs).elementSum()==0);
00514 
00515   unit_pass();  
00516 }
00517 
00518 
00519 /// clipping function for mapP
00520 double clip(double r,double x){  
00521   if(!isnormal(x)) return 0;
00522   return x < -r ? -r : (x>r ? r : x); 
00523 }
00524 
00525 //TODO test secure inverses
00526 DEFINE_TEST( invertzero ) {  
00527   cout << "\n -[ Inverion of Singular Matrices ]-\n";  
00528   Matrix M1;
00529   srand(time(0));
00530   D testdata0[9] = {1.0,0.0, 0.0,0.0}; 
00531   Matrix M2(2,2,testdata0);
00532   M1 = M2.secureInverse();
00533   cout << M1*M2 <<endl;
00534   unit_assert( "2x2 validation", 1 ); // comparetoidentity(M1*M2,0.001));
00535 
00536   D testdata1[9] = {1,2,3, 1,2,3, 0.3,-0.9,.2}; 
00537   Matrix M3(3,3,testdata1);
00538   M1 = (M3.secureInverse());
00539   unit_assert( "3x3 validation",  1 ); //comparetoidentity(M1*M3,0.001));
00540   cout << M3*M1 << endl;
00541 
00542   D testdata2[16] = {1,2,3,4, 1,2,3,4, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00543   Matrix M4(4,4,testdata2);
00544   M1 = M4.secureInverse();
00545   unit_assert( "4x4 validation",  1 ); //comparetoidentity(M1*M4,0.001));
00546   cout << M4*M1 << endl;
00547   
00548   D testdata3[16] = {1,2,3,4, 1,0,3,4, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00549   Matrix M5(4,4,testdata3);
00550   M1 = M5.secureInverse();
00551   unit_assert( "4x4 validation",  1 ); //comparetoidentity(M1*M5,0.001));
00552   cout << M1*M5 << endl;
00553   unit_pass();  
00554 
00555 }
00556 
00557 UNIT_TEST_RUN( "Matrix Tests" )
00558   ADD_TEST( check_creation )
00559   ADD_TEST( check_vector_operation )
00560   ADD_TEST( check_matrix_operation )
00561   ADD_TEST( check_matrix_operators )
00562   ADD_TEST( check_matrix_utils )
00563   ADD_TEST( speed )
00564   ADD_TEST( store_restore )
00565   ADD_TEST( invertzero )
00566 
00567   UNIT_TEST_END
00568 
00569 #endif // UNITTEST
Generated on Thu Jun 28 14:45:36 2012 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.6.3