OpenWalnut  1.5.0dev
WPolynomialEquationSolvers_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WPOLYNOMIALEQUATIONSOLVERS_TEST_H
26 #define WPOLYNOMIALEQUATIONSOLVERS_TEST_H
27 
28 #include <iomanip>
29 #include <sstream>
30 #include <string>
31 #include <utility>
32 
33 #include <cxxtest/TestSuite.h>
34 
35 #include "../WPolynomialEquationSolvers.h"
36 
37 /**
38  * Testsuite for the WPolynomialEquationSolvers functions
39  */
40 class WPolynomialEquationSolversTest : public CxxTest::TestSuite
41 {
42 public:
43  /**
44  * If there is no solution an exception should be thrown.
45  */
47  {
48  TS_ASSERT_THROWS_EQUALS( solveRealQuadraticEquation( 0.0, 0.0, 1.0 ), const WEquationHasNoRoots &e,
49  std::string( e.what() ), "The equation: 0x^2 + 0x + 1 = 0.0 has no solutions!" );
50  }
51 
52  /**
53  * x^2 = 0 has only one solution: 0.0.
54  */
56  {
57  typedef std::pair< std::complex< double >, std::complex< double > > ComplexPair;
58  ComplexPair actual = solveRealQuadraticEquation( 1.0, 0.0, 0.0 );
59  TS_ASSERT_EQUALS( actual.first, std::complex< double >( 0.0, 0.0 ) );
60  TS_ASSERT_EQUALS( actual.second, actual.first );
61  }
62 
63  /**
64  * x^2 - 1 = 0 has two solutions: 1.0 and -1.0.
65  */
67  {
68  typedef std::pair< std::complex< double >, std::complex< double > > ComplexPair;
69  ComplexPair actual = solveRealQuadraticEquation( 1.0, 0.0, -1.0 );
70  ComplexPair expected = ComplexPair( std::complex< double >( -1.0, 0.0 ), std::complex< double >( 1.0, 0.0 ) );
71  if( actual.first != expected.first )
72  {
73  std::cout << std::endl << "We assume the order of the pair is swaped, but both solutions are right" << std::endl;
74  TS_ASSERT_EQUALS( actual.first, expected.second );
75  TS_ASSERT_EQUALS( actual.second, expected.first );
76  }
77  else
78  {
79  TS_ASSERT_EQUALS( actual.first, expected.first );
80  TS_ASSERT_EQUALS( actual.second, expected.second );
81  }
82  }
83 
84  /**
85  * x^2 + 1 = 0 has two solutions: i and -i.
86  */
88  {
89  typedef std::pair< std::complex< double >, std::complex< double > > ComplexPair;
90  ComplexPair actual = solveRealQuadraticEquation( 1.0, 0.0, 1.0 );
91  ComplexPair expected = ComplexPair( std::complex< double >( 0.0, 1.0 ), std::complex< double >( 0.0, -1.0 ) );
92  if( actual.first != expected.first )
93  {
94  std::cout << std::endl << "We assume the order of the pair is swaped, but both solutions are right" << std::endl;
95  TS_ASSERT_EQUALS( actual.first, expected.second );
96  TS_ASSERT_EQUALS( actual.second, expected.first );
97  }
98  else
99  {
100  TS_ASSERT_EQUALS( actual.first, expected.first );
101  TS_ASSERT_EQUALS( actual.second, expected.second );
102  }
103  }
104 
105  /**
106  * This test numerical stability:
107  * x^2 + 9999999999x -9e10 = 0, has solutions according to wolfram alpha:
108  * x_1 = -1.00000000079999999928x10^10
109  * x_2 = 8.99999999280000001224
110  */
112  {
113  typedef std::pair< std::complex< double >, std::complex< double > > ComplexPair;
114  ComplexPair actual = solveRealQuadraticEquation( 1.0, 9999999999.0, -9.0e10 );
115  ComplexPair expected = ComplexPair( std::complex< double >( -1.00000000079999999928e10, 0.0 ), std::complex< double >( 8.99999999280000001224, 0.0 ) ); // NOLINT line length
116  double delta = 0.00000001; // This precision was found by trial and error
117  if( ( ( std::abs( actual.first - expected.first ) > delta ) && ( std::abs( actual.first - expected.second ) > delta ) ) ||
118  ( ( std::abs( actual.second - expected.second ) > delta ) && ( std::abs( actual.second - expected.first ) > delta ) ) )
119  {
120  std::stringstream ss;
121  ss << std::fixed << std::setprecision( 16 ) << std::endl;
122  ss << "Invalid solutions: " << std::endl;
123  ss << std::real( actual.first ) << " i" << std::imag( actual.first ) << " :::: ";
124  ss << std::real( actual.second ) << " i" << std::imag( actual.second ) << std::endl;
125  ss << " were invalid. I expected: " << std::endl;
126  ss << std::real( expected.first ) << " i" << std::imag( expected.first ) << " :::: ";
127  ss << std::real( expected.second ) << " i" << std::imag( expected.second ) << std::endl;
128  std::cout << ss.str();
129  TS_FAIL( "Check your numerical stability and the order of the solutions found." );
130  }
131  }
132 };
133 
134 #endif // WPOLYNOMIALEQUATIONSOLVERS_TEST_H
Indicates invalid element access of a container.
virtual const char * what() const
Returns the message string set on throw.
Definition: WException.cpp:90
Testsuite for the WPolynomialEquationSolvers functions.
void testRealQuadraticEquationToTestNumericalIssuesAndPrecisions(void)
This test numerical stability: x^2 + 9999999999x -9e10 = 0, has solutions according to wolfram alpha:...
void testRealQuadraticEquationWithTwoImaginarySolutions(void)
x^2 + 1 = 0 has two solutions: i and -i.
void testRealQuadraticEquationWithTwoRealSolutions(void)
x^2 - 1 = 0 has two solutions: 1.0 and -1.0.
void testRealQuadraticEquationWithNoSolution(void)
If there is no solution an exception should be thrown.
void testRealQuadraticEquationWithOnlyOneSolution(void)
x^2 = 0 has only one solution: 0.0.