0024399: ICC warnings 3280 "declaration hides..."
[occt.git] / src / math / math_FunctionSetRoot.cxx
CommitLineData
b311480e 1// Copyright (c) 1997-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19// pmn 15/05/97 pas de Gauss avec des pivot trop petit. SVD fait mieux
20// l'affaire + limitation de la longeur du pas + qq comentaire issus d'EUCLID3
21// pmn 10/06/97 refonte totale du traitement des bords + ajustement des init
22// et des tolerances pour brent...
23
24//#ifndef DEB
25#define No_Standard_RangeError
26#define No_Standard_OutOfRange
27#define No_Standard_DimensionError
28//#endif
29
30//math_FunctionSetRoot.cxx
31
32
33#include <math_FunctionSetRoot.ixx>
34#include <Standard_DimensionError.hxx>
35#include <math_Gauss.hxx>
36#include <math_SVD.hxx>
37#include <math_GaussLeastSquare.hxx>
38#include <math_IntegerVector.hxx>
39#include <math_Function.hxx>
40#include <math_BrentMinimum.hxx>
41#include <math_FunctionSetWithDerivatives.hxx>
42#include <Precision.hxx>
43
44
45//===========================================================================
46// - A partir d une solution de depart, recherche d une direction.( Newton la
47// plupart du temps, gradient si Newton echoue.
7fd59977 48// - Recadrage au niveau des bornes avec recalcul de la direction si une
49// inconnue a une valeur imposee.
7fd59977 50// -Si On ne sort pas des bornes
51// Tant que (On ne progresse pas assez ou on ne change pas de direction)
52// . Si (Progression encore possible)
53// Si (On ne sort pas des bornes)
54// On essaye de progresser dans cette meme direction.
55// Sinon
56// On diminue le pas d'avancement ou on change de direction.
57// Sinon
58// Si on depasse le minimum
59// On fait une interpolation parabolique.
7fd59977 60// - Si on a progresse sur F
61// On fait les tests d'arret
62// Sinon
63// On change de direction
64//============================================================================
65
3e42bd70
J
66#define FSR_DEBUG(arg)
67// Uncomment the following code to have debug output to cout
89d8607f 68//==========================================================
69//static Standard_Boolean mydebug = Standard_True;
70//#undef FSR_DEBUG
71//#define FSR_DEBUG(arg) {if (mydebug) { cout << arg << endl; }}
72//===========================================================
fbadd2cc 73
7fd59977 74class MyDirFunction : public math_Function
75{
76
89d8607f 77 math_Vector *P0;
78 math_Vector *Dir;
79 math_Vector *P;
80 math_Vector *FV;
81 math_FunctionSetWithDerivatives *F;
7fd59977 82
83public :
84
89d8607f 85 MyDirFunction(math_Vector& V1,
86 math_Vector& V2,
87 math_Vector& V3,
88 math_Vector& V4,
89 math_FunctionSetWithDerivatives& f) ;
90
91 void Initialize(const math_Vector& p0, const math_Vector& dir) const;
92 //For hp :
93 Standard_Boolean Value(const math_Vector& Sol, math_Vector& FF,
94 math_Matrix& DF, math_Vector& GH,
95 Standard_Real& F2, Standard_Real& Gnr1);
96 // Standard_Boolean MyDirFunction::Value(const math_Vector& Sol, math_Vector& FF,
97 // math_Matrix& DF, math_Vector& GH,
98 // Standard_Real& F2, Standard_Real& Gnr1);
99 Standard_Boolean Value(const Standard_Real x, Standard_Real& fval) ;
100
7fd59977 101};
102
103MyDirFunction::MyDirFunction(math_Vector& V1,
89d8607f 104 math_Vector& V2,
105 math_Vector& V3,
106 math_Vector& V4,
107 math_FunctionSetWithDerivatives& f) {
108
109 P0 = &V1;
110 Dir = &V2;
111 P = &V3;
112 FV = &V4;
113 F = &f;
7fd59977 114}
115
116void MyDirFunction::Initialize(const math_Vector& p0,
89d8607f 117 const math_Vector& dir) const
7fd59977 118{
119 *P0 = p0;
120 *Dir = dir;
121}
122
123
124Standard_Boolean MyDirFunction::Value(const Standard_Real x,
89d8607f 125 Standard_Real& fval)
7fd59977 126{
127 Standard_Real p;
128 for(Standard_Integer i = P->Lower(); i <= P->Upper(); i++) {
129 p = Dir->Value(i);
130 P->Value(i) = p * x + P0->Value(i);
131 }
132 if( F->Value(*P, *FV) ) {
133
134 Standard_Real aVal = 0.;
135
136 for(Standard_Integer i = FV->Lower(); i <= FV->Upper(); i++) {
137 aVal = FV->Value(i);
138 if(aVal < 0.) {
89d8607f 139 if(aVal <= -1.e+100) // Precision::HalfInfinite() later
140 // if(Precision::IsInfinite(Abs(FV->Value(i)))) {
141 // fval = Precision::Infinite();
142 return Standard_False;
7fd59977 143 }
144 else if(aVal >= 1.e+100) // Precision::HalfInfinite() later
89d8607f 145 return Standard_False;
7fd59977 146 }
147
148 fval = 0.5 * (FV->Norm2());
149 return Standard_True;
150 }
151 return Standard_False;
152}
153
154Standard_Boolean MyDirFunction::Value(const math_Vector& Sol,
89d8607f 155 math_Vector& FF,
156 math_Matrix& DF,
157 math_Vector& GH,
158 Standard_Real& F2,
159 Standard_Real& Gnr1)
7fd59977 160{
161 if( F->Values(Sol, FF, DF) ) {
162
163 Standard_Real aVal = 0.;
164
165 for(Standard_Integer i = FF.Lower(); i <= FF.Upper(); i++) {
89d8607f 166 // modified by NIZHNY-MKK Mon Oct 3 17:56:50 2005.BEGIN
7fd59977 167 aVal = FF.Value(i);
168 if(aVal < 0.) {
89d8607f 169 if(aVal <= -1.e+100) // Precision::HalfInfinite() later
170 // if(Precision::IsInfinite(Abs(FF.Value(i)))) {
171 // F2 = Precision::Infinite();
172 // Gnr1 = Precision::Infinite();
173 return Standard_False;
7fd59977 174 }
175 else if(aVal >= 1.e+100) // Precision::HalfInfinite() later
89d8607f 176 return Standard_False;
177 // modified by NIZHNY-MKK Mon Oct 3 17:57:05 2005.END
7fd59977 178 }
179
180
181 F2 = 0.5 * (FF.Norm2());
182 GH.TMultiply(DF, FF);
12f139fd 183 for(Standard_Integer i = GH.Lower(); i <= GH.Upper(); i++)
184 {
185 if(Precision::IsInfinite((GH.Value(i))))
186 {
187 return Standard_False;
188 }
189 }
7fd59977 190 Gnr1 = GH.Norm2();
191 return Standard_True;
192 }
193 return Standard_False;
194}
195
196
197//--------------------------------------------------------------
198static Standard_Boolean MinimizeDirection(const math_Vector& P0,
89d8607f 199 const math_Vector& P1,
200 const math_Vector& P2,
201 const Standard_Real F1,
202 math_Vector& Delta,
203 const math_Vector& Tol,
204 MyDirFunction& F)
205 // Purpose : minimisation a partir de 3 points
206 //-------------------------------------------------------
7fd59977 207{
208 // (1) Evaluation d'un tolerance parametrique 1D
209 Standard_Real tol1d = 2.1 , invnorme, tsol;
210 Standard_Real Eps = 1.e-16;
211 Standard_Real ax, bx, cx;
212
213 for (Standard_Integer ii =1; ii<=Tol.Length(); ii++) {
214 invnorme = Abs(Delta(ii));
215 if (invnorme>Eps) tol1d = Min(tol1d, Tol(ii) / invnorme);
216 }
217 if (tol1d > 1.9) return Standard_False; //Pas la peine de se fatiguer
218 tol1d /= 3;
219
89d8607f 220 //JR/Hp :
7fd59977 221 math_Vector PP0 = P0 ;
222 math_Vector PP1 = P1 ;
223 Delta = PP1 - PP0;
89d8607f 224 // Delta = P1 - P0;
7fd59977 225 invnorme = Delta.Norm();
226 if (invnorme <= Eps) return Standard_False;
227 invnorme = ((Standard_Real) 1) / invnorme;
228
229 F.Initialize(P1, Delta);
230
231 // (2) On minimise
3e42bd70 232 FSR_DEBUG (" minimisation dans la direction")
89d8607f 233 ax = -1; bx = 0;
7fd59977 234 cx = (P2-P1).Norm()*invnorme;
235 if (cx < 1.e-2) return Standard_False;
236 math_BrentMinimum Sol(F, ax, bx, cx, tol1d, 100, tol1d);
237 if(Sol.IsDone()) {
238 tsol = Sol.Location();
239 if (Sol.Minimum() < F1) {
240 Delta.Multiply(tsol);
241 return Standard_True;
242 }
243 }
244 return Standard_False;
245}
246
247//----------------------------------------------------------------------
248static Standard_Boolean MinimizeDirection(const math_Vector& P,
89d8607f 249 math_Vector& Dir,
250 const Standard_Real& PValue,
251 const Standard_Real& PDirValue,
252 const math_Vector& Gradient,
253 const math_Vector& DGradient,
254 const math_Vector& Tol,
255 MyDirFunction& F)
256 // Purpose: minimisation a partir de 2 points et une derives
257 //----------------------------------------------------------------------
7fd59977 258
259{
260 // (0) Evaluation d'un tolerance parametrique 1D
261 Standard_Boolean good = Standard_False;
262 Standard_Real Eps = 1.e-20;
263 Standard_Real tol1d = 1.1, Result = PValue, absdir;
264
265 for (Standard_Integer ii =1; ii<=Tol.Length(); ii++) {
266 absdir = Abs(Dir(ii));
267 if (absdir >Eps) tol1d = Min(tol1d, Tol(ii) / absdir);
268 }
269 if (tol1d > 0.9) return Standard_False;
89d8607f 270
7fd59977 271 // (1) On realise une premiere interpolation quadratique
272 Standard_Real ax, bx, cx, df1, df2, Delta, tsol, fsol, tsolbis;
89d8607f 273 FSR_DEBUG(" essai d interpolation");
fbadd2cc 274
7fd59977 275 df1 = Gradient*Dir;
276 df2 = DGradient*Dir;
277
278 if (df1<-Eps && df2>Eps) { // cuvette
279 tsol = - df1 / (df2 - df1);
280 }
281 else {
282 cx = PValue;
283 bx = df1;
284 ax = PDirValue - (bx+cx);
285
286 if (Abs(ax) <= Eps) { // cas lineaire
287 if ((Abs(bx) >= Eps)) tsol = - cx/bx;
288 else tsol = 0;
289 }
290 else { // cas quadratique
291 Delta = bx*bx - 4*ax*cx;
292 if (Delta > 1.e-9) {
89d8607f 293 // il y a des racines, on prend la plus proche de 0
294 Delta = Sqrt(Delta);
295 tsol = -(bx + Delta);
296 tsolbis = (Delta - bx);
297 if (Abs(tsolbis) < Abs(tsol)) tsol = tsolbis;
298 tsol /= 2*ax;
7fd59977 299 }
300 else {
89d8607f 301 // pas ou peu de racine : on "extremise"
302 tsol = -(0.5*bx)/ax;
7fd59977 303 }
304 }
305 }
306
307 if (Abs(tsol) >= 1) return Standard_False; //resultat sans interet
308
309 F.Initialize(P, Dir);
310 F.Value(tsol, fsol);
311
312 if (fsol<PValue) {
313 good = Standard_True;
314 Result = fsol;
89d8607f 315 FSR_DEBUG("t= "<<tsol<<" F = " << fsol << " OldF = "<<PValue);
7fd59977 316 }
317
318 // (2) Si l'on a pas assez progresser on realise une recherche
319 // en bonne et due forme, a partir des inits precedents
320 if ((fsol > 0.2*PValue) && (tol1d < 0.5)) {
89d8607f 321
7fd59977 322 if (tsol <0) {
323 ax = tsol; bx = 0.0; cx = 1.0;
324 }
325 else {
326 ax = 0.0; bx = tsol; cx = 1.0;
327 }
89d8607f 328 FSR_DEBUG(" minimisation dans la direction");
7fd59977 329 math_BrentMinimum Sol(F, ax, bx, cx, tol1d, 100, tol1d);
330 if(Sol.IsDone()) {
331 if (Sol.Minimum() <= Result) {
3e42bd70
J
332 tsol = Sol.Location();
333 good = Standard_True;
89d8607f 334 FSR_DEBUG("t= "<<tsol<<" F ="<< Sol.Minimum() << " OldF = "<<Result)
7fd59977 335 }
336 }
337 }
338 if (good) {
339 // mise a jour du Delta
340 Dir.Multiply(tsol);
341 }
342 return good;
343}
344
345//------------------------------------------------------
346static void SearchDirection(const math_Matrix& DF,
89d8607f 347 const math_Vector& GH,
348 const math_Vector& FF,
349 Standard_Boolean ChangeDirection,
350 const math_Vector& InvLengthMax,
351 math_Vector& Direction,
352 Standard_Real& Dy)
7fd59977 353
354{
355 Standard_Integer Ninc = DF.ColNumber(), Neq = DF.RowNumber();
356 Standard_Real Eps = 1.e-32;
357 if (!ChangeDirection) {
358 if (Ninc == Neq) {
359 for (Standard_Integer i = FF.Lower(); i <= FF.Upper(); i++) {
89d8607f 360 Direction(i) = -FF(i);
7fd59977 361 }
362 math_Gauss Solut(DF, 1.e-9);
363 if (Solut.IsDone()) Solut.Solve(Direction);
364 else { // we have to "forget" singular directions.
89d8607f 365 FSR_DEBUG(" Matrice singuliere : On prend SVD");
3e42bd70 366 math_SVD SolvebySVD(DF);
7fd59977 367 if (SolvebySVD.IsDone()) SolvebySVD.Solve(-1*FF, Direction);
3e42bd70
J
368 else ChangeDirection = Standard_True;
369 }
7fd59977 370 }
371 else if (Ninc > Neq) {
372 math_SVD Solut(DF);
373 if (Solut.IsDone()) Solut.Solve(-1*FF, Direction);
374 else ChangeDirection = Standard_True;
375 }
376 else if (Ninc < Neq) { // Calcul par GaussLeastSquare
377 math_GaussLeastSquare Solut(DF);
378 if (Solut.IsDone()) Solut.Solve(-1*FF, Direction);
379 else ChangeDirection = Standard_True;
380 }
381 }
382 // Il vaut mieux interdire des directions trops longue
383 // Afin de blinder les cas trop mal conditionne
384 // PMN 12/05/97 Traitement des singularite dans les conges
385 // Sur des surfaces periodiques
89d8607f 386
7fd59977 387 Standard_Real ratio = Abs( Direction(Direction.Lower())
89d8607f 388 *InvLengthMax(Direction.Lower()) );
7fd59977 389 Standard_Integer i;
390 for (i = Direction.Lower()+1; i<=Direction.Upper(); i++) {
391 ratio = Max(ratio, Abs( Direction(i)*InvLengthMax(i)) );
392 }
393 if (ratio > 1) {
394 Direction /= ratio;
395 }
89d8607f 396
7fd59977 397 Dy = Direction*GH;
398 if (Dy >= -Eps) { // newton "ne descend pas" on prend le gradient
399 ChangeDirection = Standard_True;
400 }
401 if (ChangeDirection) { // On va faire un gradient !
402 for (i = Direction.Lower(); i <= Direction.Upper(); i++) {
403 Direction(i) = - GH(i);
404 }
405 Dy = - (GH.Norm2());
406 }
407}
408
409
410//=====================================================================
411static void SearchDirection(const math_Matrix& DF,
89d8607f 412 const math_Vector& GH,
413 const math_Vector& FF,
414 const math_IntegerVector& Constraints,
415 // const math_Vector& X, // Le point d'init
416 const math_Vector& , // Le point d'init
417 Standard_Boolean ChangeDirection,
7fd59977 418 const math_Vector& InvLengthMax,
89d8607f 419 math_Vector& Direction,
420 Standard_Real& Dy)
421 //Purpose : Recherche une direction (et un pas si Newton Fonctionne) le long
422 // d'une frontiere
423 //=====================================================================
7fd59977 424{
425 Standard_Integer Ninc = DF.ColNumber(), Neq = DF.RowNumber();
426 Standard_Integer i, j, k, Cons = 0;
427
428 // verification sur les bornes imposees:
429
430 for (i = 1; i <= Ninc; i++) {
431 if (Constraints(i) != 0) Cons++;
432 // sinon le systeme a resoudre ne change pas.
433 }
434
435 if (Cons == 0) {
436 SearchDirection(DF, GH, FF, ChangeDirection, InvLengthMax,
89d8607f 437 Direction, Dy);
7fd59977 438 }
439 else if (Cons == Ninc) { // il n'y a plus rien a faire...
440 for(Standard_Integer i = Direction.Lower(); i <= Direction.Upper(); i++) {
89d8607f 441 Direction(i) = 0;
442 }
7fd59977 443 Dy = 0;
444 }
445 else { //(1) Cas general : On definit un sous probleme
446 math_Matrix DF2(1, Neq, 1, Ninc-Cons);
447 math_Vector MyGH(1, Ninc-Cons);
448 math_Vector MyDirection(1, Ninc-Cons);
449 math_Vector MyInvLengthMax(1, Ninc);
450
451 for (k=1, i = 1; i <= Ninc; i++) {
452 if (Constraints(i) == 0) {
89d8607f 453 MyGH(k) = GH(i);
454 MyInvLengthMax(k) = InvLengthMax(i);
455 MyDirection(k) = Direction(i);
456 for (j = 1; j <= Neq; j++) {
457 DF2(j, k) = DF(j, i);
458 }
459 k++; //on passe a l'inconnue suivante
460 }
7fd59977 461 }
462 //(2) On le resoud
463 SearchDirection(DF2, MyGH, FF, ChangeDirection, MyInvLengthMax,
89d8607f 464 MyDirection, Dy);
7fd59977 465
466 // (3) On l'interprete...
467 // Reconstruction de Direction:
468 for (i = 1, k = 1; i <= Ninc; i++) {
469 if (Constraints(i) == 0) {
89d8607f 470 if (!ChangeDirection) {
471 Direction(i) = MyDirection(k);
472 }
473 else Direction(i) = - GH(i);
474 k++;
7fd59977 475 }
476 else {
89d8607f 477 Direction(i) = 0.0;
7fd59977 478 }
479 }
480 }
481}
482
483
484
485//====================================================
3e42bd70
J
486Standard_Boolean Bounds(const math_Vector& InfBound,
487 const math_Vector& SupBound,
488 const math_Vector& Tol,
489 math_Vector& Sol,
490 const math_Vector& SolSave,
491 math_IntegerVector& Constraints,
492 math_Vector& Delta,
493 Standard_Boolean& theIsNewSol)
89d8607f 494 //
495 // Purpose: Trims an initial solution Sol to be within a domain defined by
496 // InfBound and SupBound. Delta will contain a distance between final Sol and
497 // SolSave.
498 // IsNewSol returns False, if final Sol fully coincides with SolSave, i.e.
499 // if SolSave already lied on a boundary and initial Sol was fully beyond it
500 //======================================================
7fd59977 501{
502 Standard_Boolean Out = Standard_False;
503 Standard_Integer i, Ninc = Sol.Length();
504 Standard_Real monratio = 1;
89d8607f 505
3e42bd70
J
506 theIsNewSol = Standard_True;
507
7fd59977 508 // Calcul du ratio de recadrage
509 for (i = 1; i <= Ninc; i++) {
510 Constraints(i) = 0;
511 Delta(i) = Sol(i) - SolSave(i);
512 if (InfBound(i) == SupBound(i)) {
513 Constraints(i) = 1;
514 Out = Standard_True; // Ok mais, cela devrait etre eviter
515 }
516 else if(Sol(i) < InfBound(i)) {
517 Constraints(i) = 1;
518 Out = Standard_True;
3e42bd70
J
519 // Delta(i) is negative
520 if (-Delta(i) > Tol(i)) // Afin d'eviter des ratio nulles pour rien
521 monratio = Min(monratio, (InfBound(i) - SolSave(i))/Delta(i) );
7fd59977 522 }
523 else if (Sol(i) > SupBound(i)) {
524 Constraints(i) = 1;
525 Out = Standard_True;
3e42bd70
J
526 // Delta(i) is positive
527 if (Delta(i) > Tol(i))
528 monratio = Min(monratio, (SupBound(i) - SolSave(i))/Delta(i) );
7fd59977 529 }
530 }
531
532 if (Out){ // Troncature et derniers recadrage pour blinder (pb numeriques)
3e42bd70
J
533 if (monratio == 0.0) {
534 theIsNewSol = Standard_False;
535 Sol = SolSave;
536 Delta.Init (0.0);
537 } else {
538 Delta *= monratio;
539 Sol = SolSave+Delta;
540 for (i = 1; i <= Ninc; i++) {
541 if(Sol(i) < InfBound(i)) {
542 Sol(i) = InfBound(i);
543 Delta(i) = Sol(i) - SolSave(i);
544 }
545 else if (Sol(i) > SupBound(i)) {
546 Sol(i) = SupBound(i);
547 Delta(i) = Sol(i) - SolSave(i);
548 }
7fd59977 549 }
550 }
551 }
552 return Out;
553}
554
555
556
557
558
559math_FunctionSetRoot::math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
89d8607f 560 const math_Vector& Tolerance,
561 const Standard_Integer NbIterations) :
562Delta(1, F.NbVariables()),
563Sol(1, F.NbVariables()),
564DF(1, F.NbEquations(),
565 1, F.NbVariables()),
566 Tol(1,F.NbVariables()),
567
568 InfBound(1, F.NbVariables()),
569 SupBound(1, F.NbVariables()),
570
571 SolSave(1, F.NbVariables()),
572 GH(1, F.NbVariables()),
573 DH(1, F.NbVariables()),
574 DHSave(1, F.NbVariables()),
575 FF(1, F.NbEquations()),
576 PreviousSolution(1, F.NbVariables()),
577 Save(0, NbIterations),
578 Constraints(1, F.NbVariables()),
579 Temp1(1, F.NbVariables()),
580 Temp2(1, F.NbVariables()),
581 Temp3(1, F.NbVariables()),
582 Temp4(1, F.NbEquations())
7fd59977 583
584{
585 for (Standard_Integer i = 1; i <= Tol.Length(); i++) {
586 Tol(i) =Tolerance(i);
587 }
588 Itermax = NbIterations;
589}
590
591math_FunctionSetRoot::math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
89d8607f 592 const Standard_Integer NbIterations) :
593Delta(1, F.NbVariables()),
594Sol(1, F.NbVariables()),
595DF(1, F.NbEquations(),
596 1, F.NbVariables()),
597 Tol(1, F.NbVariables()),
598
599 InfBound(1, F.NbVariables()),
600 SupBound(1, F.NbVariables()),
601
602 SolSave(1, F.NbVariables()),
603 GH(1, F.NbVariables()),
604 DH(1, F.NbVariables()),
605 DHSave(1, F.NbVariables()),
606 FF(1, F.NbEquations()),
607 PreviousSolution(1, F.NbVariables()),
608 Save(0, NbIterations),
609 Constraints(1, F.NbVariables()),
610 Temp1(1, F.NbVariables()),
611 Temp2(1, F.NbVariables()),
612 Temp3(1, F.NbVariables()),
613 Temp4(1, F.NbEquations())
7fd59977 614
615{
616 Itermax = NbIterations;
617}
618
619
620
621math_FunctionSetRoot::math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
89d8607f 622 const math_Vector& StartingPoint,
623 const math_Vector& Tolerance,
624 const math_Vector& infBound,
625 const math_Vector& supBound,
626 const Standard_Integer NbIterations,
627 Standard_Boolean theStopOnDivergent) :
628Delta(1, F.NbVariables()),
629Sol(1, F.NbVariables()),
630DF(1, F.NbEquations(),
631 1, F.NbVariables()),
632 Tol(1,F.NbVariables()),
633
634
635 InfBound(1, F.NbVariables()),
636 SupBound(1, F.NbVariables()),
637
638 SolSave(1, F.NbVariables()),
639 GH(1, F.NbVariables()),
640 DH(1, F.NbVariables()),
641 DHSave(1, F.NbVariables()),
642 FF(1, F.NbEquations()),
643 PreviousSolution(1, F.NbVariables()),
644 Save(0, NbIterations),
645 Constraints(1, F.NbVariables()),
646 Temp1(1, F.NbVariables()),
647 Temp2(1, F.NbVariables()),
648 Temp3(1, F.NbVariables()),
649 Temp4(1, F.NbEquations())
7fd59977 650
651{
89d8607f 652
7fd59977 653 for (Standard_Integer i = 1; i <= Tol.Length(); i++) {
654 Tol(i) =Tolerance(i);
655 }
656 Itermax = NbIterations;
b659a6dc 657 Perform(F, StartingPoint, infBound, supBound, theStopOnDivergent);
7fd59977 658}
659
660math_FunctionSetRoot::math_FunctionSetRoot(math_FunctionSetWithDerivatives& F,
89d8607f 661 const math_Vector& StartingPoint,
662 const math_Vector& Tolerance,
663 const Standard_Integer NbIterations) :
664Delta(1, F.NbVariables()),
665Sol(1, F.NbVariables()),
666DF(1, F.NbEquations(),
667 1, StartingPoint.Length()),
668 Tol(1,F.NbVariables()),
669
670 InfBound(1, F.NbVariables()),
671 SupBound(1, F.NbVariables()),
672
673 SolSave(1, F.NbVariables()),
674 GH(1, F.NbVariables()),
675 DH(1, F.NbVariables()),
676 DHSave(1, F.NbVariables()),
677 FF(1, F.NbEquations()),
678 PreviousSolution(1, F.NbVariables()),
679 Save(0, NbIterations),
680 Constraints(1, F.NbVariables()),
681 Temp1(1, F.NbVariables()),
682 Temp2(1, F.NbVariables()),
683 Temp3(1, F.NbVariables()),
684 Temp4(1, F.NbEquations())
685
686{
7fd59977 687 for (Standard_Integer i = 1; i <= Tol.Length(); i++) {
688 Tol(i) = Tolerance(i);
689 }
690 Itermax = NbIterations;
691 InfBound.Init(RealFirst());
692 SupBound.Init(RealLast());
693 Perform(F, StartingPoint, InfBound, SupBound);
694}
695
696void math_FunctionSetRoot::Delete()
697{}
698
699void math_FunctionSetRoot::SetTolerance(const math_Vector& Tolerance)
700{
701 for (Standard_Integer i = 1; i <= Tol.Length(); i++) {
702 Tol(i) = Tolerance(i);
703 }
704}
705
706void math_FunctionSetRoot::Perform(math_FunctionSetWithDerivatives& F,
89d8607f 707 const math_Vector& StartingPoint,
75259fc5 708 const math_Vector& theInfBound,
709 const math_Vector& theSupBound,
89d8607f 710 Standard_Boolean theStopOnDivergent)
7fd59977 711{
7fd59977 712 Standard_Integer Ninc = F.NbVariables(), Neq = F.NbEquations();
89d8607f 713
7fd59977 714 if ((Neq <= 0) ||
89d8607f 715 (StartingPoint.Length()!= Ninc) ||
75259fc5 716 (theInfBound.Length() != Ninc) ||
717 (theSupBound.Length() != Ninc)) { Standard_DimensionError:: Raise(); }
7fd59977 718
719 Standard_Integer i;
3e42bd70 720 Standard_Boolean ChangeDirection = Standard_False, Sort = Standard_False, isNewSol = Standard_False;
7fd59977 721 Standard_Boolean Good, Verif;
722 Standard_Boolean Stop;
3e42bd70 723 const Standard_Real EpsSqrt = 1.e-16, Eps = 1.e-32, Eps2 = 1.e-64, Progres = 0.005;
7fd59977 724 Standard_Real F2, PreviousMinimum, Dy, OldF;
725 Standard_Real Ambda, Ambda2, Gnr1, Oldgr;
726 math_Vector InvLengthMax(1, Ninc); // Pour bloquer les pas a 1/4 du domaine
75259fc5 727 math_IntegerVector aConstraints(1, Ninc); // Pour savoir sur quels bord on se trouve
7fd59977 728 for (i = 1; i <= Ninc ; i++) {
89d8607f 729 // modified by NIZHNY-MKK Mon Oct 3 18:03:50 2005
730 // InvLengthMax(i) = 1. / Max(Abs(SupBound(i) - InfBound(i))/4, 1.e-9);
75259fc5 731 InvLengthMax(i) = 1. / Max((theSupBound(i) - theInfBound(i))/4, 1.e-9);
89d8607f 732 }
7fd59977 733
734 MyDirFunction F_Dir(Temp1, Temp2, Temp3, Temp4, F);
735 Standard_Integer DescenteIter;
736
737 Done = Standard_False;
738 Sol = StartingPoint;
739 Kount = 0;
740
b659a6dc 741 //
742 myIsDivergent = Standard_False;
743 for (i = 1; i <= Ninc; i++)
744 {
75259fc5 745 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
b659a6dc 746 }
747 if (theStopOnDivergent & myIsDivergent)
748 {
749 return;
750 }
7fd59977 751 // Verification de la validite des inconnues par rapport aux bornes.
752 // Recentrage sur les bornes si pas valide.
753 for ( i = 1; i <= Ninc; i++) {
75259fc5 754 if (Sol(i) <= theInfBound(i)) Sol(i) = theInfBound(i);
755 else if (Sol(i) > theSupBound(i)) Sol(i) = theSupBound(i);
7fd59977 756 }
757
758 // Calcul de la premiere valeur de F et de son gradient
759 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
760 Done = Standard_False;
b659a6dc 761 if (!theStopOnDivergent || !myIsDivergent)
762 {
763 State = F.GetStateNumber();
764 }
7fd59977 765 return;
766 }
767 Ambda2 = Gnr1;
768 // Le rang 0 de Save ne doit servir q'au test accelarteur en fin de boucle
769 // s'il on est dejas sur la solution, il faut leurer ce test pour eviter
770 // de faire une seconde iteration...
3e42bd70 771 Save(0) = Max (F2, EpsSqrt);
5368adff 772 Standard_Real aTol_Func = Epsilon(F2);
89d8607f 773 FSR_DEBUG("=== Mode Debug de Function Set Root" << endl);
774 FSR_DEBUG(" F2 Initial = " << F2);
7fd59977 775
3e42bd70 776 if ((F2 <= Eps) || (Gnr1 <= Eps2)) {
b659a6dc 777 Done = Standard_False;
778 if (!theStopOnDivergent || !myIsDivergent)
779 {
780 Done = Standard_True;
781 State = F.GetStateNumber();
782 }
7fd59977 783 return;
784 }
785
786 for (Kount = 1; Kount <= Itermax; Kount++) {
787 PreviousMinimum = F2;
788 Oldgr = Gnr1;
789 PreviousSolution = Sol;
790 SolSave = Sol;
791
792 SearchDirection(DF, GH, FF, ChangeDirection, InvLengthMax, DH, Dy);
793 if (Abs(Dy) <= Eps) {
b659a6dc 794 Done = Standard_False;
795 if (!theStopOnDivergent || !myIsDivergent)
796 {
797 Done = Standard_True;
798 ////modified by jgv, 31.08.2011////
799 F.Value(Sol, FF); //update F before GetStateNumber
800 ///////////////////////////////////
801 State = F.GetStateNumber();
802 }
7fd59977 803 return;
804 }
805 if (ChangeDirection) {
3e42bd70 806 Ambda = Ambda2 / Sqrt(Abs(Dy));
7fd59977 807 if (Ambda > 1.0) Ambda = 1.0;
808 }
809 else {
810 Ambda = 1.0;
811 Ambda2 = 0.5*Ambda/DH.Norm();
812 }
813
814 for( i = Sol.Lower(); i <= Sol.Upper(); i++) {
815 Sol(i) = Sol(i) + Ambda * DH(i);
816 }
b659a6dc 817 //
818 for (i = 1; i <= Ninc; i++)
819 {
75259fc5 820 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
b659a6dc 821 }
822 if (theStopOnDivergent & myIsDivergent)
823 {
824 return;
825 }
826 //
75259fc5 827 Sort = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
828 aConstraints, Delta, isNewSol);
89d8607f 829
7fd59977 830
7fd59977 831 DHSave = GH;
3e42bd70 832 if (isNewSol) {
89d8607f 833 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
3e42bd70
J
834 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
835 Done = Standard_False;
b659a6dc 836 if (!theStopOnDivergent || !myIsDivergent)
837 {
838 State = F.GetStateNumber();
839 }
3e42bd70
J
840 return;
841 }
7fd59977 842 }
89d8607f 843
844 FSR_DEBUG("Kount = " << Kount);
845 FSR_DEBUG("Le premier F2 = " << F2);
846 FSR_DEBUG("Direction = " << ChangeDirection);
7fd59977 847
3e42bd70 848 if ((F2 <= Eps) || (Gnr1 <= Eps2)) {
b659a6dc 849 Done = Standard_False;
850 if (!theStopOnDivergent || !myIsDivergent)
851 {
852 Done = Standard_True;
853 ////modified by jgv, 31.08.2011////
854 F.Value(Sol, FF); //update F before GetStateNumber
855 ///////////////////////////////////
856 State = F.GetStateNumber();
857 }
7fd59977 858 return;
859 }
860
861 if (Sort || (F2/PreviousMinimum > Progres)) {
862 Dy = GH*DH;
863 OldF = PreviousMinimum;
864 Stop = Standard_False;
865 Good = Standard_False;
866 DescenteIter = 0;
867 Standard_Boolean Sortbis;
868
869 // -------------------------------------------------
870 // Traitement standard sans traitement des bords
871 // -------------------------------------------------
872 if (!Sort) { // si l'on est pas sortie on essaye de progresser en avant
89d8607f 873 while((F2/PreviousMinimum > Progres) && !Stop) {
874 if (F2 < OldF && (Dy < 0.0)) {
875 // On essaye de progresser dans cette direction.
876 FSR_DEBUG(" iteration de descente = " << DescenteIter);
877 DescenteIter++;
878 SolSave = Sol;
879 OldF = F2;
880 for( i = Sol.Lower(); i <= Sol.Upper(); i++) {
881 Sol(i) = Sol(i) + Ambda * DH(i);
882 }
883 //
884 for (i = 1; i <= Ninc; i++)
885 {
75259fc5 886 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
89d8607f 887 }
888 if (theStopOnDivergent & myIsDivergent)
889 {
890 return;
891 }
892 //
75259fc5 893 Stop = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
894 aConstraints, Delta, isNewSol);
89d8607f 895 FSR_DEBUG(" Augmentation de lambda");
896 Ambda *= 1.7;
b659a6dc 897 }
89d8607f 898 else {
899 if ((F2 >= OldF)||(F2 >= PreviousMinimum)) {
900 Good = Standard_False;
901 if (DescenteIter == 0) {
902 // C'est le premier pas qui flanche, on fait une interpolation.
903 // et on minimise si necessaire.
904 DescenteIter++;
905 Good = MinimizeDirection(SolSave, Delta, OldF, F2, DHSave, GH,
906 Tol, F_Dir);
907 }
908 else if (ChangeDirection || (DescenteIter>1)
909 || (OldF>PreviousMinimum) ) {
910 // La progression a ete utile, on minimise...
911 DescenteIter++;
912 Good = MinimizeDirection(PreviousSolution, SolSave, Sol,
913 OldF, Delta, Tol, F_Dir);
914 }
915 if (!Good) {
916 Sol = SolSave;
917 F2 = OldF;
918 }
919 else {
920 Sol = SolSave+Delta;
921 //
922 for (i = 1; i <= Ninc; i++)
923 {
75259fc5 924 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
89d8607f 925 }
926 if (theStopOnDivergent & myIsDivergent)
927 {
928 return;
929 }
930 //
75259fc5 931 Sort = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
932 aConstraints, Delta, isNewSol);
89d8607f 933 }
934 Sort = Standard_False; // On a rejete le point sur la frontiere
935 }
936 Stop = Standard_True; // et on sort dans tous les cas...
b659a6dc 937 }
89d8607f 938 DHSave = GH;
3e42bd70 939 if (isNewSol) {
89d8607f 940 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
3e42bd70
J
941 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
942 Done = Standard_False;
b659a6dc 943 if (!theStopOnDivergent || !myIsDivergent)
944 {
945 State = F.GetStateNumber();
946 }
3e42bd70
J
947 return;
948 }
949 }
89d8607f 950 Dy = GH*DH;
951 if (Abs(Dy) <= Eps) {
952 if (F2 > OldF)
3e42bd70 953 Sol = SolSave;
89d8607f 954 Done = Standard_False;
955 if (!theStopOnDivergent || !myIsDivergent)
956 {
957 Done = Standard_True;
b659a6dc 958 ////modified by jgv, 31.08.2011////
959 F.Value(Sol, FF); //update F before GetStateNumber
960 ///////////////////////////////////
89d8607f 961 State = F.GetStateNumber();
962 }
963 return;
964 }
965 if (DescenteIter >= 100) {
966 Stop = Standard_True;
967 }
968 }
969 FSR_DEBUG("--- Sortie du Traitement Standard");
970 FSR_DEBUG(" DescenteIter = "<<DescenteIter << " F2 = " << F2);
7fd59977 971 }
972 // ------------------------------------
973 // on passe au traitement des bords
974 // ------------------------------------
975 if (Sort) {
89d8607f 976 Stop = (F2 > 1.001*OldF); // Pour ne pas progresser sur le bord
977 Sortbis = Sort;
978 DescenteIter = 0;
979 while (Sortbis && ((F2<OldF)|| (DescenteIter == 0))
980 && (!Stop)) {
981 DescenteIter++;
982 // On essaye de progresser sur le bord
983 SolSave = Sol;
984 OldF = F2;
75259fc5 985 SearchDirection(DF, GH, FF, aConstraints, Sol,
89d8607f 986 ChangeDirection, InvLengthMax, DH, Dy);
987 FSR_DEBUG(" Conditional Direction = " << ChangeDirection);
988 if (Dy<-Eps) { //Pour eviter des calculs inutiles et des /0...
989 if (ChangeDirection) {
990
991 // Ambda = Ambda2 / Sqrt(Abs(Dy));
992 Ambda = Ambda2 / Sqrt(-Dy);
993 if (Ambda > 1.0) Ambda = 1.0;
994 }
995 else {
996 Ambda = 1.0;
997 Ambda2 = 0.5*Ambda/DH.Norm();
998 }
999
1000 for( i = Sol.Lower(); i <= Sol.Upper(); i++) {
1001 Sol(i) = Sol(i) + Ambda * DH(i);
1002 }
1003 //
1004 for (i = 1; i <= Ninc; i++)
1005 {
75259fc5 1006 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
89d8607f 1007 }
1008 if (theStopOnDivergent & myIsDivergent)
1009 {
3e42bd70
J
1010 return;
1011 }
89d8607f 1012 //
75259fc5 1013 Sortbis = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
1014 aConstraints, Delta, isNewSol);
89d8607f 1015
1016 DHSave = GH;
1017 if (isNewSol) {
1018 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
1019 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
1020 Done = Standard_False;
1021 if (!theStopOnDivergent || !myIsDivergent)
1022 {
1023 State = F.GetStateNumber();
1024 }
1025 return;
b659a6dc 1026 }
3e42bd70 1027 }
89d8607f 1028 Ambda2 = Gnr1;
1029 FSR_DEBUG("--- Iteration au bords : " << DescenteIter);
1030 FSR_DEBUG("--- F2 = " << F2);
3e42bd70 1031 }
89d8607f 1032 else {
1033 Stop = Standard_True;
1034 }
1035
1036 while((F2/PreviousMinimum > Progres) && (F2<OldF) && (!Stop) ) {
1037 DescenteIter++;
1038 FSR_DEBUG("--- Iteration de descente conditionnel = " << DescenteIter);
1039 if (F2 < OldF && Dy < 0.0) {
1040 // On essaye de progresser dans cette direction.
1041 SolSave = Sol;
1042 OldF = F2;
1043 for( i = Sol.Lower(); i <= Sol.Upper(); i++) {
1044 Sol(i) = Sol(i) + Ambda * DH(i);
1045 }
1046 //
1047 for (i = 1; i <= Ninc; i++)
b659a6dc 1048 {
75259fc5 1049 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
b659a6dc 1050 }
89d8607f 1051 if (theStopOnDivergent & myIsDivergent)
1052 {
1053 return;
1054 }
1055 //
75259fc5 1056 Sortbis = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
1057 aConstraints, Delta, isNewSol);
89d8607f 1058 }
1059 DHSave = GH;
1060 if (isNewSol) {
1061 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
1062 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
1063 Done = Standard_False;
1064 if (!theStopOnDivergent || !myIsDivergent)
1065 {
1066 State = F.GetStateNumber();
1067 }
1068 return;
1069 }
1070 }
1071 Ambda2 = Gnr1;
1072 Dy = GH*DH;
1073 Stop = ((Dy >=0) || (DescenteIter >= 10) || Sortbis);
1074 }
1075 Stop = ((Dy >=0) || (DescenteIter >= 10));
1076 }
1077 if (((F2/PreviousMinimum > Progres) &&
1078 (F2>=OldF))||(F2>=PreviousMinimum)) {
1079 // On minimise par Brent
1080 DescenteIter++;
1081 Good = MinimizeDirection(SolSave, Delta, OldF, F2,
1082 DHSave, GH, Tol, F_Dir);
1083 if (!Good) {
1084 Sol = SolSave;
1085 Sort = Standard_False;
1086 }
1087 else {
1088 Sol = SolSave + Delta;
1089 //
1090 for (i = 1; i <= Ninc; i++)
1091 {
75259fc5 1092 myIsDivergent |= (Sol(i) < theInfBound(i)) | (theSupBound(i) < Sol(i));
89d8607f 1093 }
1094 if (theStopOnDivergent & myIsDivergent)
1095 {
3e42bd70
J
1096 return;
1097 }
89d8607f 1098 //
75259fc5 1099 Sort = Bounds(theInfBound, theSupBound, Tol, Sol, SolSave,
1100 aConstraints, Delta, isNewSol);
89d8607f 1101 if (isNewSol) {
1102 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
1103 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
1104 Done = Standard_False;
1105 if (!theStopOnDivergent || !myIsDivergent)
1106 {
1107 State = F.GetStateNumber();
1108 }
1109 return;
1110 }
1111 }
1112 }
1113 Dy = GH*DH;
1114 }
1115 FSR_DEBUG("--- Sortie du Traitement des Bords");
1116 FSR_DEBUG("--- DescenteIter = "<<DescenteIter << " F2 = " << F2);
7fd59977 1117 }
1118 }
1119
1120 // ---------------------------------------------
1121 // on passe aux tests d'ARRET
1122 // ---------------------------------------------
1123 Save(Kount) = F2;
1124 // Est ce la solution ?
1125 if (ChangeDirection) Verif = Standard_True;
89d8607f 1126 // Gradient : Il faut eviter de boucler
7fd59977 1127 else {
1128 Verif = Standard_False;
1129 if (Kount > 1) { // Pour accelerer les cas quasi-quadratique
89d8607f 1130 if (Save(Kount-1)<1.e-4*Save(Kount-2)) Verif = Standard_True;
7fd59977 1131 }
1132 else Verif = (F2 < 1.e-6*Save(0)); //Pour les cas dejas solutions
1133 }
1134 if (Verif) {
1135 for(i = Delta.Lower(); i <= Delta.Upper(); i++) {
89d8607f 1136 Delta(i) = PreviousSolution(i) - Sol(i);
7fd59977 1137 }
89d8607f 1138
7fd59977 1139 if (IsSolutionReached(F)) {
89d8607f 1140 if (PreviousMinimum < F2) {
1141 Sol = SolSave;
1142 }
1143 Done = Standard_False;
1144 if (!theStopOnDivergent || !myIsDivergent)
1145 {
1146 Done = Standard_True;
b659a6dc 1147 ////modified by jgv, 31.08.2011////
1148 F.Value(Sol, FF); //update F before GetStateNumber
1149 ///////////////////////////////////
89d8607f 1150 State = F.GetStateNumber();
1151 }
1152 return;
7fd59977 1153 }
1154 }
1155 //fin du test solution
89d8607f 1156
7fd59977 1157 // Analyse de la progression...
5368adff 1158 //comparison of current minimum and previous minimum
1159 if ((F2 - PreviousMinimum) <= aTol_Func){
7fd59977 1160 if (Kount > 5) {
89d8607f 1161 // L'historique est il bon ?
1162 if (F2 >= 0.95*Save(Kount - 5)) {
1163 if (!ChangeDirection) ChangeDirection = Standard_True;
1164 else
1165 {
1166 Done = Standard_False;
1167 if (!theStopOnDivergent || !myIsDivergent)
1168 {
1169 Done = Standard_True;
1170 State = F.GetStateNumber();
1171 }
1172 return; // si un gain inf a 5% on sort
1173 }
1174 }
1175 else ChangeDirection = Standard_False; //Si oui on recommence
7fd59977 1176 }
1177 else ChangeDirection = Standard_False; //Pas d'historique on continue
1178 // Si le gradient ne diminue pas suffisemment par newton on essaie
1179 // le gradient sauf si f diminue (aussi bizarre que cela puisse
1180 // paraitre avec NEWTON le gradient de f peut augmenter alors que f
1181 // diminue: dans ce cas il faut garder NEWTON)
1182 if ((Gnr1 > 0.9*Oldgr) &&
89d8607f 1183 (F2 > 0.5*PreviousMinimum)) {
1184 ChangeDirection = Standard_True;
7fd59977 1185 }
1186
1187 // Si l'on ne decide pas de changer de strategie, on verifie,
1188 // si ce n'est dejas fait
1189 if ((!ChangeDirection) && (!Verif)) {
89d8607f 1190 for(i = Delta.Lower(); i <= Delta.Upper(); i++) {
1191 Delta(i) = PreviousSolution(i) - Sol(i);
1192 }
1193 if (IsSolutionReached(F)) {
1194 Done = Standard_False;
1195 if (!theStopOnDivergent || !myIsDivergent)
1196 {
1197 Done = Standard_True;
b659a6dc 1198 ////modified by jgv, 31.08.2011////
1199 F.Value(Sol, FF); //update F before GetStateNumber
1200 ///////////////////////////////////
89d8607f 1201 State = F.GetStateNumber();
1202 }
1203 return;
1204 }
7fd59977 1205 }
1206 }
1207 else { // Cas de regression
1208 if (!ChangeDirection) { // On passe au gradient
89d8607f 1209 ChangeDirection = Standard_True;
1210 Sol = PreviousSolution;
1211 // F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1);
1212 if(!F_Dir.Value(Sol, FF, DF, GH, F2, Gnr1)) {
1213 Done = Standard_False;
1214 if (!theStopOnDivergent || !myIsDivergent)
1215 {
1216 State = F.GetStateNumber();
1217 }
1218 return;
1219 }
7fd59977 1220 }
5368adff 1221 else
1222 {
89d8607f 1223
b659a6dc 1224 if (!theStopOnDivergent || !myIsDivergent)
1225 {
1226 State = F.GetStateNumber();
1227 }
5368adff 1228 return; // y a plus d'issues
1229 }
7fd59977 1230 }
1231 }
b659a6dc 1232 if (!theStopOnDivergent || !myIsDivergent)
1233 {
1234 State = F.GetStateNumber();
1235 }
7fd59977 1236}
1237
1238
1239
1240
1241Standard_Boolean math_FunctionSetRoot::IsSolutionReached(math_FunctionSetWithDerivatives& ) {
89d8607f 1242 for(Standard_Integer i = 1; i<= Sol.Length(); i++) {
1243 if(Abs(Delta(i)) > Tol(i)) {return Standard_False;}
1244 }
1245 return Standard_True;
7fd59977 1246}
1247
1248
1249void math_FunctionSetRoot::Dump(Standard_OStream& o) const {
89d8607f 1250 o<<" math_FunctionSetRoot";
1251 if (Done) {
1252 o << " Status = Done\n";
1253 o << " Location value = " << Sol << "\n";
1254 o << " Number of iterations = " << Kount << "\n";
1255 }
1256 else {
1257 o<<"Status = Not Done\n";
1258 }
7fd59977 1259}
1260
1261
1262void math_FunctionSetRoot::Root(math_Vector& Root) const{
1263 StdFail_NotDone_Raise_if(!Done, " ");
1264 Standard_DimensionError_Raise_if(Root.Length() != Sol.Length(), " ");
1265 Root = Sol;
1266}
1267
1268
1269void math_FunctionSetRoot::FunctionSetErrors(math_Vector& Err) const{
1270 StdFail_NotDone_Raise_if(!Done, " ");
1271 Standard_DimensionError_Raise_if(Err.Length() != Sol.Length(), " ");
1272 Err = Delta;
1273}