NEST main@caf0ae8
 
Loading...
Searching...
No Matches
regula_falsi.h
Go to the documentation of this file.
1/*
2 * regula_falsi.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef REGULA_FALSI_H
24#define REGULA_FALSI_H
25
26
27namespace nest
28{
29
40template < typename CN >
41double
42regula_falsi( const CN& node, const double dt )
43{
44 double root;
45 double threshold_dist_root;
46
47 int last_threshold_sign = 0;
48
49 double a_k = 0.0;
50 double b_k = dt;
51
52 double threshold_dist_a_k = node.threshold_distance( a_k );
53 double threshold_dist_b_k = node.threshold_distance( b_k );
54
55 if ( threshold_dist_a_k * threshold_dist_b_k > 0 )
56 {
57 throw NumericalInstability( "regula_falsi: time step too short to reach threshold." );
58 }
59
60 const int MAX_ITER = 500;
61 const double TERMINATION_CRITERION = 1e-14;
62
63 for ( int iter = 0; iter < MAX_ITER; ++iter )
64 {
65 assert( threshold_dist_b_k != threshold_dist_a_k );
66
67 root = ( a_k * threshold_dist_b_k - b_k * threshold_dist_a_k ) / ( threshold_dist_b_k - threshold_dist_a_k );
68 threshold_dist_root = node.threshold_distance( root );
69
70 if ( std::abs( threshold_dist_root ) < TERMINATION_CRITERION )
71 {
72 return root;
73 }
74
75 if ( threshold_dist_a_k * threshold_dist_root > 0.0 )
76 {
77 // threshold_dist_a_k and threshold_dist_root have the same sign
78 a_k = root;
79 threshold_dist_a_k = threshold_dist_root;
80
81 if ( last_threshold_sign == 1 )
82 {
83 // If threshold_dist_a_k and threshold_dist_root had the same sign in
84 // the last time step, we halve the value of threshold_distance_(b_k) to
85 // force the root in the next time step to occur on b_k's side. This is
86 // done to improve the convergence rate.
87 threshold_dist_b_k /= 2;
88 }
89 last_threshold_sign = 1;
90 }
91 else if ( threshold_dist_b_k * threshold_dist_root > 0.0 )
92 {
93 // threshold_dist_b_k and threshold_dist_root have the same sign
94 b_k = root;
95 threshold_dist_b_k = threshold_dist_root;
96
97 if ( last_threshold_sign == -1 )
98 {
99 threshold_dist_a_k /= 2;
100 }
101 last_threshold_sign = -1;
102 }
103 else
104 {
105 throw NumericalInstability( "regula_falsi: Regula falsi method did not converge" );
106 }
107 }
108 throw NumericalInstability( "regula_falsi: Regula falsi method did not converge during set number of iterations" );
109}
110
111} // namespace nest
112
113#endif // REGULA_FALSI_H
Exception to be thrown if numerical instabilities are detected.
Definition exceptions.h:1063
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
double regula_falsi(const CN &node, const double dt)
Localize threshold crossing by using Illinois algorithm of regula falsi method.
Definition regula_falsi.h:42