1 /*
2  [auto_generated]
3  libs/numeric/odeint/test/integrate_overflow.cpp
4 
5  [begin_description]
6  This file tests the overflow exception of the integrate functions.
7  [end_description]
8 
9  Copyright 2015 Mario Mulansky
10 
11  Distributed under the Boost Software License, Version 1.0.
12  (See accompanying file LICENSE_1_0.txt or
13  copy at http://www.boost.org/LICENSE_1_0.txt)
14  */
15 
16 
17 #define BOOST_TEST_MODULE odeint_integrate_overflow
18 
19 #include <boost/test/unit_test.hpp>
20 
21 #include <utility>
22 #include <iostream>
23 #include <vector>
24 
25 
26 #include <vector>
27 #include <cmath>
28 #include <iostream>
29 
30 #include <boost/iterator/counting_iterator.hpp>
31 
32 #include <boost/numeric/odeint.hpp>
33 
34 
35 using namespace boost::numeric::odeint;
36 
37 
38 typedef double value_type;
39 typedef std::vector< value_type > state_type;
40 
41 // the famous lorenz system as usual
lorenz(const state_type & x,state_type & dxdt,const value_type t)42 void lorenz( const state_type &x , state_type &dxdt , const value_type t )
43 {
44     //const value_type sigma( 10.0 );
45     const value_type R( 28.0 );
46     const value_type b( value_type( 8.0 ) / value_type( 3.0 ) );
47 
48     // first component trivial
49     dxdt[0] = 1.0; //sigma * ( x[1] - x[0] );
50     dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
51     dxdt[2] = -b * x[2] + x[0] * x[1];
52 }
53 
54 struct push_back_time
55 {
56     std::vector< double >& m_times;
57 
push_back_timepush_back_time58     push_back_time( std::vector< double > &times )
59             :  m_times( times ) { }
60 
operator ()push_back_time61     void operator()( const state_type &x , double t )
62     {
63         m_times.push_back( t );
64     }
65 };
66 
67 typedef runge_kutta_dopri5<state_type> stepper_type;
68 typedef runge_kutta_cash_karp54<state_type> cash_karp_type;
69 
70 
71 BOOST_AUTO_TEST_SUITE( integrate_overflow )
72 
BOOST_AUTO_TEST_CASE(test_integrate_const)73 BOOST_AUTO_TEST_CASE( test_integrate_const )
74 {
75     state_type x(3, 5.0);
76     std::vector<double> times;
77 
78     // check the function signatures with normal stepper
79     integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0);
80     integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer());
81     // no exceptions expected for normal steppers
82     integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer(), max_step_checker(10));
83 
84 
85     // check exceptions for controlled stepper
86     integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0);
87     // very small error terms -> standard overflow threshold of 500 should fire an exception
88     BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x,
89                                       0.0, 10.0, 1.0, push_back_time(times), max_step_checker()),
90                       std::runtime_error);
91     // small threshold of 10 -> larger error still gives an exception
92     BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x,
93                                       0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)),
94                       std::runtime_error);
95 
96     // check exceptions for dense output stepper
97     integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0);
98     integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0);
99     // very small error terms -> standard overflow threshold of 500 should fire an exception
100     BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x,
101                                       0.0, 10.0, 1.0, push_back_time(times), max_step_checker()),
102                       std::runtime_error);
103     // small threshold of 10 -> larger error still gives an exception
104     BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x,
105                                       0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)),
106                       std::runtime_error);
107 }
108 
BOOST_AUTO_TEST_CASE(test_integrate_n_steps)109 BOOST_AUTO_TEST_CASE( test_integrate_n_steps )
110 {
111     state_type x(3, 5.0);
112     std::vector<double> times;
113 
114     // check the function signatures with normal stepper
115     integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10);
116     integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer());
117     // no exceptions expected for normal steppers
118     integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer(), max_step_checker(10));
119 
120 
121     // check exceptions for controlled stepper
122     integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10);
123     // very small error terms -> standard overflow threshold of 500 should fire an exception
124     BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x,
125                                         0.0, 1.0, 10, push_back_time(times), max_step_checker()),
126                       std::runtime_error);
127     // small threshold of 10 -> larger error still gives an exception
128     BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x,
129                                         0.0, 1.0, 10, push_back_time(times), max_step_checker(10)),
130                       std::runtime_error);
131 
132     // check exceptions for dense output stepper
133     integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10);
134     integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10, push_back_time(times));
135     // very small error terms -> standard overflow threshold of 500 should fire an exception
136     BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x,
137                                         0.0, 1.0, 10, push_back_time(times), max_step_checker()),
138                       std::runtime_error);
139     // small threshold of 10 -> larger error still gives an exception
140     BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x,
141                                         0.0, 1.0, 10, push_back_time(times), max_step_checker(10)),
142                       std::runtime_error);
143 }
144 
BOOST_AUTO_TEST_CASE(test_integrate_times)145 BOOST_AUTO_TEST_CASE( test_integrate_times )
146 {
147     state_type x(3, 5.0);
148     std::vector<double> times;
149     boost::counting_iterator<int> t0(0);
150     boost::counting_iterator<int> t1(10);
151 
152     // check the function signatures with normal stepper
153     integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times));
154     // no exceptions expected for big enough step size
155     integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times), max_step_checker(10));
156     // if dt*max_steps < observer time difference we expect an exception
157     BOOST_CHECK_THROW(integrate_times(stepper_type(), lorenz, x, t0, t1, 0.01, push_back_time(times),
158                                       max_step_checker(10)),
159                       std::runtime_error);
160 
161     // check exceptions for controlled stepper
162     // no exception if no checker is provided
163     integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times));
164     // very small error terms -> standard overflow threshold of 500 should fire an exception
165     BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x,
166                                       t0, t1, 1.0 , push_back_time(times), max_step_checker()),
167                       std::runtime_error);
168 
169     // small threshold of 10 -> larger error still gives an exception
170     BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x,
171                                       t0, t1, 1.0 , push_back_time(times), max_step_checker(10)),
172                       std::runtime_error);
173 
174     // check cash karp controlled stepper
175     // no exception if no checker is provided
176     integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times));
177     // very small error terms -> standard overflow threshold of 500 should fire an exception
178     BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-15, 1E-15), lorenz, x,
179                       t0, t1, 1.0 , push_back_time(times), max_step_checker()),
180     std::runtime_error);
181 
182     // small threshold of 10 -> larger error still gives an exception
183     BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x,
184                       t0, t1, 1.0 , push_back_time(times), max_step_checker(10)),
185     std::runtime_error);
186 
187     // check exceptions for dense output stepper
188     integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 ,
189                     push_back_time(times));
190     // very small error terms -> standard overflow threshold of 500 should fire an exception
191     BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x,
192                                       t0, t1, 1.0 , push_back_time(times), max_step_checker()),
193                       std::runtime_error);
194     // small threshold of 10 -> larger error still gives an exception
195     BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x,
196                                       t0, t1, 1.0 , push_back_time(times), max_step_checker(10)),
197                       std::runtime_error);
198 }
199 
200 BOOST_AUTO_TEST_SUITE_END()