GteRootsBisection.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <GTEngineDEF.h>
11 #include <functional>
12 
13 // Compute a root of a function F(t) on an interval [t0, t1]. The caller
14 // specifies the maximum number of iterations, in case you want limited
15 // accuracy for the root. However, the function is designed for native types
16 // (Real = float/double). If you specify a sufficiently large number of
17 // iterations, the root finder bisects until either F(t) is identically zero
18 // [a condition dependent on how you structure F(t) for evaluation] or the
19 // midpoint (t0 + t1)/2 rounds numerically to tmin or tmax. Of course, it
20 // is required that t0 < t1. The return value of Find is:
21 // 0: F(t0)*F(t1) > 0, we cannot determine a root
22 // 1: F(t0) = 0 or F(t1) = 0
23 // 2..maxIterations: the number of bisections plus one
24 // maxIterations+1: the loop executed without a break (no convergence)
25 
26 namespace gte
27 {
28 
29 template <typename Real>
31 {
32 public:
33  // Use this function when F(t0) and F(t1) are not already known.
34  static unsigned int Find(std::function<Real(Real)> const& F, Real t0,
35  Real t1, unsigned int maxIterations, Real& root);
36 
37  // If f0 = F(t0) and f1 = F(t1) are already known, pass them to the
38  // bisector. This is useful when |f0| or |f1| is infinite, and you can
39  // pass sign(f0) or sign(f1) rather than then infinity because the
40  // bisector cares only about the signs of f.
41  static unsigned int Find(std::function<Real(Real)> const& F, Real t0,
42  Real t1, Real f0, Real f1, unsigned int maxIterations, Real& root);
43 };
44 
45 
46 template <typename Real>
47 unsigned int RootsBisection<Real>::Find(std::function<Real(Real)> const& F,
48  Real t0, Real t1, unsigned int maxIterations, Real& root)
49 {
50  if (t0 < t1)
51  {
52  // Test the endpoints to see whether F(t) is zero.
53  Real f0 = F(t0);
54  if (f0 == (Real)0)
55  {
56  root = t0;
57  return 1;
58  }
59 
60  Real f1 = F(t1);
61  if (f1 == (Real)0)
62  {
63  root = t1;
64  return 1;
65  }
66 
67  if (f0*f1 > (Real)0)
68  {
69  // It is not known whether the interval bounds a root.
70  return 0;
71  }
72 
73  unsigned int i;
74  for (i = 2; i <= maxIterations; ++i)
75  {
76  root = ((Real)0.5) * (t0 + t1);
77  if (root == t0 || root == t1)
78  {
79  // The numbers t0 and t1 are consecutive floating-point
80  // numbers.
81  break;
82  }
83 
84  Real fm = F(root);
85  Real product = fm * f0;
86  if (product < (Real)0)
87  {
88  t1 = root;
89  f1 = fm;
90  }
91  else if (product > (Real)0)
92  {
93  t0 = root;
94  f0 = fm;
95  }
96  else
97  {
98  break;
99  }
100  }
101  return i;
102  }
103  else
104  {
105  return 0;
106  }
107 }
108 
109 template <typename Real>
110 unsigned int RootsBisection<Real>::Find(std::function<Real(Real)> const& F,
111  Real t0, Real t1, Real f0, Real f1, unsigned int maxIterations,
112  Real& root)
113 {
114  if (t0 < t1)
115  {
116  // Test the endpoints to see whether F(t) is zero.
117  if (f0 == (Real)0)
118  {
119  root = t0;
120  return 1;
121  }
122 
123  if (f1 == (Real)0)
124  {
125  root = t1;
126  return 1;
127  }
128 
129  if (f0*f1 > (Real)0)
130  {
131  // It is not known whether the interval bounds a root.
132  return 0;
133  }
134 
135  unsigned int i;
136  for (i = 2; i <= maxIterations; ++i)
137  {
138  root = ((Real)0.5) * (t0 + t1);
139  if (root == t0 || root == t1)
140  {
141  // The numbers t0 and t1 are consecutive floating-point
142  // numbers.
143  break;
144  }
145 
146  Real fm = F(root);
147  Real product = fm * f0;
148  if (product < (Real)0)
149  {
150  t1 = root;
151  f1 = fm;
152  }
153  else if (product >(Real)0)
154  {
155  t0 = root;
156  f0 = fm;
157  }
158  else
159  {
160  break;
161  }
162  }
163  return i;
164  }
165  else
166  {
167  return 0;
168  }
169 }
170 
171 
172 }
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition: glext.h:9013
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glext.h:9013
static unsigned int Find(std::function< Real(Real)> const &F, Real t0, Real t1, unsigned int maxIterations, Real &root)


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01