debug.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup debug
00018 //! @{
00019 
00020 
00021 //
00022 // arma_stop
00023 
00024 //! print a message to std::cout and/or throw a run-time error exception
00025 template<typename T1>
00026 inline
00027 void
00028 arma_cold
00029 arma_stop(const T1& x)
00030   {
00031   std::cerr.flush();
00032   std::cout.flush();
00033   
00034   std::cout << '\n';
00035   std::cout << "run-time error: " << x << '\n';
00036   std::cout << '\n';
00037   std::cout.flush();
00038   
00039   throw std::runtime_error("");
00040   }
00041 
00042 
00043 
00044 //
00045 // arma_print
00046 
00047 
00048 inline
00049 void
00050 arma_cold
00051 arma_print()
00052   {
00053   std::cout << std::endl;
00054   }
00055 
00056 
00057 template<typename T1>
00058 inline
00059 void
00060 arma_cold
00061 arma_print(const T1& x)
00062   {
00063   std::cout << x << std::endl;
00064   }
00065 
00066 
00067 
00068 template<typename T1, typename T2>
00069 inline
00070 void
00071 arma_cold
00072 arma_print(const T1& x, const T2& y)
00073   {
00074   std::cout << x << y << std::endl;
00075   }
00076 
00077 
00078 
00079 template<typename T1, typename T2, typename T3>
00080 inline
00081 void
00082 arma_cold
00083 arma_print(const T1& x, const T2& y, const T3& z)
00084   {
00085   std::cout << x << y << z << std::endl;
00086   }
00087 
00088 
00089 
00090 
00091 
00092 
00093 //
00094 // arma_sigprint
00095 
00096 //! print a message on cout, with a preceding @ character.
00097 //! used for printing the signature of a function
00098 //! (see the arma_extra_debug_sigprint macro) 
00099 inline
00100 void
00101 arma_sigprint(const char* x)
00102   {
00103   std::cout << "@ " << x;
00104   }
00105 
00106 
00107 
00108 //
00109 // arma_bktprint
00110 
00111 
00112 inline
00113 void
00114 arma_bktprint()
00115   {
00116   std::cout << std::endl;
00117   }
00118 
00119 
00120 template<typename T1>
00121 inline
00122 void
00123 arma_bktprint(const T1& x)
00124   {
00125   std::cout << " [" << x << ']' << std::endl;
00126   }
00127 
00128 
00129 
00130 template<typename T1, typename T2>
00131 inline
00132 void
00133 arma_bktprint(const T1& x, const T2& y)
00134   {
00135   std::cout << " [" << x << y << ']' << std::endl;
00136   }
00137 
00138 
00139 
00140 
00141 
00142 
00143 //
00144 // arma_thisprint
00145 
00146 
00147 inline
00148 void
00149 arma_thisprint(void* this_ptr)
00150   {
00151   std::cout << " [this = " << this_ptr << ']' << std::endl;
00152   }
00153 
00154 
00155 
00156 //
00157 // arma_warn
00158 
00159 //! if state is true, print a message on cout
00160 template<typename T1>
00161 inline
00162 void
00163 arma_hot
00164 arma_warn(const bool state, const T1& x)
00165   {
00166   if(state==true)
00167     {
00168     arma_print(x);
00169     }
00170   }
00171 
00172 
00173 template<typename T1, typename T2>
00174 inline
00175 void
00176 arma_hot
00177 arma_warn(const bool state, const T1& x, const T2& y)
00178   {
00179   if(state==true)
00180     {
00181     arma_print(x,y);
00182     }
00183   }
00184 
00185 
00186 
00187 
00188 
00189 //
00190 // arma_check
00191 
00192 //! if state is true, abort program
00193 template<typename T1>
00194 inline
00195 void
00196 arma_hot
00197 arma_check(const bool state, const T1& x)
00198   {
00199   if(state==true)
00200     {
00201     arma_stop(arma_boost::str_wrapper(x));
00202     }
00203   }
00204 
00205 
00206 template<typename T1, typename T2>
00207 inline
00208 void
00209 arma_hot
00210 arma_check(const bool state, const T1& x, const T2& y)
00211   {
00212   if(state==true)
00213     {
00214     arma_stop( std::string(x) + std::string(y) );
00215     }
00216   }
00217 
00218 
00219 
00220 
00221 
00222 
00223 //
00224 // functions for checking whether two matrices have the same dimensions
00225 
00226 
00227 
00228 inline
00229 std::string
00230 arma_cold
00231 arma_incompat_size_string(const u32 A_n_rows, const u32 A_n_cols, const u32 B_n_rows, const u32 B_n_cols, const char* x)
00232   {
00233   std::stringstream tmp;
00234   
00235   tmp << x << ": incompatible matrix dimensions: (" << A_n_rows << ',' << A_n_cols << ") and (" << B_n_rows << ',' << B_n_cols << ')';
00236   
00237   return tmp.str();
00238   }
00239 
00240 
00241 
00242 inline
00243 void
00244 arma_hot
00245 arma_assert_same_size(const u32 A_n_rows, const u32 A_n_cols, const u32 B_n_rows, const u32 B_n_cols, const char* x)
00246   {
00247   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
00248     {
00249     arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
00250     }
00251   }
00252 
00253 
00254 
00255 //! stop if given matrices have different sizes
00256 template<typename eT1, typename eT2>
00257 inline
00258 void
00259 arma_hot
00260 arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00261   {
00262   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00263     {
00264     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00265     }
00266   }
00267 
00268 
00269 
00270 //! stop if given proxies have different sizes
00271 template<typename eT1, typename eT2>
00272 inline
00273 void
00274 arma_hot
00275 arma_assert_same_size(const Proxy<eT1>& A, const Proxy<eT2>& B, const char* x)
00276   {
00277   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00278     {
00279     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00280     }
00281   }
00282 
00283 
00284 
00285 template<typename eT1, typename eT2>
00286 inline
00287 void
00288 arma_hot
00289 arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
00290   {
00291   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00292     {
00293     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00294     }
00295   }
00296 
00297 
00298 
00299 template<typename eT1, typename eT2>
00300 inline
00301 void
00302 arma_hot
00303 arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00304   {
00305   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00306     {
00307     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00308     }
00309   }
00310 
00311 
00312 
00313 template<typename eT1, typename eT2>
00314 inline
00315 void
00316 arma_hot
00317 arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00318   {
00319   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00320     {
00321     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00322     }
00323   }
00324 
00325 
00326 
00327 template<typename eT1, typename eT2>
00328 inline
00329 void
00330 arma_hot
00331 arma_assert_same_size(const Mat<eT1>& A, const Proxy<eT2>& B, const char* x)
00332   {
00333   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00334     {
00335     arma_stop ( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00336     }
00337   }
00338 
00339 
00340 
00341 template<typename eT1, typename eT2>
00342 inline
00343 void
00344 arma_hot
00345 arma_assert_same_size(const Proxy<eT1>& A, const Mat<eT2>& B, const char* x)
00346   {
00347   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00348     {
00349     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00350     }
00351   }
00352 
00353 
00354 
00355 template<typename eT1, typename eT2>
00356 inline
00357 void
00358 arma_hot
00359 arma_assert_same_size(const Proxy<eT1>& A, const subview<eT2>& B, const char* x)
00360   {
00361   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00362     {
00363     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00364     }
00365   }
00366 
00367 
00368 
00369 template<typename eT1, typename eT2>
00370 inline
00371 void
00372 arma_hot
00373 arma_assert_same_size(const subview<eT1>& A, const Proxy<eT2>& B, const char* x)
00374   {
00375   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00376     {
00377     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00378     }
00379   }
00380 
00381 
00382 
00383 //
00384 // functions for checking whether two cubes have the same dimensions
00385 
00386 
00387 
00388 inline
00389 arma_cold
00390 std::string
00391 arma_incompat_size_string(const u32 A_n_rows, const u32 A_n_cols, const u32 A_n_slices, const u32 B_n_rows, const u32 B_n_cols, const u32 B_n_slices, const char* x)
00392   {
00393   std::stringstream tmp;
00394   
00395   tmp << x << ": incompatible cube dimensions: (" << A_n_rows << ',' << A_n_cols << ',' << A_n_slices << ") and (" << B_n_rows << ',' << B_n_cols << ',' << B_n_slices << ')';
00396   
00397   return tmp.str();
00398   }
00399 
00400 
00401 
00402 inline
00403 void
00404 arma_hot
00405 arma_assert_same_size(const u32 A_n_rows, const u32 A_n_cols, const u32 A_n_slices, const u32 B_n_rows, const u32 B_n_cols, const u32 B_n_slices, const char* x)
00406   {
00407   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
00408     {
00409     arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
00410     }
00411   }
00412 
00413 
00414 
00415 //! stop if given cubes have different sizes
00416 template<typename eT1, typename eT2>
00417 inline
00418 void
00419 arma_hot
00420 arma_assert_same_size(const Cube<eT1>& A, const Cube<eT2>& B, const char* x)
00421   {
00422   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00423     {
00424     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
00425     }
00426   }
00427 
00428 
00429 
00430 template<typename eT1, typename eT2>
00431 inline
00432 void
00433 arma_hot
00434 arma_assert_same_size(const Cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
00435   {
00436   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00437     {
00438     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
00439     }
00440   }
00441 
00442 
00443 
00444 template<typename eT1, typename eT2>
00445 inline
00446 void
00447 arma_hot
00448 arma_assert_same_size(const subview_cube<eT1>& A, const Cube<eT2>& B, const char* x)
00449   {
00450   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00451     {
00452     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
00453     }
00454   }
00455 
00456 
00457 
00458 template<typename eT1, typename eT2>
00459 inline
00460 void
00461 arma_hot
00462 arma_assert_same_size(const subview_cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
00463   {
00464   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
00465     {
00466     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
00467     }
00468   }
00469 
00470 
00471 
00472 //! stop if given cube proxies have different sizes
00473 template<typename eT1, typename eT2>
00474 inline
00475 void
00476 arma_hot
00477 arma_assert_same_size(const ProxyCube<eT1>& A, const ProxyCube<eT2>& B, const char* x)
00478   {
00479   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
00480     {
00481     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
00482     }
00483   }
00484 
00485 
00486 
00487 //
00488 // functions for checking whether a cube or subcube can be interpreted as a matrix (i.e. single slice)
00489 
00490 
00491 
00492 template<typename eT1, typename eT2>
00493 inline
00494 void
00495 arma_hot
00496 arma_assert_same_size(const Cube<eT1>& A, const Mat<eT2>& B, const char* x)
00497   {
00498   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
00499     {
00500     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
00501     }
00502   }
00503 
00504 
00505 
00506 template<typename eT1, typename eT2>
00507 inline
00508 void
00509 arma_hot
00510 arma_assert_same_size(const Mat<eT1>& A, const Cube<eT2>& B, const char* x)
00511   {
00512   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
00513     {
00514     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
00515     }
00516   }
00517 
00518 
00519 
00520 template<typename eT1, typename eT2>
00521 inline
00522 void
00523 arma_hot
00524 arma_assert_same_size(const subview_cube<eT1>& A, const Mat<eT2>& B, const char* x)
00525   {
00526   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
00527     {
00528     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
00529     }
00530   }
00531 
00532 
00533 
00534 template<typename eT1, typename eT2>
00535 inline
00536 void
00537 arma_hot
00538 arma_assert_same_size(const Mat<eT1>& A, const subview_cube<eT2>& B, const char* x)
00539   {
00540   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
00541     {
00542     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
00543     }
00544   }
00545 
00546 
00547 
00548 //
00549 // functions for checking whether two matrices have dimensions that are compatible with the matrix multiply operation
00550 
00551 
00552 
00553 inline
00554 void
00555 arma_hot
00556 arma_assert_mul_size(const u32 A_n_rows, const u32 A_n_cols, const u32 B_n_rows, const u32 B_n_cols, const char* x)
00557   {
00558   if(A_n_cols != B_n_rows)
00559     {
00560     arma_stop( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
00561     }
00562   }
00563 
00564 
00565 
00566 //! stop if given matrices are incompatible for multiplication
00567 template<typename eT1, typename eT2>
00568 inline
00569 void
00570 arma_hot
00571 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00572   {
00573   if(A.n_cols != B.n_rows)
00574     {
00575     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00576     }
00577   }
00578 
00579 
00580 
00581 //! stop if given matrices are incompatible for multiplication
00582 template<typename eT1, typename eT2>
00583 inline
00584 void
00585 arma_hot
00586 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const bool do_trans_A, const bool do_trans_B, const char* x)
00587   {
00588   const u32 final_A_n_cols = (do_trans_A == false) ? A.n_cols : A.n_rows;
00589   const u32 final_B_n_rows = (do_trans_B == false) ? B.n_rows : B.n_cols;
00590     
00591   if(final_A_n_cols != final_B_n_rows)
00592     {
00593     const u32 final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
00594     const u32 final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
00595     
00596     arma_stop( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
00597     }
00598   }
00599 
00600 
00601 
00602 template<typename eT1, typename eT2>
00603 inline
00604 void
00605 arma_hot
00606 arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00607   {
00608   if(A.n_cols != B.n_rows)
00609     {
00610     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00611     }
00612   }
00613 
00614 
00615 
00616 template<typename eT1, typename eT2>
00617 inline
00618 void
00619 arma_hot
00620 arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00621   {
00622   if(A.n_cols != B.n_rows)
00623     {
00624     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00625     }
00626   }
00627 
00628 
00629 
00630 template<typename eT1, typename eT2>
00631 inline
00632 void
00633 arma_hot
00634 arma_assert_mul_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
00635   {
00636   if(A.n_cols != B.n_rows)
00637     {
00638     arma_stop( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
00639     }
00640   }
00641 
00642 
00643 
00644 //
00645 // macros
00646 
00647 
00648 #define ARMA_STRING1(x) #x
00649 #define ARMA_STRING2(x) ARMA_STRING1(x)
00650 #define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
00651 
00652 
00653 #if defined (__GNUG__)
00654   #define ARMA_FNSIG  __PRETTY_FUNCTION__
00655 #elif defined (_MSC_VER)
00656   #define ARMA_FNSIG  __FUNCSIG__ 
00657 #elif defined (ARMA_USE_BOOST)
00658   #define ARMA_FNSIG  BOOST_CURRENT_FUNCTION  
00659 #else 
00660   #define ARMA_FNSIG  "(unknown)"
00661 #endif
00662 
00663 
00664 
00665 #if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
00666   
00667   #define arma_debug_print            arma_print
00668   #define arma_debug_warn             arma_warn
00669   #define arma_debug_check            arma_check
00670   #define arma_debug_assert_same_size arma_assert_same_size
00671   #define arma_debug_assert_mul_size  arma_assert_mul_size
00672   
00673 #else
00674   
00675   #undef ARMA_EXTRA_DEBUG
00676   
00677   #define arma_debug_print            true ? (void)0 : arma_print
00678   #define arma_debug_warn             true ? (void)0 : arma_warn
00679   #define arma_debug_check            true ? (void)0 : arma_check
00680   #define arma_debug_assert_same_size true ? (void)0 : arma_assert_same_size
00681   #define arma_debug_assert_mul_size  true ? (void)0 : arma_assert_mul_size
00682 
00683 #endif
00684 
00685 
00686 #if defined(ARMA_EXTRA_DEBUG)
00687   
00688   #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
00689   #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
00690   #define arma_extra_debug_print          arma_print
00691   #define arma_extra_debug_warn           arma_warn
00692   #define arma_extra_debug_check          arma_check
00693 
00694 #else
00695   
00696   #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
00697   #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
00698   #define arma_extra_debug_print           true ? (void)0 : arma_print
00699   #define arma_extra_debug_warn            true ? (void)0 : arma_warn
00700   #define arma_extra_debug_check           true ? (void)0 : arma_check
00701  
00702 #endif
00703 
00704 
00705 
00706 
00707 #if defined(ARMA_EXTRA_DEBUG)
00708 
00709   namespace junk
00710     {
00711     class arma_first_extra_debug_message
00712       {
00713       public:
00714       
00715       inline
00716       arma_cold
00717       arma_first_extra_debug_message()
00718         {
00719         std::cout << "@ ---" << '\n';
00720         std::cout << "@ Armadillo " << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch << '\n';
00721         std::cout << "@ arma_config::atlas      = " << arma_config::atlas      << '\n';
00722         std::cout << "@ arma_config::lapack     = " << arma_config::lapack     << '\n';
00723         std::cout << "@ arma_config::blas       = " << arma_config::blas       << '\n';
00724         std::cout << "@ arma_config::boost      = " << arma_config::boost      << '\n';
00725         std::cout << "@ arma_config::boost_date = " << arma_config::boost_date << '\n';
00726         std::cout << "@ arma_config::good_comp  = " << arma_config::good_comp  << '\n';
00727         std::cout << "@ sizeof(int)  = " << sizeof(int)  << '\n';
00728         std::cout << "@ sizeof(int*) = " << sizeof(int*) << '\n';
00729         std::cout << "@ sizeof(long) = " << sizeof(long) << '\n';
00730         std::cout << "@ ---" << std::endl;
00731         }
00732       
00733       };
00734     
00735     static arma_first_extra_debug_message arma_first_extra_debug_message_run;
00736     }
00737 
00738 #endif
00739 
00740 
00741 //! @}