00001 
00013 #ifndef MAT_CHECKS_H
00014 #define MAT_CHECKS_H
00015 
00016 #include "../bdm/itpp_ext.h"
00017 #include "UnitTest++.h"
00018 #include <string>
00019 
00020 namespace UnitTest {
00021 
00022 bool AreClose ( const itpp::vec &expected, const itpp::vec &actual,
00023                 double tolerance );
00024 
00025 bool AreClose ( const itpp::vec &expected, const itpp::vec &actual,
00026                 const itpp::vec &tolerance );
00027 
00028 bool AreClose ( const itpp::mat &expected, const itpp::mat &actual,
00029                 double tolerance );
00030 
00031 inline void CheckClose ( TestResults &results, const itpp::vec &expected,
00032                          const itpp::vec &actual, double tolerance,
00033                          TestDetails const &details ) {
00034         if ( !AreClose ( expected, actual, tolerance ) ) {
00035                 MemoryOutStream stream;
00036                 stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
00037 
00038                 results.OnTestFailure ( details, stream.GetText() );
00039         }
00040 }
00041 
00042 inline void CheckClose ( TestResults &results, const itpp::mat &expected,
00043                          const itpp::mat &actual, double tolerance,
00044                          TestDetails const &details ) {
00045         if ( !AreClose ( expected, actual, tolerance ) ) {
00046                 MemoryOutStream stream;
00047                 stream << "Expected " << expected << " +/- " << tolerance << " but was " << actual;
00048 
00049                 results.OnTestFailure ( details, stream.GetText() );
00050         }
00051 }
00052 
00053 }
00054 
00057 inline itpp::vec make_close_tolerance ( const itpp::vec & variance, int nsamples ) {
00058         
00059         return 2 * ( sqrt ( variance ) / sqrt ( static_cast<double> ( nsamples ) ) );
00060 }
00061 
00064 class CurrentContext {
00065 public:
00066         
00067         
00068         static const int max_trial_count = 3;
00069 
00070 private:
00071         static const char *config_name;
00072         static int index;
00073 
00074 public:
00075         
00076         CurrentContext ( const char *name, int idx );
00077         ~CurrentContext();
00078 
00079         
00080 
00081 
00082 
00083         static std::string format_context( int ln = -1 );
00084 
00085         template<typename Expected, typename Actual>
00086         static void CheckEqualEx ( UnitTest::TestResults& results,
00087                                    Expected const& expected,
00088                                    Actual const& actual,
00089                                    UnitTest::TestDetails const& details ) {
00090                 if ( ! ( expected == actual ) ) {
00091                         UnitTest::MemoryOutStream stream;
00092                         stream << format_context() << "expected " << expected << " but was " << actual;
00093 
00094                         results.OnTestFailure ( details, stream.GetText() );
00095                 }
00096         }
00097 
00098         template<typename Expected, typename Actual, typename Tolerance>
00099         static void CheckCloseEx ( UnitTest::TestResults& results,
00100                                    Expected const& expected,
00101                                    Actual const& actual,
00102                                    Tolerance const& tolerance,
00103                                    UnitTest::TestDetails const& details ) {
00104                 if ( !UnitTest::AreClose ( expected, actual, tolerance ) ) {
00105                         UnitTest::MemoryOutStream stream;
00106                         stream << format_context() << "expected " << expected << " +/- " << tolerance << " but was " << actual;
00107 
00108                         results.OnTestFailure ( details, stream.GetText() );
00109                 }
00110         }
00111 };
00112 
00113 #define CHECK_EQUAL_EX(expected, actual) \
00114     do \
00115     { \
00116         try { \
00117             CurrentContext::CheckEqualEx(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \
00118         } \
00119         catch (...) { \
00120             UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
00121                     "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \
00122         } \
00123     } while (0)
00124 
00125 
00126 #define CHECK_CLOSE_EX(expected, actual, tolerance) \
00127     do \
00128     { \
00129         try { \
00130             CurrentContext::CheckCloseEx(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), 0, false)); \
00131         } \
00132         catch (...) { \
00133             UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
00134                     "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \
00135         } \
00136     } while (0)
00137 
00138 #endif