1 // Created on: 1996-05-03
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #define No_Standard_RangeError
24 #define No_Standard_OutOfRange
25 #define No_Standard_DimensionError
28 #include <math_NewtonMinimum.ixx>
30 #include <math_Gauss.hxx>
31 #include <math_Jacobi.hxx>
33 //============================================================================
34 math_NewtonMinimum::math_NewtonMinimum(math_MultipleVarFunctionWithHessian& F,
35 const math_Vector& StartingPoint,
36 const Standard_Real Tolerance,
37 const Standard_Integer NbIterations,
38 const Standard_Real Convexity,
39 const Standard_Boolean WithSingularity)
40 //============================================================================
41 : TheLocation(1, F.NbVariables()),
42 TheGradient(1, F.NbVariables()),
43 TheStep(1, F.NbVariables(), 10*Tolerance),
44 TheHessian(1, F.NbVariables(), 1, F.NbVariables() )
48 Itermax = NbIterations;
49 NoConvexTreatement = WithSingularity;
50 Convex = Standard_True;
51 // Done = Standard_True;
52 // TheStatus = math_OK;
53 Perform ( F, StartingPoint);
56 //============================================================================
57 math_NewtonMinimum::math_NewtonMinimum(math_MultipleVarFunctionWithHessian& F,
58 const Standard_Real Tolerance,
59 const Standard_Integer NbIterations,
60 const Standard_Real Convexity,
61 const Standard_Boolean WithSingularity)
62 //============================================================================
63 : TheLocation(1, F.NbVariables()),
64 TheGradient(1, F.NbVariables()),
65 TheStep(1, F.NbVariables(), 10*Tolerance),
66 TheHessian(1, F.NbVariables(), 1, F.NbVariables() )
70 Itermax = NbIterations;
71 NoConvexTreatement = WithSingularity;
72 Convex = Standard_True;
73 Done = Standard_False;
74 TheStatus = math_NotBracketed;
76 //============================================================================
77 void math_NewtonMinimum::Delete()
79 //============================================================================
80 void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
81 const math_Vector& StartingPoint)
82 //============================================================================
84 math_Vector Point1 (1, F.NbVariables());
85 Point1 = StartingPoint;
86 math_Vector Point2(1, F.NbVariables());
87 math_Vector* precedent = &Point1;
88 math_Vector* suivant = &Point2;
89 math_Vector* auxiliaire = precedent;
91 Standard_Boolean Ok = Standard_True;
92 Standard_Integer NbConv = 0, ii, Nreduction;
93 Standard_Real VPrecedent, VItere;
99 while ( Ok && (NbConv < 2) ) {
104 Ok = F.Values(*precedent, VPrecedent, TheGradient, TheHessian);
106 Done = Standard_False;
107 TheStatus = math_FunctionError;
111 PreviousMinimum = VPrecedent;
112 TheMinimum = VPrecedent;
115 // Traitement de la non convexite
117 math_Jacobi CalculVP(TheHessian);
118 if ( !CalculVP.IsDone() ) {
119 Done = Standard_False;
120 TheStatus = math_FunctionError;
126 MinEigenValue = CalculVP.Values() ( CalculVP.Values().Min());
127 if ( MinEigenValue < CTol) {
128 Convex = Standard_False;
129 if (NoConvexTreatement) {
130 Standard_Real Delta = CTol+0.1*Abs(MinEigenValue) -MinEigenValue ;
131 for (ii=1; ii<=TheGradient.Length(); ii++) {
132 TheHessian(ii, ii) += Delta;
136 TheStatus = math_FunctionError;
143 math_Gauss LU(TheHessian, CTol/100);
145 Done = Standard_False;
146 TheStatus = math_DirectionSearchError;
150 LU.Solve(TheGradient, TheStep);
151 *suivant = *precedent - TheStep;
154 // Gestion de la convergence
156 F.Value(*suivant, TheMinimum);
158 if (IsConverged()) { NbConv++; }
161 // Controle et corrections.
164 TheMinimum = PreviousMinimum;
166 while (VItere > VPrecedent && Nreduction < 10) {
168 *suivant = *precedent - TheStep;
169 F.Value(*suivant, VItere);
173 if (VItere <= VPrecedent) {
174 auxiliaire = precedent;
176 suivant = auxiliaire;
177 PreviousMinimum = VPrecedent;
179 Ok = (nbiter < Itermax);
180 if (!Ok && NbConv < 2) TheStatus = math_TooManyIterations;
184 TheStatus = math_DirectionSearchError;
187 TheLocation = *precedent;
190 //============================================================================
191 Standard_Boolean math_NewtonMinimum::IsConverged() const
192 //============================================================================
194 return ( (TheStep.Norm() <= XTol ) ||
195 ( Abs(TheMinimum-PreviousMinimum) <= XTol*Abs(PreviousMinimum) ));
198 //============================================================================
199 void math_NewtonMinimum::Dump(Standard_OStream& o) const
200 //============================================================================
202 o<< "math_Newton Optimisation: ";
203 o << " Done =" << Done << endl;
204 o << " Status = " << (Standard_Integer)TheStatus << endl;
205 o <<" Location Vector = " << Location() << endl;
206 o <<" Minimum value = "<< Minimum()<< endl;
207 o <<" Previous value = "<< PreviousMinimum << endl;
208 o <<" Number of iterations = " <<NbIterations() << endl;
209 o <<" Convexity = " << Convex << endl;
210 o <<" Eigen Value = " << MinEigenValue << endl;