matrix.tests.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           matrix.tests.cpp  -  description
00003                              -------------------
00004     email                : georg.martius@web.de
00005 ***************************************************************************/
00006 // 
00007 // $Log: matrix.tests.cpp,v $
00008 // Revision 1.15  2005/10/21 11:58:25  martius
00009 // map2 (similar to map but for 2 matrices)
00010 // changed naming of functions to be more consistent.
00011 //  Functions with "to" in front indicate the change of this. (Still not consistent with add, mult ...)
00012 //
00013 // Revision 1.14  2005/10/06 17:10:06  martius
00014 // convertToList
00015 // above and toAbove
00016 //
00017 // Revision 1.13  2005/08/06 20:47:36  martius
00018 // Commented
00019 //
00020 // Revision 1.12  2005/06/17 15:18:09  martius
00021 // 2x2 Inversion tested
00022 //
00023 // Revision 1.11  2005/06/10 08:21:50  martius
00024 // mult???wise are copy operations now!
00025 // toMult???wise are inplace instead
00026 //
00027 // Revision 1.10  2005/06/09 11:52:03  martius
00028 // multMT (M * M^T) and multTM (M^T * M)
00029 //
00030 // Revision 1.9  2005/06/02 22:49:33  martius
00031 // speed tests extended
00032 //
00033 // Revision 1.8  2005/06/02 08:49:26  martius
00034 // mult_row/column_wise
00035 //
00036 // Revision 1.7  2005/05/30 22:40:56  martius
00037 // map becomes toMap and the new map returns a new matrix
00038 // exp becomes toExp
00039 //
00040 // Revision 1.6  2005/05/30 21:46:54  martius
00041 // *** empty log message ***
00042 //
00043 // Revision 1.5  2005/05/30 16:43:02  martius
00044 // map function included (component-wise function application)
00045 //
00046 // Revision 1.4  2005/05/30 10:15:47  martius
00047 // proper log entry in header
00048 //
00049 /***************************************************************************/
00050 
00051 // //////////////////////////////////////////////////////////////////////////////
00052 // ////////////////// UNIT TESTS for matrix lib /////////////////////////////////////////////////
00053 
00054 #ifdef UNITTEST
00055 #include "unit_test.h"
00056 using namespace matrix;
00057 
00058 const D EPS=1e-9;
00059 bool comparetoidentity(const Matrix& m)  {
00060   int worstdiagonal = 0;
00061   D maxunitydeviation = 0.0;
00062   D currentunitydeviation;
00063   for ( int i = 0; i < m.getM(); i++ )  {
00064     currentunitydeviation = m.val(i,i) - 1.;
00065     if ( currentunitydeviation < 0.0) currentunitydeviation *= -1.;
00066     if ( currentunitydeviation > maxunitydeviation )  {
00067       maxunitydeviation = currentunitydeviation;
00068       worstdiagonal = i;
00069     }
00070   }
00071   int worstoffdiagonalrow = 0;
00072   int worstoffdiagonalcolumn = 0;
00073   D maxzerodeviation = 0.0;
00074   D currentzerodeviation ;
00075   for ( int i = 0; i < m.getM(); i++ )  {
00076     for ( int j = 0; j < m.getN(); j++ )  {
00077       if ( i == j ) continue;  // we look only at non-diagonal terms
00078       currentzerodeviation = m.val(i,j);
00079       if ( currentzerodeviation < 0.0) currentzerodeviation *= -1.0;
00080       if ( currentzerodeviation > maxzerodeviation )  {
00081         maxzerodeviation = currentzerodeviation;
00082         worstoffdiagonalrow = i;
00083         worstoffdiagonalcolumn = j;
00084       }
00085 
00086     }
00087   }
00088 //   cout << "\tWorst diagonal value deviation from unity: " 
00089 //        << maxunitydeviation << " at row/column " << worstdiagonal << endl;
00090 //   cout << "\tWorst off-diagonal value deviation from zero: " 
00091 //        << maxzerodeviation << " at row = " << worstoffdiagonalrow 
00092 //        << ", column = " << worstoffdiagonalcolumn << endl;
00093   return (maxunitydeviation < EPS && maxzerodeviation < EPS); 
00094 }
00095 
00096 
00097 UNIT_TEST_DEFINES
00098 
00099 DEFINE_TEST( check_creation ) {  
00100   cout << "\n -[ Creation and Access ]-\n";
00101   Matrix M1(3,3);  
00102   D testdata[9]={1,0,0, 0,1,0, 0,0,1};
00103   Matrix M2(3,3);
00104   M2.set(testdata);
00105   M1.toId();
00106   unit_assert( "id=identity_set", M1 == M2 );
00107   D testdata2[12]={1,2,3, 4,5,6, 7,8,9, 10,11,12};
00108   Matrix M3(4,3, testdata2);
00109   unit_assert( "dimension of matrix", M3.getM() == 4 &&  M3.getN() == 3 );
00110   unit_assert( "field check", 
00111                M3.val(0,2) == 3 &&  M3.val(2,1) == 8 &&  M3.val(3,0) == 10 );
00112   Matrix M4(M3);  
00113   unit_assert( "copy constructor", M3 == M4 );
00114   Matrix M5(1,3,testdata2+3);  
00115   unit_assert( "row", M3.row(1) == M5 );
00116 
00117   unit_pass();
00118 }
00119 
00120 DEFINE_TEST( check_vector_operation ) {  
00121   cout << "\n -[ Vector Operations ]-\n";
00122   D testdata[3]={-1,3,2};
00123   const Matrix V1(1,3, testdata);
00124   const Matrix V2(3,1, testdata);  
00125   Matrix V3(V1);  
00126 
00127   V3.toTranspose();
00128   unit_assert( "transpose", V3 == V2 );
00129   V3.toTranspose();
00130   unit_assert( "double transpose", V3 == V1 );
00131   D testdata2[3]={-2,6,4};
00132   Matrix V4(1,3,testdata2);    
00133   V3.add(V1,V1);
00134   unit_assert( "add", V3 == V4 );
00135   D testdata3[3]={1,-3,-2};
00136   Matrix V5(1,3,testdata3);
00137   V4.sub(V1,V3);
00138   unit_assert( "sub", V4 == V5 );
00139 
00140   D testdata4[3]={3,-9,-6};
00141   V5.set(testdata4);
00142   V4.copy(V1);
00143   V4.toMult(-3.0);
00144   unit_assert( "mult with scalar I", V4 == V5 );
00145   V4.mult(V1,-3.0);
00146   unit_assert( "mult with scalar II", V4 == V5 );
00147 
00148   double f = 14;
00149   Matrix V6(1,1,&f);
00150   V3.copy(V1);  
00151   V3.toTranspose();
00152   V4.mult(V1,V3);
00153   unit_assert( "scalarproduct", V4 == V6 );
00154   V4.copy(V1);
00155   unit_assert( "scalarproduct with exp(2)", V4.multMT() == V6 );
00156   V4.mult(V3,V1);
00157   unit_assert( "vector^T*vector=matrix", V4.getM() == 3);
00158   unit_assert( "vector^T*vector=exp(2)", V3.multMT().getM() == 3);
00159     
00160   unit_pass();
00161 }
00162 
00163 DEFINE_TEST( check_matrix_operation ) {  
00164   cout << "\n -[ Matrix Operations ]-\n";
00165   D testdata[6]={1,2,3, 4,5,6 };
00166   const Matrix M1(2,3, testdata);
00167   D testdata2[6]={1,4, 2,5, 3,6 };
00168   const Matrix M2(3,2, testdata2);  
00169   Matrix M3(M1);  
00170 
00171   M3.toTranspose();
00172   unit_assert( "transpose", M3 == M2 );
00173   D testdata3[6]={2,4,6, 8,10,12};
00174   Matrix M4(2,3,testdata3);    
00175   M3.add(M1,M1);
00176   unit_assert( "add", M3 == M4 );
00177 
00178   D testdata4[6]={-0.5, -1, -1.5,  -2, -2.5, -3};
00179   M3.set(testdata4);
00180   M4.copy(M1);
00181   M4.toMult(-0.5);
00182   unit_assert( "mult with scalar", M4 == M3 );
00183 
00184   D testdata5[6] = {2, -1,  0, 3,  2, -2};
00185   D testdata6[4] = {8, -1,  20, -1};
00186   Matrix M5 (3,2, testdata5);
00187   Matrix M6(2,2,testdata6);
00188   M4.mult(M1,M5);
00189   unit_assert( "mult(matrix, matrix)", M4 == M6 );
00190 
00191   M3.copy(M1);  
00192   M4.copy(M1);  
00193   M4.toExp(1);
00194   unit_assert( "exp(1)", M3 == M4 );
00195   M3.toTranspose();
00196   M4.toExp(T);
00197   unit_assert( "exp(T)=transpose", M3 == M4 );
00198   M3.toId();
00199   M4.toExp(0);
00200   unit_assert( "exp(0)=id", M3 == M4 );
00201 
00202   D testdata7[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00203   Matrix M7(4,4,testdata7);
00204   Matrix M8(M7);  
00205   M7.toExp(-1);  
00206   M4.mult(M7,M8);
00207   unit_assert( "exp(-1)*exp(1)=id",   comparetoidentity(M4) );
00208 
00209   D testdata9[6] = {sin(1.0),sin(2.0),sin(3.0), sin(4.0),sin(5.0),sin(6.0) };
00210   Matrix M9(2,3,testdata9);  
00211   M4.copy(M1);
00212   M4.toMap(sin);
00213   unit_assert( "map(sin)",   M4 == M9 );
00214 
00215   D testdata10[6] = {2,4,6, -0.4,-0.5,-0.6 };
00216   D testdata11[2] = {2,-0.1};
00217   Matrix M10(2,3,testdata10);  
00218   Matrix M11(2,1,testdata11);  
00219   M4.copy(M1);
00220   M4.toMultrowwise(M11);
00221   unit_assert( "multrowwise()",   M4 == M10 );
00222   D testdata12[6] = {2,1,0, 8, 2.5, 0 };
00223   D testdata13[3] = {2, 0.5, 0};
00224   M10.set(2,3,testdata12);  
00225   Matrix M12(3,1,testdata13);  
00226   M4.copy(M1);
00227   M4.toMultcolwise(M12);
00228   unit_assert( "multrowwise()",   M4 == M10 );
00229 
00230   M3.copy(M1);  
00231   M4.copy(M1);
00232   M4.toTranspose();
00233   M5 = M3.multMT();
00234   M6.mult(M1,M4);
00235   unit_assert( "multMT() ",   M5 == M6 );
00236   M5 = M3.multTM();
00237   M6.mult(M4,M1);
00238   unit_assert( "multTM() ",   M5 == M6 );
00239 
00240   D testdata20[12]={1,2,3, 4,5,6, 1,2,3, 4,5,6 };
00241   const Matrix M20(4,3, testdata20);
00242   const Matrix M21 = M1.above(M1);
00243   unit_assert( "above() ",   M20 == M21 );
00244   
00245    
00246   
00247   unit_pass();
00248 }
00249 
00250 DEFINE_TEST( check_matrix_operators ) {  
00251   cout << "\n -[ Matrix Operators (+ - * ^)]-\n";
00252   D testdata[6]={1,2,3, 4,5,6 };
00253   const Matrix M1(2,3, testdata);
00254   D testdata2[6]={1,4, 2,5, 3,6 };
00255   const Matrix M2(3,2, testdata2);  
00256   unit_assert( "^T ",  (M1^T) == M2 );
00257   D testdata3[6]={2,4,6, 8,10,12};
00258   Matrix M4(2,3,testdata3);    
00259   unit_assert( "+  ", M1+M1 == M4 );
00260   unit_assert( "-  ", M1+M1-M1 == M1 );
00261 
00262   D testdata4[6]={-0.5, -1, -1.5,  -2, -2.5, -3};
00263   Matrix M3(2,3, testdata4);
00264   unit_assert( "* scalar", M1*(-0.5) == M3 );
00265 
00266   D testdata5[6] = {2, -1,  0, 3,  2, -2};
00267   D testdata6[4] = {8, -1,  20, -1};
00268   Matrix M5 (3,2, testdata5);
00269   Matrix M6(2,2,testdata6);
00270   unit_assert( "*  ", M1*M5 == M6 );
00271 
00272   unit_assert( "^1 ", (M1^1) == M1 );
00273   M3.toId();
00274   unit_assert( "^0=id ", (M1^0) == M3 );
00275 
00276   D testdata7[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00277   Matrix M7(4,4,testdata7);
00278   unit_assert( "^1 * ^-1=id ",   comparetoidentity(M7*(M7^-1)) );
00279   unit_pass();
00280 }
00281 
00282 DEFINE_TEST( speed ) {  
00283   cout << "\n -[ Speed: Inverion]-\n";  
00284 #ifndef NDEBUG
00285   cout << "   DEBUG MODE! use -DNDEBUG -O3 (not -g) to get full performance\n";
00286 #endif
00287   Matrix M1;
00288   srand(time(0));
00289   D testdata0[9] = {1,2, -4,2}; 
00290   Matrix M2(2,2,testdata0);
00291   UNIT_MEASURE_START("2x2 Matrix inversion", 100000)
00292     M1 = (M2^-1);
00293   UNIT_MEASURE_STOP("");
00294   unit_assert( "validation", comparetoidentity(M1*M2));
00295   /* LU version:  555648/s */
00296   /* Explicit  : 1428775/s */
00297   D testdata1[9] = {1,2,3, -4,2,1, 0.3,-0.9}; 
00298   Matrix M3(3,3,testdata1);
00299   UNIT_MEASURE_START("3x3 Matrix inversion", 100000)
00300     M1 = (M3^-1);
00301   UNIT_MEASURE_STOP("");
00302   unit_assert( "validation", comparetoidentity(M1*M3));
00303 
00304   D testdata2[16] = {1,2,3,4, -4,2,1,3, 0.3,-0.9, 4, -3, 1,0.5,0.3,5.0};
00305   Matrix M4(4,4,testdata2);
00306   UNIT_MEASURE_START("4x4 Matrix inversion", 100000)
00307     M1 = (M4^-1);
00308   UNIT_MEASURE_STOP("");
00309   unit_assert( "validation", comparetoidentity(M1*M4));
00310 
00311   Matrix M20(20,20); 
00312   for (int i=0; i < M20.getM(); i++)  // define random values for initial matrix
00313     for (int j=0; j < M20.getN(); j++) {
00314       M20.val(i,j) = -22+(100. * rand())/RAND_MAX;
00315     }
00316   UNIT_MEASURE_START("20x20 Matrix inversion",1000)
00317     M1 = (M20^-1);  
00318   UNIT_MEASURE_STOP("");
00319   unit_assert( "validation", comparetoidentity(M1*M20));
00320 
00321   Matrix M200(200,200); 
00322   rand();  // eliminates the first (= zero) call
00323   for (int i=0; i < M200.getM(); i++)  // define random values for initial matrix
00324     for (int j=0; j < M200.getN(); j++) {
00325       M200.val(i,j) = -22+(100. * rand())/RAND_MAX;
00326     }
00327   UNIT_MEASURE_START("200x200 Matrix inversion",2)
00328     M1 = (M200^-1);  
00329   UNIT_MEASURE_STOP("");
00330   unit_assert( "validation", comparetoidentity(M1*M200));
00331 
00332   cout << "\n -[ Speed: Other Operations]-\n";    
00333   UNIT_MEASURE_START("20x20 Matrix multiplication with assignment",5000)
00334     M1 = M20*M20;  
00335   UNIT_MEASURE_STOP("");
00336   UNIT_MEASURE_START("20x20 Matrix addition with assignment",100000)
00337     M1= (M1 + M20);  
00338   UNIT_MEASURE_STOP("");
00339   UNIT_MEASURE_START("20x20 Matrix inplace addition",100000)
00340     M1 += M20;  
00341   UNIT_MEASURE_STOP("");
00342   UNIT_MEASURE_START("20x20 Matrix transposition",100000)
00343     M1 += M20;  
00344   UNIT_MEASURE_STOP("");
00345 
00346   unit_pass();  
00347 }
00348 
00349 UNIT_TEST_RUN( "Matrix Tests" )
00350   ADD_TEST( check_creation )
00351   ADD_TEST( check_vector_operation )
00352   ADD_TEST( check_matrix_operation )
00353   ADD_TEST( check_matrix_operators )
00354   ADD_TEST( speed )
00355 
00356   UNIT_TEST_END
00357 
00358 #endif // UNITTEST

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5