OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
solution.cpp
Go to the documentation of this file.
1 //$$ solution.cpp // solve routines
2 
3 // Copyright (C) 1994: R B Davies
4 
5 
6 #define WANT_STREAM // include.h will get stream fns
7 #define WANT_MATH // include.h will get math fns
8 
9 #include <cmath>
10 #include <ossim/matrix/include.h>
11 #include <ossim/matrix/myexcept.h>
12 
13 #include <ossim/matrix/solution.h>
14 
15 #ifdef use_namespace
16 namespace RBD_COMMON {
17 #endif
18 
20 {
21 }
22 
24 {
25  if ((!minXinf && X <= minX) || (!maxXinf && X >= maxX))
26  Throw(SolutionException("X value out of range"));
27  x = X; xSet = true;
28 }
29 
30 R1_R1::operator Real()
31 {
32  if (!xSet) Throw(SolutionException("Value of X not set"));
33  Real y = operator()();
34  return y;
35 }
36 
37 unsigned long SolutionException::Select;
38 
39 SolutionException::SolutionException(const char* a_what) : Exception()
40 {
41  Select = Exception::Select;
42  AddMessage("Error detected by solution package\n");
43  AddMessage(a_what); AddMessage("\n");
44  if (a_what) Tracer::AddTrace();
45 };
46 
47 inline Real square(Real x) { return x*x; }
48 
50 {
51  lim--;
52  if (!lim) Throw(SolutionException("Does not converge"));
53  Last = V;
54  Real yy = function(x[V]) - YY;
55  Finish = (std::fabs(yy) <= accY) ||
56  (Captured && std::fabs(x[L]-x[U]) <= accX );
57  y[V] = vpol*yy;
58 }
59 
61 
63  { vpol = -vpol; y[0] = -y[0]; y[1] = -y[1]; y[2] = -y[2]; }
64 
66 {
67  hpol=-hpol; vpol=-vpol; State(U,C,L);
68  y[0] = -y[0]; y[1] = -y[1]; y[2] = -y[2];
69 }
70 
71 void OneDimSolve::State(int I, int J, int K) { L=I; C=J; U=K; }
72 
73 void OneDimSolve::Linear(int I, int J, int K)
74 {
75  x[J] = (x[I]*y[K] - x[K]*y[I])/(y[K] - y[I]);
76  // cout << "Linear\n";
77 }
78 
79 void OneDimSolve::Quadratic(int I, int J, int K)
80 {
81  // result to overwrite I
82  Real YJK, YIK, YIJ, XKI, XKJ;
83  YJK = y[J] - y[K]; YIK = y[I] - y[K]; YIJ = y[I] - y[J];
84  XKI = (x[K] - x[I]);
85  XKJ = (x[K]*y[J] - x[J]*y[K])/YJK;
86  if ( square(YJK/YIK)>(x[K] - x[J])/XKI ||
87  square(YIJ/YIK)>(x[J] - x[I])/XKI )
88  {
89  x[I] = XKJ;
90  // cout << "Quadratic - exceptional\n";
91  }
92  else
93  {
94  XKI = (x[K]*y[I] - x[I]*y[K])/YIK;
95  x[I] = (XKJ*y[I] - XKI*y[J])/YIJ;
96  // cout << "Quadratic - normal\n";
97  }
98 }
99 
100 Real OneDimSolve::Solve(Real Y, Real X, Real Dev, int Lim)
101 {
102  enum Loop { start, captured1, captured2, binary, finish };
103  Tracer et("OneDimSolve::Solve");
104  lim=Lim; Captured = false;
105  if (Dev==0.0) Throw(SolutionException("Dev is zero"));
106  L=0; C=1; U=2; vpol=1; hpol=1; y[C]=0.0; y[U]=0.0;
107  if (Dev<0.0) { hpol=-1; Dev = -Dev; }
108  YY=Y; // target value
109  x[L] = X; // initial trial value
110  if (!function.IsValid(X))
111  Throw(SolutionException("Starting value is invalid"));
112  Loop TheLoop = start;
113  for (;;)
114  {
115  switch (TheLoop)
116  {
117  case start:
118  LookAt(L); if (Finish) { TheLoop = finish; break; }
119  if (y[L]>0.0) VFlip(); // so Y[L] < 0
120 
121  x[U] = X + Dev * hpol;
122  if (!function.maxXinf && x[U] > function.maxX)
123  x[U] = (function.maxX + X) / 2.0;
124  if (!function.minXinf && x[U] < function.minX)
125  x[U] = (function.minX + X) / 2.0;
126 
127  LookAt(U); if (Finish) { TheLoop = finish; break; }
128  if (y[U] > 0.0) { TheLoop = captured1; Captured = true; break; }
129  if (y[U] == y[L])
130  Throw(SolutionException("Function is flat"));
131  if (y[U] < y[L]) HFlip(); // Change direction
132  State(L,U,C);
133  for (i=0; i<20; i++)
134  {
135  // cout << "Searching for crossing point\n";
136  // Have L C then crossing point, Y[L]<Y[C]<0
137  x[U] = x[C] + Dev * hpol;
138  if (!function.maxXinf && x[U] > function.maxX)
139  x[U] = (function.maxX + x[C]) / 2.0;
140  if (!function.minXinf && x[U] < function.minX)
141  x[U] = (function.minX + x[C]) / 2.0;
142 
143  LookAt(U); if (Finish) { TheLoop = finish; break; }
144  if (y[U] > 0) { TheLoop = captured2; Captured = true; break; }
145  if (y[U] < y[C])
146  Throw(SolutionException("Function is not monotone"));
147  Dev *= 2.0;
148  State(C,U,L);
149  }
150  if (TheLoop != start ) break;
151  Throw(SolutionException("Cannot locate a crossing point"));
152 
153  case captured1:
154  // cout << "Captured - 1\n";
155  // We have 2 points L and U with crossing between them
156  Linear(L,C,U); // linear interpolation
157  // - result to C
158  LookAt(C); if (Finish) { TheLoop = finish; break; }
159  if (y[C] > 0.0) Flip(); // Want y[C] < 0
160  if (y[C] < 0.5*y[L]) { State(C,L,U); TheLoop = binary; break; }
161 
162  case captured2:
163  // cout << "Captured - 2\n";
164  // We have L,C before crossing, U after crossing
165  Quadratic(L,C,U); // quad interpolation
166  // - result to L
167  State(C,L,U);
168  if ((x[C] - x[L])*hpol <= 0.0 || (x[C] - x[U])*hpol >= 0.0)
169  { TheLoop = captured1; break; }
170  LookAt(C); if (Finish) { TheLoop = finish; break; }
171  // cout << "Through first stage\n";
172  if (y[C] > 0.0) Flip();
173  if (y[C] > 0.5*y[L]) { TheLoop = captured2; break; }
174  else { State(C,L,U); TheLoop = captured1; break; }
175 
176  case binary:
177  // We have L, U around crossing - do binary search
178  // cout << "Binary\n";
179  for (i=3; i; i--)
180  {
181  x[C] = 0.5*(x[L]+x[U]);
182  LookAt(C); if (Finish) { TheLoop = finish; break; }
183  if (y[C]>0.0) State(L,U,C); else State(C,L,U);
184  }
185  if (TheLoop != binary) break;
186  TheLoop = captured1; break;
187 
188  case finish:
189  return x[Last];
190 
191  }
192  }
193 }
194 
196 {
197  Set(X);
198  return (minXinf || x > minX) && (maxXinf || x < maxX);
199 }
200 
201 #ifdef use_namespace
202 }
203 #endif
204 
ossim_uint32 x
double Real
Definition: include.h:57
Real accX
Definition: solution.h:56
int hpol
Definition: solution.h:74
bool minXinf
Definition: solution.h:35
ossim_uint32 y
int Last
Definition: solution.h:73
Real y[3]
Definition: solution.h:72
bool Finish
Definition: solution.h:78
Real minX
Definition: solution.h:34
Real maxX
Definition: solution.h:34
Real x[3]
Definition: solution.h:72
SolutionException(const char *a_what=0)
Definition: solution.cpp:39
int vpol
Definition: solution.h:74
void State(int I, int J, int K)
Definition: solution.cpp:71
static void AddTrace()
Definition: myexcept.cpp:110
bool maxXinf
Definition: solution.h:35
virtual void Set(Real X)
Definition: solution.cpp:23
void VFlip()
Definition: solution.cpp:62
void Linear(int, int, int)
Definition: solution.cpp:73
Real x
Definition: solution.h:28
virtual bool IsValid(Real X)
Definition: solution.cpp:195
Real YY
Definition: solution.h:75
static unsigned long Select
Definition: solution.h:49
void LookAt(int)
Definition: solution.cpp:49
Real square(Real x)
Definition: solution.cpp:47
bool Captured
Definition: solution.h:79
void HFlip()
Definition: solution.cpp:60
virtual ~R1_R1()
Definition: solution.cpp:19
void Quadratic(int, int, int)
Definition: solution.cpp:79
Real accY
Definition: solution.h:57
void Flip()
Definition: solution.cpp:65
Real Solve(Real Y, Real X, Real Dev, int Lim=100)
Definition: solution.cpp:100