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