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 //
00265 // functions for checking whether two matrices have the same dimensions
00266 
00267 
00268 
00269 inline
00270 std::string
00271 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)
00272   {
00273   std::stringstream tmp;
00274   
00275   tmp << x << ": incompatible matrix dimensions: (" << A_n_rows << ',' << A_n_cols << ") and (" << B_n_rows << ',' << B_n_cols << ')';
00276   
00277   return tmp.str();
00278   }
00279 
00280 
00281 
00282 inline
00283 void
00284 arma_hot
00285 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)
00286   {
00287   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
00288     {
00289     throw std::runtime_error
00290       (
00291       arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x)
00292       );
00293     }
00294   }
00295 
00296 
00297 
00298 //! if given matrices have different sizes, throw a run-time error exception
00299 template<typename eT1, typename eT2>
00300 inline
00301 void
00302 arma_hot
00303 arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00304   {
00305   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00306     {
00307     throw std::runtime_error
00308       (
00309       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00310       );
00311     }
00312   }
00313 
00314 
00315 
00316 template<typename eT1, typename eT2>
00317 inline
00318 void
00319 arma_hot
00320 arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00321   {
00322   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00323     {
00324     throw std::runtime_error
00325       (
00326       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00327       );
00328     }
00329   }
00330 
00331 
00332 
00333 template<typename eT1, typename eT2>
00334 inline
00335 void
00336 arma_hot
00337 arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00338   {
00339   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00340     {
00341     throw std::runtime_error
00342       (
00343       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00344       );
00345     }
00346   }
00347 
00348 
00349 
00350 template<typename eT1, typename eT2>
00351 inline
00352 void
00353 arma_hot
00354 arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
00355   {
00356   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) )
00357     {
00358     throw std::runtime_error
00359       (
00360       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00361       );
00362     }
00363   }
00364 
00365 
00366 
00367 //
00368 // functions for checking whether two cubes have the same dimensions
00369 
00370 
00371 
00372 inline
00373 std::string
00374 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)
00375   {
00376   std::stringstream tmp;
00377   
00378   tmp << x << ": incompatible cube dimensions: (" << A_n_rows << ',' << A_n_cols << ',' << A_n_slices << ") and (" << B_n_rows << ',' << B_n_cols << ',' << B_n_slices << ')';
00379   
00380   return tmp.str();
00381   }
00382 
00383 
00384 
00385 inline
00386 void
00387 arma_hot
00388 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)
00389   {
00390   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
00391     {
00392     throw std::runtime_error
00393       (
00394       arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x)
00395       );
00396     }
00397   }
00398 
00399 
00400 
00401 //! if given cubes have different sizes, throw a run-time error exception
00402 template<typename eT1, typename eT2>
00403 inline
00404 void
00405 arma_hot
00406 arma_assert_same_size(const Cube<eT1>& A, const Cube<eT2>& B, const char* x)
00407   {
00408   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00409     {
00410     throw std::runtime_error
00411       (
00412       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x)
00413       );
00414     }
00415   }
00416 
00417 
00418 
00419 template<typename eT1, typename eT2>
00420 inline
00421 void
00422 arma_hot
00423 arma_assert_same_size(const Cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
00424   {
00425   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00426     {
00427     throw std::runtime_error
00428       (
00429       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x)
00430       );
00431     }
00432   }
00433 
00434 
00435 
00436 template<typename eT1, typename eT2>
00437 inline
00438 void
00439 arma_hot
00440 arma_assert_same_size(const subview_cube<eT1>& A, const Cube<eT2>& B, const char* x)
00441   {
00442   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
00443     {
00444     throw std::runtime_error
00445       (
00446       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x)
00447       );
00448     }
00449   }
00450 
00451 
00452 
00453 template<typename eT1, typename eT2>
00454 inline
00455 void
00456 arma_hot
00457 arma_assert_same_size(const subview_cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
00458   {
00459   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
00460     {
00461     throw std::runtime_error
00462       (
00463       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x)
00464       );
00465     }
00466   }
00467 
00468 
00469 
00470 //
00471 // functions for checking whether a cube or subcube can be interpreted as a matrix (i.e. single slice)
00472 
00473 
00474 
00475 template<typename eT1, typename eT2>
00476 inline
00477 void
00478 arma_hot
00479 arma_assert_same_size(const Cube<eT1>& A, const Mat<eT2>& B, const char* x)
00480   {
00481   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
00482     {
00483     throw std::runtime_error
00484       (
00485       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x)
00486       );
00487     }
00488   }
00489 
00490 
00491 
00492 template<typename eT1, typename eT2>
00493 inline
00494 void
00495 arma_hot
00496 arma_assert_same_size(const Mat<eT1>& A, const Cube<eT2>& B, const char* x)
00497   {
00498   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
00499     {
00500     throw std::runtime_error
00501       (
00502       arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x)
00503       );
00504     }
00505   }
00506 
00507 
00508 
00509 template<typename eT1, typename eT2>
00510 inline
00511 void
00512 arma_hot
00513 arma_assert_same_size(const subview_cube<eT1>& A, const Mat<eT2>& B, const char* x)
00514   {
00515   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
00516     {
00517     throw std::runtime_error
00518       (
00519       arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x)
00520       );
00521     }
00522   }
00523 
00524 
00525 
00526 template<typename eT1, typename eT2>
00527 inline
00528 void
00529 arma_hot
00530 arma_assert_same_size(const Mat<eT1>& A, const subview_cube<eT2>& B, const char* x)
00531   {
00532   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
00533     {
00534     throw std::runtime_error
00535       (
00536       arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x)
00537       );
00538     }
00539   }
00540 
00541 
00542 
00543 //
00544 // functions for checking whether two matrices have dimensions that are compatible with the matrix multiply operation
00545 
00546 
00547 
00548 inline
00549 void
00550 arma_hot
00551 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)
00552   {
00553   if(A_n_cols != B_n_rows)
00554     {
00555     throw std::runtime_error
00556       (
00557       arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x)
00558       );
00559     }
00560   }
00561 
00562 
00563 
00564 //! if given matrices are incompatible for multiplication, throw a run-time error exception
00565 template<typename eT1, typename eT2>
00566 inline
00567 void
00568 arma_hot
00569 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
00570   {
00571   if(A.n_cols != B.n_rows)
00572     {
00573     throw std::runtime_error
00574       (
00575       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00576       );
00577     }
00578   }
00579 
00580 
00581 
00582 template<typename eT1, typename eT2>
00583 inline
00584 void
00585 arma_hot
00586 arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
00587   {
00588   if(A.n_cols != B.n_rows)
00589     {
00590     throw std::runtime_error
00591       (
00592       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00593       );
00594     }
00595   }
00596 
00597 
00598 
00599 template<typename eT1, typename eT2>
00600 inline
00601 void
00602 arma_hot
00603 arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
00604   {
00605   if(A.n_cols != B.n_rows)
00606     {
00607     throw std::runtime_error
00608       (
00609       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00610       );
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 subview<eT2>& B, const char* x)
00621   {
00622   if(A.n_cols != B.n_rows)
00623     {
00624     throw std::runtime_error
00625       (
00626       arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x)
00627       );
00628     }
00629   }
00630 
00631 
00632 
00633 //
00634 // arma_stop
00635 
00636 //! throw a run-time error exception
00637 template<typename T1>
00638 inline
00639 void
00640 arma_stop(const T1& x)
00641   {
00642   arma_check(true, x);
00643   }
00644 
00645 
00646 
00647 //
00648 // macros
00649 
00650 
00651 #define ARMA_STRING1(x) #x
00652 #define ARMA_STRING2(x) ARMA_STRING1(x)
00653 #define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
00654 
00655 
00656 #if defined (__GNUG__)
00657   #define ARMA_FNSIG  __PRETTY_FUNCTION__
00658 #elif defined (_MSC_VER)
00659   #define ARMA_FNSIG  __FUNCSIG__ 
00660 #elif defined (ARMA_USE_BOOST)
00661   #define ARMA_FNSIG  BOOST_CURRENT_FUNCTION  
00662 #else 
00663   #define ARMA_FNSIG  "(unknown)"
00664 #endif
00665 
00666 
00667 
00668 #if !defined(ARMA_NO_DEBUG) && !defined(NDEBUG)
00669   
00670   #define arma_debug_print            arma_print
00671   #define arma_debug_warn             arma_warn
00672   #define arma_debug_check            arma_check
00673   #define arma_debug_assert_same_size arma_assert_same_size
00674   #define arma_debug_assert_mul_size  arma_assert_mul_size
00675   
00676 #else
00677   
00678   #undef ARMA_EXTRA_DEBUG
00679   
00680   #define arma_debug_print            true ? (void)0 : arma_print
00681   #define arma_debug_warn             true ? (void)0 : arma_warn
00682   #define arma_debug_check            true ? (void)0 : arma_check
00683   #define arma_debug_assert_same_size true ? (void)0 : arma_assert_same_size
00684   #define arma_debug_assert_mul_size  true ? (void)0 : arma_assert_mul_size
00685 
00686 #endif
00687 
00688 
00689 #if defined(ARMA_EXTRA_DEBUG)
00690   
00691   #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
00692   #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
00693   #define arma_extra_debug_print          arma_print
00694   #define arma_extra_debug_warn           arma_warn
00695   #define arma_extra_debug_check          arma_check
00696 
00697 #else
00698   
00699   #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
00700   #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
00701   #define arma_extra_debug_print           true ? (void)0 : arma_print
00702   #define arma_extra_debug_warn            true ? (void)0 : arma_warn
00703   #define arma_extra_debug_check           true ? (void)0 : arma_check
00704  
00705 #endif
00706 
00707 
00708 
00709 
00710 #if defined(ARMA_EXTRA_DEBUG)
00711 
00712   namespace junk
00713     {
00714     class arma_first_extra_debug_message
00715       {
00716       public:
00717       
00718       inline
00719       arma_first_extra_debug_message()
00720         {
00721         std::cout << "@ ---" << '\n';
00722         std::cout << "@ Armadillo " << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch << '\n';
00723         std::cout << "@ arma_config::atlas      = " << arma_config::atlas      << '\n';
00724         std::cout << "@ arma_config::lapack     = " << arma_config::lapack     << '\n';
00725         std::cout << "@ arma_config::blas       = " << arma_config::blas       << '\n';
00726         std::cout << "@ arma_config::boost      = " << arma_config::boost      << '\n';
00727         std::cout << "@ arma_config::boost_date = " << arma_config::boost_date << '\n';
00728         std::cout << "@ arma_config::good_comp  = " << arma_config::good_comp  << '\n';
00729         std::cout << "@ sizeof(int)  = " << sizeof(int)  << '\n';
00730         std::cout << "@ sizeof(int*) = " << sizeof(int*) << '\n';
00731         std::cout << "@ sizeof(long) = " << sizeof(long) << '\n';
00732         std::cout << "@ ---" << std::endl;
00733         }
00734       
00735       };
00736     
00737     static arma_first_extra_debug_message arma_first_extra_debug_message_run;
00738     }
00739 
00740 #endif
00741 
00742 
00743 //! @}