0022904: Clean up sccsid variables
[occt.git] / src / math / math_BracketMinimum.cxx
1 #include <math_BracketMinimum.ixx>
2
3 #include <StdFail_NotDone.hxx>   // waiting for NotDone Exception
4 #include <math_Function.hxx>
5
6 #define GOLD           1.618034
7 #define CGOLD          0.3819660
8 #define GLIMIT         100.0
9 #define TINY           1.0e-20
10 #ifdef MAX
11 #undef MAX
12 #endif
13 #define MAX(a,b)       ((a) > (b) ? (a) : (b))
14 #define SIGN(a,b)      ((b) > 0.0 ? fabs(a) : -fabs(a))
15 #define SHFT(a,b,c,d)  (a)=(b);(b)=(c);(c)=(d)
16
17
18     void math_BracketMinimum::Perform(math_Function& F, 
19                                       const Standard_Real A, 
20                                       const Standard_Real B) {
21
22      Standard_Boolean OK;
23      Standard_Real ulim, u, r, q, f, fu, dum;
24
25      Done = Standard_False; 
26      Ax = A;
27      Bx = B;
28      Standard_Real Lambda = GOLD;
29      if (!myFA) {
30        OK = F.Value(Ax, FAx);
31        if(!OK) return;
32      }
33      if (!myFB) {
34        OK = F.Value(Bx, FBx);
35        if(!OK) return;
36      }
37      if(FBx > FAx) {
38        SHFT(dum, Ax, Bx, dum);
39        SHFT(dum, FBx, FAx, dum);
40      }
41      Cx = Bx + Lambda * (Bx - Ax);
42      OK = F.Value(Cx, FCx);
43      if(!OK) return;
44      while(FBx > FCx) {
45        r = (Bx - Ax) * (FBx -FCx);
46        q = (Bx - Cx) * (FBx -FAx);
47        u = Bx - ((Bx - Cx) * q - (Bx - Ax) * r) / 
48            (2.0 * SIGN(MAX(fabs(q - r), TINY), q - r));
49        ulim = Bx + GLIMIT * (Cx - Bx);
50        if((Bx - u) * (u - Cx) > 0.0) {
51          OK = F.Value(u, fu);
52          if(!OK) return;
53          if(fu < FCx) {
54            Ax = Bx;
55            Bx = u;
56            FAx = FBx;
57            FBx = fu;
58            Done = Standard_True;
59            return;
60          }
61          else if(fu > FBx) {
62            Cx = u;
63            FCx = fu;
64            Done = Standard_True;
65            return;
66          }
67          u = Cx + Lambda * (Cx - Bx);
68          OK = F.Value(u, fu);
69          if(!OK) return;
70        }
71        else if((Cx - u) * (u - ulim) > 0.0) {
72          OK = F.Value(u, fu);
73          if(!OK) return;
74          if(fu < FCx) {
75            SHFT(Bx, Cx, u, Cx + GOLD * (Cx - Bx));
76            OK = F.Value(u, f);
77            if(!OK) return;
78            SHFT(FBx, FCx, fu, f);
79          }
80        }
81        else if ((u - ulim) * (ulim - Cx) >= 0.0) {
82          u = ulim;
83          OK = F.Value(u, fu);
84          if(!OK) return;
85        }
86        else {
87          u = Cx + GOLD * (Cx - Bx);
88          OK = F.Value(u, fu);
89          if(!OK) return;
90        }
91        SHFT(Ax, Bx, Cx, u);
92        SHFT(FAx, FBx, FCx, fu);
93      }
94      Done = Standard_True;
95    }
96
97
98
99
100     math_BracketMinimum::math_BracketMinimum(math_Function& F, 
101                                              const Standard_Real A, 
102                                              const Standard_Real B) {
103
104       myFA = Standard_False;
105       myFB = Standard_False;
106       Perform(F, A, B);
107     }
108
109     math_BracketMinimum::math_BracketMinimum(math_Function& F, 
110                                              const Standard_Real A, 
111                                              const Standard_Real B,
112                                              const Standard_Real FA) {
113       FAx = FA;
114       myFA = Standard_True;
115       myFB = Standard_False;
116       Perform(F, A, B);
117     }
118
119     math_BracketMinimum::math_BracketMinimum(math_Function& F, 
120                                              const Standard_Real A, 
121                                              const Standard_Real B,
122                                              const Standard_Real FA,
123                                              const Standard_Real FB) {
124       FAx = FA;
125       FBx = FB;
126       myFA = Standard_True;
127       myFB = Standard_True;
128       Perform(F, A, B);
129     }
130
131
132     void math_BracketMinimum::Values(Standard_Real& A, Standard_Real& B, Standard_Real& C) const{
133
134       StdFail_NotDone_Raise_if(!Done, " ");
135       A = Ax;
136       B = Bx;
137       C = Cx;
138     }
139
140     void math_BracketMinimum::FunctionValues(Standard_Real& FA, Standard_Real& FB, Standard_Real& FC) const{
141
142       StdFail_NotDone_Raise_if(!Done, " ");
143       FA = FAx;
144       FB = FBx;
145       FC = FCx;
146     }
147
148     void math_BracketMinimum::Dump(Standard_OStream& o) const {
149
150        o << "math_BracketMinimum ";
151        if(Done) {
152          o << " Status = Done \n";
153          o << " The bracketed triplet is: " << endl;
154          o << Ax << ", " << Bx << ", " << Cx << endl;
155          o << " The corresponding function values are: "<< endl;
156          o << FAx << ", " << FBx << ", " << FCx << endl;
157        }
158        else {
159          o << " Status = not Done \n";
160        }
161 }
162