Basic Image AlgorithmS Library 2.8.0

TestMatrixVectorIO.cpp

00001 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
00002 
00003    Copyright (C) 2003-2009    (see file CONTACT for details)
00004    Multimediale Systeme der Informationsverarbeitung
00005    Institut fuer Informatik
00006    Christian-Albrechts-Universitaet Kiel
00007    
00008    
00009    BIAS is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU Lesser General Public License as published by
00011    the Free Software Foundation; either version 2.1 of the License, or
00012    (at your option) any later version.
00013    
00014    BIAS is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU Lesser General Public License for more details.
00018    
00019    You should have received a copy of the GNU Lesser General Public License
00020    along with BIAS; if not, write to the Free Software
00021    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/
00022 
00023 
00024 
00025 
00026 /** 
00027     @test TestMatrixVectorIO.cpp
00028     @brief Test Matrix I/O precision issues.    
00029     @ingroup g_tests
00030     @author evers
00031 */
00032 
00033 // one file used for I/O
00034 #ifdef WIN32
00035 #  define TMP "tmp.txt"
00036 #else //WIN32
00037 #  define TMP "/tmp/tmp.txt"
00038 #endif //WIN32
00039 
00040 #include <stdlib.h> // srand
00041 #include <string>
00042 #include <limits>
00043 
00044 #include <Base/Math/Vector2.hh>
00045 #include <Base/Math/Vector3.hh>
00046 #include <Base/Math/Vector4.hh>
00047 #include <Base/Math/RGB.hh>
00048 #include <Base/Math/RGBA.hh>
00049 
00050 #include <Base/Math/Matrix2x2.hh>
00051 #include <Base/Math/Matrix3x3.hh>
00052 #include <Base/Math/Matrix3x4.hh>
00053 #include <Base/Math/Matrix4x4.hh>
00054 
00055 
00056 
00057 using namespace std;
00058 using namespace BIAS;
00059 
00060 
00061 // helper 
00062 #define DISPVAL(_ARG) {string s(#_ARG); std::cout<<s<<" "<<endl<<_ARG<<endl;}
00063 
00064 
00065 int g_result (0);  //< global result
00066 int g_samples(20); //< gloabl nr. of random samples (default)
00067 
00068 
00069 // random value [0..1]
00070 double rand1(){
00071   return ((double)rand() / (double)RAND_MAX);
00072 }
00073 
00074 
00075 // typed random function inside values range
00076 template <class T>
00077 T myrand()
00078 {
00079   T val = (T) ( rand1() * numeric_limits<T>::max());
00080   return val;
00081 }
00082 
00083 
00084 void checkRGBuc()
00085 {
00086   cout<<FUNCNAME<<" ";
00087   // check disk I/O
00088   for (unsigned int i=0; (int)i<(int)g_samples; i++){
00089     RGBuc a(myrand<unsigned char>(), myrand<unsigned char>(), myrand<unsigned char>()), b;
00090     a.Save(TMP);
00091     b.Load(TMP);
00092     if (!(a==b)){
00093       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i<<"/"<<g_samples<<" with "<<endl
00094         <<"\ta="<<a<<endl
00095         <<"\tb="<<b );
00096       g_result=-1;
00097       return;
00098     }
00099   }
00100   cout<<" + OK"<<endl;
00101 }
00102 
00103 
00104 void checkRGBAuc()
00105 {
00106   cout<<FUNCNAME<<" ";
00107   // check disk I/O
00108   for (unsigned int i=0; (int)i<(int)g_samples; i++){
00109     RGBAuc a(myrand<unsigned char>(), myrand<unsigned char>(), myrand<unsigned char>(), myrand<unsigned char>()), b;
00110     a.Save(TMP);
00111     b.Load(TMP);
00112     if (!(a==b)){
00113       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i<<"/"<<g_samples<<" with "<<endl
00114         <<"\ta="<<a<<endl
00115         <<"\tb="<<b );
00116       g_result=-1;
00117       return;
00118     }
00119   }
00120   cout<<" + OK"<<endl;
00121 }
00122 
00123 
00124 void checkRGBAf()
00125 {
00126   cout<<FUNCNAME<<" ";
00127   // check disk I/O
00128   for (unsigned int i=0; (int)i<(int)g_samples; i++){
00129     RGBAf a(myrand<float>(), myrand<float>(), myrand<float>(), myrand<float>()), b;
00130     a.Save(TMP);
00131     b.Load(TMP);
00132     if (!(a==b)){
00133       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i<<"/"<<g_samples<<" with "<<endl
00134         <<"\ta="<<a<<endl
00135         <<"\tb="<<b );
00136       g_result=-1;
00137       return;
00138     }
00139   }
00140   cout<<" + OK"<<endl;
00141 }
00142 
00143 
00144 void checkRGBf()
00145 {
00146   cout<<FUNCNAME<<" ";
00147   // check disk I/O
00148   for (unsigned int i=0; (int)i<(int)g_samples; i++){
00149     RGBf a(myrand<float>(), myrand<float>(), myrand<float>()), b;
00150     a.Save(TMP);
00151     b.Load(TMP);
00152     if (!(a==b)){
00153       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i<<"/"<<g_samples<<" with "<<endl
00154         <<"\ta="<<a<<endl
00155         <<"\tb="<<b );
00156       g_result=-1;
00157       return;
00158     }
00159   }
00160   cout<<" + OK"<<endl;
00161 }
00162 
00163 
00164 template <class TYPE, class T>
00165 void display(const unsigned int samples=1)
00166 {
00167 
00168 #ifdef WIN32
00169   cout
00170     <<FUNCNAME<<" "
00171     <<"TYPE="<<typeid(TYPE).name()<<" "
00172     <<"T="<<typeid(T).name()<<" "<<endl;
00173 #else
00174   cout<<FUNCNAME<<" "<<endl;
00175 #endif
00176 
00177   TYPE a;
00178   a.SetZero();
00179   for (unsigned int jj=0; (int)jj<(int)a.GetNumElements(); jj++){
00180     if (jj==0)
00181       a.GetData()[jj]=numeric_limits<T>::min();
00182     else if (jj==1)
00183       a.GetData()[jj]=numeric_limits<T>::max();
00184     else if (jj==2)
00185       a.GetData()[jj]=(T)0;
00186     else
00187       a.GetData()[jj]=myrand<T>();
00188   }
00189   cout<<a<<endl;
00190 }
00191 
00192 
00193 // For fixed size matrix, vector, i.e. Vector3<> Matrix3x3<> etc.
00194 template <class TYPE, class T>
00195 void check(const unsigned int samples=1)
00196 {
00197 
00198 #ifdef WIN32
00199   cout
00200     <<FUNCNAME<<" "
00201     <<"TYPE="<<typeid(TYPE).name()<<" "
00202     <<"T="<<typeid(T).name()<<" ";
00203 #else
00204   cout<<FUNCNAME<<" ";
00205 #endif
00206 
00207   // check disk I/O
00208   for (unsigned int i=0; i<samples; i++)
00209   {
00210     TYPE a, b;
00211     for (unsigned int jj=0; (int)jj<(int)a.GetNumElements(); jj++)
00212       a.GetData()[jj]=myrand<T>();
00213 
00214     b.SetZero();
00215     a.Save(TMP);
00216     b.Load(TMP);
00217     if (!(a==b)){
00218       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i+1<<"/"<<samples<<" with "<<endl
00219         <<"a="<<a<<endl
00220         <<"b="<<b<<endl
00221         <<"delta:"<<a-b<<endl
00222         );
00223       cout<<a<<endl; // DBG
00224       g_result=-1;
00225       return;
00226     }
00227   }
00228   cout<<"+ OK"<<endl;
00229   // example display to check formatting
00230   display<TYPE, T>();
00231 }
00232 
00233 
00234 // For arbitrary sized Matrix<>
00235 // copy of the above with additional 2D dimension
00236 template <class TYPE, class T>
00237 void checkWithDim2(const unsigned int dim, const unsigned int samples)
00238 {
00239 
00240 #ifdef WIN32
00241   cout
00242     <<FUNCNAME<<" "
00243     <<"TYPE="<<typeid(TYPE).name()<<" "
00244     <<"T="<<typeid(T).name()<<" "
00245     <<"dim="<<dim<<" ";
00246 #else
00247   CALLINFO;
00248 #endif
00249 
00250   // check disk I/O
00251   for (unsigned int i=0; i<samples; i++)
00252   {
00253     TYPE a, b;
00254     a.newsize(dim, dim+1);
00255     for (unsigned int jj=0; (int)jj<(int)a.GetNumElements(); jj++)
00256       a.GetData()[jj]=myrand<T>();
00257     b.clear();
00258     a.Save(TMP);
00259     b.Load(TMP);
00260     if (!(a==b)){
00261       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i+1<<"/"<<samples<<" with "<<endl
00262         <<"a="<<a<<endl
00263         <<"b="<<b<<endl
00264         <<"delta:"<<a-b<<endl
00265         );
00266       g_result=-1;
00267       return;
00268     }
00269   }
00270   cout<<"+ OK"<<endl;
00271 }
00272 
00273 
00274 
00275 // For arbitrary sized Matrix<>
00276 // copy of teh above with additional 1D dimension
00277 template <class TYPE, class T>
00278 void checkWithDim1(const unsigned int dim, const unsigned int samples)
00279 {
00280 
00281 #ifdef WIN32
00282   cout
00283     <<FUNCNAME<<" "
00284     <<"TYPE="<<typeid(TYPE).name()<<" "
00285     <<"T="<<typeid(T).name()<<" "
00286     <<"dim="<<dim<<" ";
00287 #else
00288   CALLINFO;
00289 #endif
00290 
00291   // check disk I/O
00292   for (unsigned int i=0; i<samples; i++)
00293   {
00294     TYPE a, b;
00295     a.newsize(dim);
00296     for (unsigned int jj=0; (int)jj<(int)a.GetNumElements(); jj++)
00297       a.GetData()[jj]=myrand<T>();
00298     b.clear();
00299     a.Save(TMP);
00300     b.Load(TMP);
00301     if (!(a==b)){
00302       BIASERR("failed: Save/Load to "<<TMP<<" on sample "<<i+1<<"/"<<samples<<" with "<<endl
00303         <<"a="<<a<<endl
00304         <<"b="<<b<<endl
00305         <<"delta:"<<a-b<<endl
00306         );
00307       g_result=-1;
00308       return;
00309     }
00310   }
00311   cout<<"+ OK"<<endl;
00312 }
00313 
00314 
00315 
00316 // checks all value types of one templated class
00317 #define CHECK_TYPE( _TPLCLASS ) \
00318   check< _TPLCLASS< unsigned char >, unsigned char >(); \
00319   check< _TPLCLASS< char          >, char >(); \
00320   check< _TPLCLASS< int           >, int >(); \
00321   check< _TPLCLASS< unsigned short>, unsigned short >(); \
00322   check< _TPLCLASS< int           >, int >(); \
00323   check< _TPLCLASS< float         >, float >(); \
00324   check< _TPLCLASS< double        >, double >(); 
00325 
00326 
00327 // entry
00328 int main(int argc, char** argv)
00329 {
00330   //srand(1); // pseudo random numbers only - same numbers on each run for debugging
00331 
00332   // ctest needs this for >1024 chars output: 
00333   cout<<"CTEST_FULL_OUTPUT"<<endl;
00334 
00335   if (argc>0)
00336     cout<<"started "<<argv[0]<<endl;
00337 
00338   if (argc>1)
00339     g_samples=atoi(argv[1]);
00340   cout<<"using "<<g_samples<<" random samples for each instance."<<endl;
00341 
00342   // check fixed size types
00343   // macro based check for all storage types (float, int, ...)
00344   CHECK_TYPE(Vector2);
00345   CHECK_TYPE(Vector3); // contains RGB
00346   CHECK_TYPE(Vector4); // contains RGBA
00347   CHECK_TYPE(Matrix2x2);
00348   CHECK_TYPE(Matrix3x3);
00349   CHECK_TYPE(Matrix3x4);
00350   CHECK_TYPE(Matrix4x4);
00351 
00352   // check variable size 2D types
00353   checkWithDim2< BIAS::Matrix<double>,        double>        (7,   g_samples); // e.g. 7x(7+1)=56 elements
00354   checkWithDim2< BIAS::Matrix<float>,         float>         (7,   g_samples);
00355   checkWithDim2< BIAS::Matrix<int>,           int>           (7,   g_samples);
00356   checkWithDim2< BIAS::Matrix<unsigned char>, unsigned char> (7,   g_samples);
00357   checkWithDim2< BIAS::Matrix<char         >, char>          (7,   g_samples);
00358   checkWithDim2< BIAS::Matrix<unsigned short>,unsigned short>(7,   g_samples);
00359 
00360   // check variable size 1D types
00361   checkWithDim1< BIAS::Vector<double>,        double>        (42,   g_samples); //i.e. 42 elements
00362   checkWithDim1< BIAS::Vector<float>,         float>         (42,   g_samples);
00363   checkWithDim1< BIAS::Vector<int>,           int>           (42,   g_samples);
00364   checkWithDim1< BIAS::Vector<unsigned char>, unsigned char> (42,   g_samples);
00365   checkWithDim1< BIAS::Vector<char         >, char>          (42,   g_samples);
00366   checkWithDim1< BIAS::Vector<unsigned short>,unsigned short>(42,   g_samples);
00367 
00368 
00369   // just to be 150% sure, check the typedefed names again
00370   checkRGBuc ();
00371   checkRGBAuc();
00372   checkRGBf  ();
00373   checkRGBAf (); 
00374 
00375   // show the values to check formatting / layout
00376   DISPVAL(RGBuc (0, 255, 3));
00377   DISPVAL(RGBAuc(0, 255, 3, 4));
00378   DISPVAL(RGBf (1.f/3.f, -2.2f, 3.3f));
00379   DISPVAL(RGBAf(1.f/3.f, -2.2f, 3.3f, 4.4f));
00380 
00381   // done, final result
00382   if (g_result!=0){
00383     cout<<"test failed with result="<<g_result<<endl;
00384     return g_result;
00385   } else {
00386     cout<<"OK - test succeeded."<<endl;
00387     return 0; // success
00388   }
00389 }
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends