OpenWalnut  1.4.0
WValue_test.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WVALUE_TEST_H
00026 #define WVALUE_TEST_H
00027 
00028 #include <string>
00029 
00030 #include <cxxtest/TestSuite.h>
00031 
00032 #include "../WValue.h"
00033 
00034 
00035 /**
00036  * Testsuite for WValue.
00037  */
00038 class WValueTest : public CxxTest::TestSuite
00039 {
00040 private:
00041     double delta; //!< Some values are allowed to differ by delta.
00042 
00043 public:
00044     /**
00045      * Called before every test.
00046      */
00047     void setUp( void )
00048     {
00049         delta = 1e-12;
00050     }
00051 
00052     /**
00053      * Instantiation should throw nothing.
00054      */
00055     void testInstantiation( void )
00056     {
00057         TS_ASSERT_THROWS_NOTHING( WValue< double > value( 3 ) );
00058         TS_ASSERT_THROWS_NOTHING( WValue< float > value( 3 ) );
00059     }
00060 
00061     /**
00062      * size should give the value we have put into the constructor
00063      */
00064     void testSize( void )
00065     {
00066         const size_t size = 3;
00067         WValue< double > value( size );
00068         TS_ASSERT_EQUALS( value.size(), size );
00069     }
00070 
00071     /**
00072      * Element access operator should return the right values
00073      */
00074     void testElementAccessOperator( void )
00075     {
00076         const size_t size = 3;
00077         WValue< double > value( size );
00078         TS_ASSERT_EQUALS( value[0], 0. );
00079         TS_ASSERT_EQUALS( value[1], 0. );
00080         TS_ASSERT_EQUALS( value[2], 0. );
00081 
00082         const double a = 3.14;
00083         value[1] = a;
00084         TS_ASSERT_EQUALS( value[1], a );
00085     }
00086 
00087     /**
00088      * Const element access operator should return the right values.
00089      */
00090     void testConstElementAccessOperator( void )
00091     {
00092         const size_t size = 3;
00093         const WValue< double > value( size );
00094         TS_ASSERT_EQUALS( value[0], 0. );
00095         TS_ASSERT_EQUALS( value[1], 0. );
00096         TS_ASSERT_EQUALS( value[2], 0. );
00097     }
00098 
00099     /**
00100      * == operator should return true if the WValues contain the same elements and false if the don't.
00101      */
00102     void testEqualityOperator( void )
00103     {
00104         const size_t size = 3;
00105         const double a = 1.2, b = 3.4, c = 5.6;
00106         WValue< double > value1( size );
00107         WValue< double > value2( size );
00108 
00109         value1[0] = a;
00110         value1[1] = b;
00111         value1[2] = c;
00112 
00113         value2[0] = a;
00114         value2[1] = b;
00115         value2[2] = c;
00116 
00117         TS_ASSERT_EQUALS( value1 == value2, true );
00118 
00119         value2[0] += 1;
00120 
00121         TS_ASSERT_EQUALS( value1 == value2, false );
00122     }
00123 
00124     /**
00125      * != operator should return false if the WValues contain the same elements and false if the don't.
00126      */
00127     void testInEqualityOperator( void )
00128     {
00129         const size_t size = 3;
00130         const double a = 1.2, b = 3.4, c = 5.6;
00131         WValue< double > value1( size );
00132         WValue< double > value2( size );
00133 
00134         value1[0] = a;
00135         value1[1] = b;
00136         value1[2] = c;
00137 
00138         value2[0] = a;
00139         value2[1] = b;
00140         value2[2] = c;
00141 
00142         TS_ASSERT_EQUALS( value1 != value2, false );
00143 
00144         value2[0] += 1;
00145 
00146         TS_ASSERT_EQUALS( value1 != value2, true );
00147     }
00148 
00149     /**
00150      * assignment operator= should assign the correct values
00151      */
00152     void testAssignmentOperator( void )
00153     {
00154         const size_t size = 3;
00155         const double a = 1.2, b = 3.4, c = 5.6;
00156         WValue< double > value1( size );
00157         WValue< double > value2( size );
00158 
00159         value1[0] = a;
00160         value1[1] = b;
00161         value1[2] = c;
00162 
00163         value2[0] = a + 1;
00164         value2[1] = b + 2;
00165         value2[2] = c + 3;
00166 
00167         // this should be the precondition for the test
00168         TS_ASSERT_EQUALS( value1 == value2, false );
00169 
00170         // test simple assignment
00171         value1 = value2;
00172         TS_ASSERT_EQUALS( value1 == value2, true );
00173 
00174         WValue< double > value3( size );
00175         WValue< double > value4( size );
00176 
00177         // this should be the precondition for the test
00178         TS_ASSERT_EQUALS( value2 == value3, false );
00179         TS_ASSERT_EQUALS( value2 == value4, false );
00180 
00181         // test whether return the reference to self works
00182         // for multiple assignment
00183         value4 = value3 = value2;
00184         TS_ASSERT_EQUALS( value2 == value3, true );
00185         TS_ASSERT_EQUALS( value2 == value4, true );
00186         TS_ASSERT_EQUALS( value3 == value4, true );
00187     }
00188 
00189     /**
00190      * plus assignment operator-= should assign the correct values
00191      */
00192     void testPlusAssignmentOperator( void )
00193     {
00194         const size_t size = 3;
00195         const double a = 1.2, b = 3.4, c = 5.6;
00196         WValue< double > value1( size );
00197         WValue< double > value2( size );
00198 
00199         value1[0] = a;
00200         value1[1] = b;
00201         value1[2] = c;
00202 
00203         value2[0] = a + 1;
00204         value2[1] = b + 2;
00205         value2[2] = c + 3;
00206 
00207         // this should be the precondition for the test
00208         TS_ASSERT_EQUALS( value1 == value2, false );
00209 
00210         // test simple plus assignement
00211         value1 += value2;
00212         TS_ASSERT_DELTA( value1[0], 1. + 2. * a, delta );
00213         TS_ASSERT_DELTA( value1[1], 2. + 2. * b, delta );
00214         TS_ASSERT_DELTA( value1[2], 3. + 2. * c, delta );
00215 
00216         WValue< double > value3( size );
00217         WValue< double > value4( size );
00218 
00219         // this should be the precondition for the test
00220         TS_ASSERT_EQUALS( value2 == value3, false );
00221         TS_ASSERT_EQUALS( value2 == value4, false );
00222 
00223         // test whether return the reference to self works
00224         // for multiple plus assignment
00225         value4 += value3 += value2;
00226         TS_ASSERT_EQUALS( value2 == value3, true );
00227         TS_ASSERT_EQUALS( value2 == value4, true );
00228         TS_ASSERT_EQUALS( value3 == value4, true );
00229     }
00230 
00231     /**
00232      * minus assignment operator-= should assign the correct values
00233      */
00234     void testMinusAssignmentOperator( void )
00235     {
00236         const size_t size = 3;
00237         const double a = 1.2, b = 3.4, c = 5.6;
00238         WValue< double > value1( size );
00239         WValue< double > value2( size );
00240 
00241         value1[0] = a;
00242         value1[1] = b;
00243         value1[2] = c;
00244 
00245         value2[0] = a + 1;
00246         value2[1] = b + 2;
00247         value2[2] = c + 3;
00248 
00249         // this should be the precondition for the test
00250         TS_ASSERT_EQUALS( value1 == value2, false );
00251 
00252         // test simple minus assignement
00253         value1 -= value2;
00254         TS_ASSERT_DELTA( value1[0], -1., delta );
00255         TS_ASSERT_DELTA( value1[1], -2., delta );
00256         TS_ASSERT_DELTA( value1[2], -3., delta );
00257 
00258         WValue< double > value3( size );
00259         WValue< double > value4( size );
00260 
00261         // this should be the precondition for the test
00262         TS_ASSERT_EQUALS( value2 == value3, false );
00263         TS_ASSERT_EQUALS( value2 == value4, false );
00264 
00265         // test whether return the reference to self works
00266         // for multiple minus assignment
00267         value4 -= value3 -= value2;
00268         TS_ASSERT_DELTA( value3[0], -value2[0], delta );
00269         TS_ASSERT_DELTA( value3[1], -value2[1], delta );
00270         TS_ASSERT_DELTA( value3[2], -value2[2], delta );
00271         TS_ASSERT_DELTA( value4[0], value2[0], delta );
00272         TS_ASSERT_DELTA( value4[1], value2[1], delta );
00273         TS_ASSERT_DELTA( value4[2], value2[2], delta );
00274     }
00275 
00276     /**
00277      * product with scalar assignment operator*= should assign the correct values
00278      */
00279     void testProductWithScalarAssignmentOperator( void )
00280     {
00281         const size_t size = 3;
00282         const double a = 1.2, b = 3.4, c = 5.6;
00283         WValue< double > value1( size );
00284         const double scalar = 32.32;
00285 
00286         value1[0] = a;
00287         value1[1] = b;
00288         value1[2] = c;
00289 
00290         // test simple product with scalar assignement
00291         value1 *= scalar;
00292         double expected[] = { 38.784, 109.888, 180.992 };
00293         TS_ASSERT_DELTA( value1[0], expected[0], delta );
00294         TS_ASSERT_DELTA( value1[1], expected[1], delta );
00295         TS_ASSERT_DELTA( value1[2], expected[2], delta );
00296 
00297         WValue< double > value2( size );
00298 
00299         // reinitialize value
00300         value1[0] = a;
00301         value1[1] = b;
00302         value1[2] = c;
00303 
00304         // this should be the precondition for the test
00305         TS_ASSERT_EQUALS( value2 == value1, false );
00306 
00307         // test whether return the reference to self works
00308         // for multiple assignments
00309         value2 = value1 *= scalar;
00310         TS_ASSERT_DELTA( value1[0], expected[0], delta );
00311         TS_ASSERT_DELTA( value1[1], expected[1], delta );
00312         TS_ASSERT_DELTA( value1[2], expected[2], delta );
00313         TS_ASSERT_DELTA( value2[0], value1[0], delta );
00314         TS_ASSERT_DELTA( value2[1], value1[1], delta );
00315         TS_ASSERT_DELTA( value2[2], value1[2], delta );
00316     }
00317     /**
00318      * componentwise product assignment operator*= should assign the correct values
00319      */
00320     void testComponentWiseProductAssignmentOperator( void )
00321     {
00322         const size_t size = 3;
00323         const double a = 1.2, b = 3.4, c = 5.6;
00324         WValue< double > value1( size );
00325         WValue< double > value2( size );
00326 
00327         value1[0] = a;
00328         value1[1] = b;
00329         value1[2] = c;
00330 
00331         value2[0] = a + 1;
00332         value2[1] = b + 2;
00333         value2[2] = c + 3;
00334 
00335         // test simple componentwise product assignement
00336         value1 *= value2;
00337         double expected[] = { 2.64, 18.36, 48.16 };
00338         TS_ASSERT_DELTA( value1[0], expected[0], delta );
00339         TS_ASSERT_DELTA( value1[1], expected[1], delta );
00340         TS_ASSERT_DELTA( value1[2], expected[2], delta );
00341 
00342         // reinitialize value
00343         value1[0] = a;
00344         value1[1] = b;
00345         value1[2] = c;
00346 
00347         WValue< double > value3( size );
00348 
00349         value3[0] = a + 1.1;
00350         value3[1] = b + 2.2;
00351         value3[2] = c + 3.3;
00352 
00353         double expected2[] = { 6.072, 102.816, 428.624 };
00354 
00355         // test whether return the reference to self works
00356         // for multiple assignments
00357         value3 *= value1 *= value2;
00358         TS_ASSERT_DELTA( value1[0], expected[0], delta );
00359         TS_ASSERT_DELTA( value1[1], expected[1], delta );
00360         TS_ASSERT_DELTA( value1[2], expected[2], delta );
00361         TS_ASSERT_DELTA( value3[0], expected2[0], delta );
00362         TS_ASSERT_DELTA( value3[1], expected2[1], delta );
00363         TS_ASSERT_DELTA( value3[2], expected2[2], delta );
00364     }
00365 
00366     /**
00367      * plus operator+
00368      */
00369     void testPlusOperator( void )
00370     {
00371         const size_t size = 3;
00372         const double a = 1.2, b = 3.4, c = 5.6;
00373         WValue< double > value1( size );
00374         WValue< double > value2( size );
00375         WValue< double > value3( size );
00376 
00377         value1[0] = a;
00378         value1[1] = b;
00379         value1[2] = c;
00380 
00381         value2[0] = a + 1;
00382         value2[1] = b + 2;
00383         value2[2] = c + 3;
00384 
00385         // test addition
00386         value3 = value1 + value2;
00387 
00388         TS_ASSERT_DELTA( value3[0], 2 * a + 1, delta );
00389         TS_ASSERT_DELTA( value3[1], 2 * b + 2, delta );
00390         TS_ASSERT_DELTA( value3[2], 2 * c + 3, delta );
00391 
00392         // Ensure that value1 and value2 have not been altered
00393         TS_ASSERT_EQUALS( value1[0], a );
00394         TS_ASSERT_EQUALS( value1[1], b );
00395         TS_ASSERT_EQUALS( value1[2], c );
00396         TS_ASSERT_EQUALS( value2[0], a + 1 );
00397         TS_ASSERT_EQUALS( value2[1], b + 2 );
00398         TS_ASSERT_EQUALS( value2[2], c + 3 );
00399     }
00400 
00401     /**
00402      * minus operator+-
00403      */
00404     void testMinusOperator( void )
00405     {
00406         const size_t size = 3;
00407         const double a = 1.2, b = 3.4, c = 5.6;
00408         WValue< double > value1( size );
00409         WValue< double > value2( size );
00410         WValue< double > value3( size );
00411 
00412         value1[0] = a;
00413         value1[1] = b;
00414         value1[2] = c;
00415 
00416         value2[0] = a + 1;
00417         value2[1] = b + 2;
00418         value2[2] = c + 3;
00419 
00420         // test subtraction
00421         value3 = value1 - value2;
00422 
00423         TS_ASSERT_DELTA( value3[0], -1, delta );
00424         TS_ASSERT_DELTA( value3[1], -2, delta );
00425         TS_ASSERT_DELTA( value3[2], -3, delta );
00426 
00427         // Ensure that value1 and value2 have not been altered
00428         TS_ASSERT_EQUALS( value1[0], a );
00429         TS_ASSERT_EQUALS( value1[1], b );
00430         TS_ASSERT_EQUALS( value1[2], c );
00431         TS_ASSERT_EQUALS( value2[0], a + 1 );
00432         TS_ASSERT_EQUALS( value2[1], b + 2 );
00433         TS_ASSERT_EQUALS( value2[2], c + 3 );
00434     }
00435 
00436     /**
00437      * componentwise multiplication operator*
00438      */
00439     void testComponentWiseProductOperator( void )
00440     {
00441         const size_t size = 3;
00442         const double a = 1.2, b = 3.4, c = 5.6;
00443         WValue< double > value1( size );
00444         WValue< double > value2( size );
00445         WValue< double > value3( size );
00446 
00447         value1[0] = a;
00448         value1[1] = b;
00449         value1[2] = c;
00450 
00451         value2[0] = a + 1;
00452         value2[1] = b + 2;
00453         value2[2] = c + 3;
00454 
00455         // test subtraction
00456         value3 = value1 * value2;
00457 
00458         double expected[] = { 2.64, 18.36, 48.16 };
00459         TS_ASSERT_DELTA( value3[0], expected[0], delta );
00460         TS_ASSERT_DELTA( value3[1], expected[1], delta );
00461         TS_ASSERT_DELTA( value3[2], expected[2], delta );
00462 
00463         // Ensure that value1 and value2 have not been altered
00464         TS_ASSERT_EQUALS( value1[0], a );
00465         TS_ASSERT_EQUALS( value1[1], b );
00466         TS_ASSERT_EQUALS( value1[2], c );
00467         TS_ASSERT_EQUALS( value2[0], a + 1 );
00468         TS_ASSERT_EQUALS( value2[1], b + 2 );
00469         TS_ASSERT_EQUALS( value2[2], c + 3 );
00470     }
00471 
00472     /**
00473      * norm with doubles
00474      */
00475     void testNormDouble( void )
00476     {
00477         const size_t size = 3;
00478         const double a = 1.2, b = 3.4, c = 5.6;
00479         WValue< double > value1( size );
00480 
00481         value1[0] = a;
00482         value1[1] = b;
00483         value1[2] = c;
00484         TS_ASSERT_DELTA( value1.norm(), 6.660330322, 1e-7 );
00485     }
00486 
00487     /**
00488      * norm int
00489      */
00490     void testNormInt( void )
00491     {
00492         const size_t size = 3;
00493         const int a = 1, b = 2, c = 3;
00494         WValue< int > value1( size );
00495 
00496         value1[0] = a;
00497         value1[1] = b;
00498         value1[2] = c;
00499         TS_ASSERT_DELTA( value1.norm(), 3.74165738677, 1e-7 );
00500     }
00501 
00502     /**
00503      * normsquare
00504      */
00505     void testNormSquare( void )
00506     {
00507         const size_t size = 3;
00508         const double a = 1.2, b = 3.4, c = 5.6;
00509         WValue< double > value1( size );
00510 
00511         value1[0] = a;
00512         value1[1] = b;
00513         value1[2] = c;
00514         TS_ASSERT_DELTA( value1.normSquare(), 44.36, delta );
00515     }
00516 
00517     /**
00518      * test normalization of the current WValue
00519      */
00520     void testNormalize( void )
00521     {
00522         const size_t size = 3;
00523         const double a = 1.2, b = 3.4, c = 5.6;
00524         WValue< double > value1( size );
00525 
00526         value1[0] = a;
00527         value1[1] = b;
00528         value1[2] = c;
00529 
00530         TS_ASSERT( std::abs( value1.norm() - 1. ) > 1e-9 );
00531         value1.normalize();
00532         TS_ASSERT_DELTA( value1.norm(), 1., delta );
00533     }
00534 
00535     /**
00536      * test returning normalized version
00537      */
00538     void testNormalized( void )
00539     {
00540         const size_t size = 3;
00541         const double a = 1.2, b = 3.4, c = 5.6;
00542         WValue< double > value1( size );
00543 
00544         value1[0] = a;
00545         value1[1] = b;
00546         value1[2] = c;
00547         WValue< double > valueCopy = value1;
00548 
00549         TS_ASSERT( std::abs( value1.norm() - 1. ) > 1e-9 );
00550         WValue< double > value2 = value1.normalized();
00551 
00552         // value1 should not have been changed
00553         TS_ASSERT( std::abs( value1.norm() - 1. ) > 1e-9 );
00554         TS_ASSERT_EQUALS( value1, valueCopy );
00555 
00556         // value2 should contain the normalized version
00557         TS_ASSERT_DELTA( value2.norm(), 1., delta );
00558     }
00559 
00560     /**
00561      * scaling operator, scalar left hand side
00562      */
00563     void testScalingLeftHandSide( void )
00564     {
00565         const size_t size = 3;
00566         const double a = 1.2, b = 3.4, c = 5.6;
00567         WValue< double > value1( size );
00568         WValue< double > value2( size );
00569         const double scalar = 32.32;
00570 
00571         value1[0] = a;
00572         value1[1] = b;
00573         value1[2] = c;
00574 
00575         // test scaling with scalar left hand side
00576         value2 = scalar * value1;
00577 
00578         double expected[] = { 38.784, 109.888, 180.992 };
00579         TS_ASSERT_DELTA( value2[0], expected[0], delta );
00580         TS_ASSERT_DELTA( value2[1], expected[1], delta );
00581         TS_ASSERT_DELTA( value2[2], expected[2], delta );
00582     }
00583 
00584     /**
00585      * scaling operator, scalar right hand side
00586      */
00587     void testScalingRightHandSide( void )
00588     {
00589         const size_t size = 3;
00590         const double a = 1.2, b = 3.4, c = 5.6;
00591         WValue< double > value1( size );
00592         WValue< double > value2( size );
00593         const double scalar = 32.32;
00594 
00595         value1[0] = a;
00596         value1[1] = b;
00597         value1[2] = c;
00598 
00599         // test scaling with scalar right hand side
00600         value2 = value1 * scalar;
00601 
00602         double expected[] = { 38.784, 109.888, 180.992 };
00603         TS_ASSERT_DELTA( value2[0], expected[0], delta );
00604         TS_ASSERT_DELTA( value2[1], expected[1], delta );
00605         TS_ASSERT_DELTA( value2[2], expected[2], delta );
00606     }
00607 
00608     /**
00609      * ensure scaling operator commutativity
00610      */
00611     void testScalingCommutativity( void )
00612     {
00613         const size_t size = 3;
00614         const double a = 1.2, b = 3.4, c = 5.6;
00615         WValue< double > value1( size );
00616         WValue< double > value2( size );
00617         WValue< double > value3( size );
00618         const double scalar = 32.32;
00619 
00620         value1[0] = a;
00621         value1[1] = b;
00622         value1[2] = c;
00623 
00624 
00625         // test scaling with scalar right hand side
00626         value2 = value1 * scalar;
00627         value3 = scalar * value1;
00628 
00629         TS_ASSERT_EQUALS( value2, value3 );
00630     }
00631 
00632     /**
00633      * Every WValue should have an operator<< for writing to ostreams
00634      */
00635     void testOutputStreamOperator( void )
00636     {
00637         WValue< double > val( 2 );
00638         val[0] = 1.;
00639         val[1] = 5.;
00640         std::string expected( "[1.0000000000000000e+00, 5.0000000000000000e+00]" );
00641         std::stringstream ss;
00642         ss << val;
00643         TS_ASSERT_EQUALS( ss.str(), expected );
00644     }
00645 
00646     /**
00647      * Test the mean calculation.
00648      */
00649     void testMean( void )
00650     {
00651         WValue< double > val( 3 );
00652         val[0] = 1.0;
00653         val[1] = 2.0;
00654         val[2] = 3.0;
00655         TS_ASSERT_EQUALS( val.mean(), 2.0 );
00656     }
00657 
00658     /**
00659      * Test the median calculation.
00660      */
00661     void testMedian( void )
00662     {
00663         WValue< double > val( 3 );
00664         val[0] = 1.0;
00665         val[1] = 2.0;
00666         val[2] = 3.0;
00667         TS_ASSERT_EQUALS( val.mean(), 2.0 );
00668     }
00669 };
00670 
00671 #endif  // WVALUE_TEST_H