0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / math / math_Powell.cxx
1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //#ifndef OCCT_DEBUG
16 #define No_Standard_RangeError
17 #define No_Standard_OutOfRange
18 #define No_Standard_DimensionError
19
20 //#endif
21
22 #include <math_BracketMinimum.hxx>
23 #include <math_BrentMinimum.hxx>
24 #include <math_Function.hxx>
25 #include <math_MultipleVarFunction.hxx>
26 #include <math_Powell.hxx>
27
28 namespace {
29 static inline Standard_Real SQR (const Standard_Real a)
30 {
31     return a * a;
32 }
33 }
34
35 class DirFunctionBis : public math_Function {
36
37   math_Vector *P0;
38   math_Vector *Dir;
39   math_Vector *P;
40   math_MultipleVarFunction *F;
41
42   public :
43     DirFunctionBis(math_Vector& V1,
44                 math_Vector& V2,
45                 math_Vector& V3,
46                 math_MultipleVarFunction& f);
47
48     void Initialize(const math_Vector& p0, const math_Vector& dir);
49
50     virtual Standard_Boolean Value(const Standard_Real x, Standard_Real& fval);
51 };
52
53  DirFunctionBis::DirFunctionBis(math_Vector& V1,
54                           math_Vector& V2,
55                           math_Vector& V3,
56                           math_MultipleVarFunction& f) {
57    P0 = &V1;
58    Dir = &V2;
59    P = &V3;
60    F = &f;
61  }
62
63
64 void DirFunctionBis::Initialize(const math_Vector& p0,
65                              const math_Vector& dir) {
66
67   *P0 = p0;
68   *Dir = dir;
69 }
70
71 Standard_Boolean DirFunctionBis::Value(const Standard_Real x, Standard_Real& fval) {
72   *P = *Dir;
73   P->Multiply(x);
74   P->Add(*P0);
75
76   fval = 0.0;
77   return F->Value(*P, fval);
78 }
79
80
81 static Standard_Boolean MinimizeDirection(math_Vector& P,
82                                  math_Vector& Dir,
83                                  Standard_Real& Result,
84                                  DirFunctionBis& F) {
85
86   Standard_Real ax;
87   Standard_Real xx;
88   Standard_Real bx;
89
90
91   F.Initialize(P, Dir);
92
93   math_BracketMinimum Bracket(F, 0.0, 1.0);
94   if (Bracket.IsDone()) {
95     Bracket.Values(ax, xx, bx);
96     math_BrentMinimum Sol(1.0e-10);
97     Sol.Perform(F, ax, xx, bx);
98     if (Sol.IsDone()) {
99       Standard_Real Scale = Sol.Location();
100       Result = Sol.Minimum();
101       Dir.Multiply(Scale);
102       P.Add(Dir);
103       return Standard_True;
104     }
105   }
106   return Standard_False;
107 }
108
109 //=======================================================================
110 //function : math_Powell
111 //purpose  : Constructor
112 //=======================================================================
113 math_Powell::math_Powell(const math_MultipleVarFunction& theFunction,
114                          const Standard_Real             theTolerance,
115                          const Standard_Integer          theNbIterations,
116                          const Standard_Real             theZEPS)
117 : TheLocation     (1, theFunction.NbVariables()),
118   TheMinimum      (RealLast()),
119   TheLocationError(RealLast()),
120   PreviousMinimum (RealLast()),
121   XTol            (theTolerance),
122   EPSZ            (theZEPS),
123   Done            (Standard_False),
124   Iter            (0),
125   TheStatus       (math_NotBracketed),
126   TheDirections   (1, theFunction.NbVariables(), 1, theFunction.NbVariables()),
127   State           (0),
128   Itermax         (theNbIterations)
129 {
130 }
131
132 //=======================================================================
133 //function : ~math_Powell
134 //purpose  : Destructor
135 //=======================================================================
136 math_Powell::~math_Powell()
137 {
138 }
139
140 //=======================================================================
141 //function : Perform
142 //purpose  : 
143 //=======================================================================
144 void math_Powell::Perform(math_MultipleVarFunction& F,
145                           const math_Vector& StartingPoint,
146                           const math_Matrix& StartingDirections)
147 {
148   Done = Standard_False;
149   Standard_Integer i, ibig, j;
150   Standard_Real t, fptt, del;
151   Standard_Integer n = TheLocation.Length();
152   math_Vector pt(1,n);
153   math_Vector ptt(1,n);
154   math_Vector xit(1,n);
155   math_Vector Temp1(1, n);
156   math_Vector Temp2(1, n);
157   math_Vector Temp3(1, n);
158   DirFunctionBis F_Dir(Temp1, Temp2, Temp3, F);
159
160   TheLocation = StartingPoint;
161   TheDirections = StartingDirections;
162   pt = TheLocation;  //sauvegarde du point initial
163
164
165   for(Iter = 1; Iter<= Itermax; Iter++) {
166     F.Value(TheLocation, PreviousMinimum);
167     ibig = 0;
168     del = 0.0;
169     for (i = 1; i <= n; i++){
170       for(j =1; j<= n; j++) xit(j) = TheDirections(j,i);
171       F.Value(TheLocation, fptt); 
172       Standard_Boolean IsGood = MinimizeDirection(TheLocation, xit, 
173                                          TheMinimum, F_Dir);
174
175       if (!IsGood) {
176         Done = Standard_False;
177         TheStatus = math_DirectionSearchError;
178         return;
179       }
180
181       if (fabs(fptt - TheMinimum)> del) {
182         del = fabs(fptt- TheMinimum);
183         ibig = i;
184       }
185     }
186
187     if (IsSolutionReached(F)) {
188       //Termination criterion
189       State = F.GetStateNumber();
190       Done = Standard_True;
191       TheStatus = math_OK;
192       return;
193     }
194
195     if (Iter == Itermax) {
196       Done = Standard_False;
197       TheStatus = math_TooManyIterations;
198       return;
199     }
200
201       ptt = 2.0 * TheLocation - pt;
202       xit = TheLocation - pt;
203       pt = TheLocation;
204     
205     // Valeur de la fonction au point extrapole:
206
207     F.Value(ptt, fptt);
208
209     if (fptt < PreviousMinimum) {
210       t = 2.0 *(PreviousMinimum -2.0*TheMinimum +fptt)*
211         SQR(PreviousMinimum-TheMinimum -del)-del*
212           SQR(PreviousMinimum-fptt);
213       if (t <0.0) {
214         //Minimisation along the direction
215         Standard_Boolean IsGood = MinimizeDirection(TheLocation, xit,
216                                            TheMinimum, F_Dir);
217         if(!IsGood) {
218           Done = Standard_False;
219           TheStatus = math_FunctionError;
220           return;
221         }
222         
223         for(j =1; j <= n; j++) {
224           TheDirections(j, ibig)=xit(j);
225         }
226       }
227     }
228   }
229 }
230
231 //=======================================================================
232 //function : Dump
233 //purpose  : 
234 //=======================================================================
235 void math_Powell::Dump(Standard_OStream& o) const
236 {
237   o << "math_Powell resolution:";
238   if(Done) {
239     o << " Status = Done \n";
240     o << " Location Vector = "<< TheLocation << "\n";
241     o << " Minimum value = " << TheMinimum <<"\n";
242     o << " Number of iterations = " << Iter <<"\n";
243   }
244   else {
245     o << " Status = not Done because " << (Standard_Integer)TheStatus << "\n";
246   }
247 }