debug.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup debug
00017 //! @{
00018 
00019 
00020 //
00021 // arma_print
00022 
00023 
00024 inline
00025 void
00026 arma_print()
00027   {
00028   std::cout << std::endl;
00029   }
00030 
00031 
00032 template<typename T1>
00033 inline
00034 void
00035 arma_print(const T1& x)
00036   {
00037   std::cout << x << std::endl;
00038   }
00039 
00040 
00041 
00042 template<typename T1, typename T2>
00043 inline
00044 void
00045 arma_print(const T1& x, const T2& y)
00046   {
00047   std::cout << x << y << std::endl;
00048   }
00049 
00050 
00051 
00052 #ifdef ARMA_USE_BOOST
00053   template<typename T1>
00054   inline
00055   void
00056   arma_print(const arma_boost::basic_format<T1>& x)
00057     {
00058     std::cout << x << std::endl;
00059     }
00060 #else
00061   template<typename T1, typename T2>
00062   inline
00063   void
00064   arma_print(const arma_boost::basic_format<T1,T2>& x)
00065     {
00066     std::cout << x << std::endl;
00067     }
00068 #endif
00069 
00070 
00071 
00072 //
00073 // arma_sigprint
00074 
00075 //! print a message on cout, with a preceding @ character.
00076 //! used for printing the signature of a function
00077 //! (see the arma_extra_debug_sigprint macro) 
00078 inline
00079 void
00080 arma_sigprint(const char* x)
00081   {
00082   std::cout << "@ " << x;
00083   }
00084 
00085 
00086 
00087 //
00088 // arma_bktprint
00089 
00090 
00091 inline
00092 void
00093 arma_bktprint()
00094   {
00095   std::cout << std::endl;
00096   }
00097 
00098 
00099 template<typename T1>
00100 inline
00101 void
00102 arma_bktprint(const T1& x)
00103   {
00104   std::cout << " [" << x << "]" << std::endl;
00105   }
00106 
00107 
00108 
00109 template<typename T1, typename T2>
00110 inline
00111 void
00112 arma_bktprint(const T1& x, const T2& y)
00113   {
00114   std::cout << " [" << x << y << "]" << std::endl;
00115   }
00116 
00117 
00118 
00119 #ifdef ARMA_USE_BOOST
00120   template<typename T1>
00121   inline
00122   void
00123   arma_bktprint(const arma_boost::basic_format<T1>& x)
00124     {
00125     std::cout << " [" << x << "]" << std::endl;
00126     }
00127 #else
00128   template<typename T1, typename T2>
00129   inline
00130   void
00131   arma_bktprint(const arma_boost::basic_format<T1,T2>& x)
00132     {
00133     std::cout << " [" << x << "]" << std::endl;
00134     }
00135 #endif
00136 
00137 
00138 
00139 //
00140 // arma_thisprint
00141 
00142 
00143 inline
00144 void
00145 arma_thisprint(void* this_ptr)
00146   {
00147   std::cout << " [this = " << this_ptr << "]" << std::endl;
00148   }
00149 
00150 
00151 
00152 //
00153 // arma_warn
00154 
00155 //! if state is true, print a message on cout
00156 template<typename T1>
00157 inline
00158 void
00159 arma_hot
00160 arma_warn(const bool state, const T1& x)
00161   {
00162   if(state==true)
00163     {
00164     arma_print(x);
00165     }
00166   }
00167 
00168 
00169 template<typename T1, typename T2>
00170 inline
00171 void
00172 arma_hot
00173 arma_warn(const bool state, const T1& x, const T2& y)
00174   {
00175   if(state==true)
00176     {
00177     arma_print(x,y);
00178     }
00179   }
00180 
00181 
00182 #ifdef ARMA_USE_BOOST
00183   template<typename T1>
00184   inline
00185   void
00186   arma_hot
00187   arma_warn(const bool state, const arma_boost::basic_format<T1>& x)
00188     {
00189     if(state==true)
00190       arma_print(x);
00191     }
00192 #else
00193   template<typename T1, typename T2>
00194   inline
00195   void
00196   arma_hot
00197   arma_warn(const bool state, const arma_boost::basic_format<T1,T2>& x)
00198     {
00199     if(state==true)
00200       arma_print(x);
00201     }
00202 #endif
00203 
00204 
00205 
00206 //
00207 // arma_check
00208 
00209 //! if state is true, throw a run-time error exception
00210 template<typename T1>
00211 inline
00212 void
00213 arma_hot
00214 arma_check(const bool state, const T1& x)
00215   {
00216   if(state==true)
00217     {
00218     throw std::runtime_error(x);
00219     }
00220   }
00221 
00222 
00223 template<typename T1, typename T2>
00224 inline
00225 void
00226 arma_hot
00227 arma_check(const bool state, const T1& x, const T2& y)
00228   {
00229   if(state==true)
00230     {
00231     throw std::runtime_error( std::string(x) + std::string(y) );
00232     }
00233   }
00234 
00235 
00236 #ifdef ARMA_USE_BOOST
00237   template<typename T1>
00238   inline
00239   void
00240   arma_hot
00241   arma_check(const bool state, const arma_boost::basic_format<T1>& x)
00242     {
00243     if(state==true)
00244       {
00245       throw std::runtime_error(str(x));
00246       }
00247     }
00248 #else
00249   template<typename T1, typename T2>
00250   inline
00251   void
00252   arma_hot
00253   arma_check(const bool state, const arma_boost::basic_format<T1,T2>& x)
00254     {
00255     if(state==true)
00256       {
00257       throw std::runtime_error(str(x));
00258       }
00259     }
00260 #endif
00261 
00262 
00263 
00264 inline
00265 std::string
00266 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)
00267   {
00268   std::stringstream tmp;
00269   
00270   tmp << x << ": incompatible matrix dimensions: (" << A_n_rows << "," << A_n_cols << ") and (" << B_n_rows << "," << B_n_cols << ")";
00271   
00272   return tmp.str();
00273   }
00274 
00275 
00276 
00277 inline
00278 void
00279 arma_hot
00280 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)
00281   {
00282   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
00283     {
00284     throw std::runtime_error
00285       (
00286       arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x)
00287       );
00288     }
00289   }
00290 
00291 
00292 
00293 //! if given matrices have different sizes, throw a run-time error exception
00294 template<typename eT1, typename eT2>
00295 inline
00296 void
00297 arma_hot
00298 arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00299   {
00300   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00301     {
00302     throw std::runtime_error
00303       (
00304       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00305       );
00306     }
00307   }
00308 
00309 
00310 
00311 template<typename eT1, typename eT2>
00312 inline
00313 void
00314 arma_hot
00315 arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00316   {
00317   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00318     {
00319     throw std::runtime_error
00320       (
00321       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00322       );
00323     }
00324   }
00325 
00326 
00327 
00328 template<typename eT1, typename eT2>
00329 inline
00330 void
00331 arma_hot
00332 arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00333   {
00334   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00335     {
00336     throw std::runtime_error
00337       (
00338       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00339       );
00340     }
00341   }
00342 
00343 
00344 
00345 template<typename eT1, typename eT2>
00346 inline
00347 void
00348 arma_hot
00349 arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
00350   {
00351   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00352     {
00353     throw std::runtime_error
00354       (
00355       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00356       );
00357     }
00358   }
00359 
00360 
00361 
00362 inline
00363 void
00364 arma_hot
00365 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)
00366   {
00367   if(A_n_cols != B_n_rows)
00368     {
00369     throw std::runtime_error
00370       (
00371       arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x)
00372       );
00373     }
00374   }
00375 
00376 
00377 
00378 //! if given matrices are incompatible for multiplication, throw a run-time error exception
00379 template<typename eT1, typename eT2>
00380 inline
00381 void
00382 arma_hot
00383 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00384   {
00385   if(A.n_cols != B.n_rows)
00386     {
00387     throw std::runtime_error
00388       (
00389       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00390       );
00391     }
00392   }
00393 
00394 
00395 
00396 template<typename eT1, typename eT2>
00397 inline
00398 void
00399 arma_hot
00400 arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00401   {
00402   if(A.n_cols != B.n_rows)
00403     {
00404     throw std::runtime_error
00405       (
00406       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00407       );
00408     }
00409   }
00410 
00411 
00412 
00413 template<typename eT1, typename eT2>
00414 inline
00415 void
00416 arma_hot
00417 arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00418   {
00419   if(A.n_cols != B.n_rows)
00420     {
00421     throw std::runtime_error
00422       (
00423       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00424       );
00425     }
00426   }
00427 
00428 
00429 
00430 template<typename eT1, typename eT2>
00431 inline
00432 void
00433 arma_hot
00434 arma_assert_mul_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
00435   {
00436   if(A.n_cols != B.n_rows)
00437     {
00438     throw std::runtime_error
00439       (
00440       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00441       );
00442     }
00443   }
00444 
00445 
00446 
00447 //
00448 // arma_stop
00449 
00450 //! throw a run-time error exception
00451 template<typename T1>
00452 inline
00453 void
00454 arma_stop(const T1& x)
00455   {
00456   arma_check(true, x);
00457   }
00458 
00459 
00460 
00461 //
00462 // macros
00463 
00464 
00465 #define ARMA_STRING1(x) #x
00466 #define ARMA_STRING2(x) ARMA_STRING1(x)
00467 #define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
00468 
00469 
00470 #if defined (__GNUG__)
00471   #define ARMA_FNSIG  __PRETTY_FUNCTION__
00472 #elif defined (_MSC_VER)
00473   #define ARMA_FNSIG  __FUNCSIG__ 
00474 #elif defined (ARMA_USE_BOOST)
00475   #define ARMA_FNSIG  BOOST_CURRENT_FUNCTION  
00476 #else 
00477   #define ARMA_FNSIG  "(unknown)"
00478 #endif
00479 
00480 
00481 
00482 #if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
00483   
00484   #define arma_debug_print            arma_print
00485   #define arma_debug_warn             arma_warn
00486   #define arma_debug_check            arma_check
00487   #define arma_debug_assert_same_size arma_assert_same_size
00488   #define arma_debug_assert_mul_size  arma_assert_mul_size
00489   
00490 #else
00491   
00492   #undef ARMA_EXTRA_DEBUG
00493   
00494   #define arma_debug_print            true ? (void)0 : arma_print
00495   #define arma_debug_warn             true ? (void)0 : arma_warn
00496   #define arma_debug_check            true ? (void)0 : arma_check
00497   #define arma_debug_assert_same_size true ? (void)0 : arma_assert_same_size
00498   #define arma_debug_assert_mul_size  true ? (void)0 : arma_assert_mul_size
00499 
00500 #endif
00501 
00502 
00503 #if defined(ARMA_EXTRA_DEBUG)
00504   
00505   #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
00506   #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
00507   #define arma_extra_debug_print          arma_print
00508   #define arma_extra_debug_warn           arma_warn
00509   #define arma_extra_debug_check          arma_check
00510 
00511 #else
00512   
00513   #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
00514   #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
00515   #define arma_extra_debug_print           true ? (void)0 : arma_print
00516   #define arma_extra_debug_warn            true ? (void)0 : arma_warn
00517   #define arma_extra_debug_check           true ? (void)0 : arma_check
00518  
00519 #endif
00520 
00521 
00522 
00523 
00524 #if defined(ARMA_EXTRA_DEBUG)
00525 
00526   namespace junk
00527     {
00528     class arma_first_extra_debug_message
00529       {
00530       public:
00531       
00532       inline
00533       arma_first_extra_debug_message()
00534         {
00535         std::cout << "@ ---" << '\n';
00536         std::cout << "@ Armadillo " << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch << '\n';
00537         std::cout << "@ arma_config::atlas      = " << arma_config::atlas      << '\n';
00538         std::cout << "@ arma_config::lapack     = " << arma_config::lapack     << '\n';
00539         std::cout << "@ arma_config::blas       = " << arma_config::blas       << '\n';
00540         std::cout << "@ arma_config::boost      = " << arma_config::boost      << '\n';
00541         std::cout << "@ arma_config::boost_date = " << arma_config::boost_date << '\n';
00542         std::cout << "@ sizeof(int)  = " << sizeof(int)  << '\n';
00543         std::cout << "@ sizeof(int*) = " << sizeof(int*) << '\n';
00544         std::cout << "@ sizeof(long) = " << sizeof(long) << '\n';
00545         std::cout << "@ ---" << std::endl;
00546         }
00547       
00548       };
00549     
00550     static arma_first_extra_debug_message arma_first_extra_debug_message_run;
00551     }
00552 
00553 #endif
00554 
00555 
00556 //! @}