0025720: Incorrect code of math classes can lead to unpredicted behavior of algorithms
[occt.git] / src / math / math_FunctionRoot.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 //#endif
20
21 #include <Standard_Failure.hxx>
22 #include <math_FunctionRoot.ixx>
23 #include <math_FunctionSetRoot.hxx>
24
25 #include <math_FunctionSetWithDerivatives.hxx>
26 #include <math_FunctionWithDerivative.hxx>
27
28
29 class math_MyFunctionSetWithDerivatives : public math_FunctionSetWithDerivatives {
30
31   private:
32          math_FunctionWithDerivative *Ff;
33   
34   public :
35
36     math_MyFunctionSetWithDerivatives (math_FunctionWithDerivative& F );
37     
38     Standard_Integer NbVariables () const;
39     Standard_Integer NbEquations () const;
40     Standard_Boolean Value (const math_Vector& X, math_Vector& F) ;
41     Standard_Boolean Derivatives (const math_Vector& X, math_Matrix& D) ;    
42     Standard_Boolean Values (const math_Vector& X, math_Vector& F, math_Matrix& D) ;    
43 };
44
45
46     math_MyFunctionSetWithDerivatives::math_MyFunctionSetWithDerivatives
47               (math_FunctionWithDerivative& F ) {
48                   Ff = &F ;
49      
50               }
51     
52     Standard_Integer math_MyFunctionSetWithDerivatives::NbVariables () const {
53       return 1;
54     }
55     Standard_Integer math_MyFunctionSetWithDerivatives::NbEquations () const {
56       return 1;
57     }
58     Standard_Boolean math_MyFunctionSetWithDerivatives::Value (const math_Vector& X, math_Vector& Fs)  {
59       return Ff->Value(X(1),Fs(1));
60     }
61     Standard_Boolean math_MyFunctionSetWithDerivatives::Derivatives (const math_Vector& X, math_Matrix& D) {
62       return Ff->Derivative(X(1),D(1,1));
63     }    
64     Standard_Boolean math_MyFunctionSetWithDerivatives::Values (const math_Vector& X, math_Vector& F, math_Matrix& D) {
65       return Ff->Values(X(1),F(1),D(1,1));      
66     }
67
68
69
70
71    math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F, 
72                                         const Standard_Real Guess, 
73                                         const Standard_Real Tolerance, 
74                                         const Standard_Integer NbIterations ){
75      math_Vector V(1,1), Tol(1,1);
76      math_MyFunctionSetWithDerivatives Ff(F);
77      V(1)=Guess;
78      Tol(1) = Tolerance;
79      math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
80      Sol.Perform(Ff, V);
81      Done = Sol.IsDone(); 
82      if (Done) {
83        F.GetStateNumber();
84        TheRoot = Sol.Root()(1);
85        TheDerivative = Sol.Derivative()(1,1);
86        F.Value(TheRoot,TheError);
87        NbIter = Sol.NbIterations();
88      }       
89    }
90    math_FunctionRoot::math_FunctionRoot(math_FunctionWithDerivative& F, 
91                                         const Standard_Real Guess, 
92                                         const Standard_Real Tolerance, 
93                                         const Standard_Real A,
94                                         const Standard_Real B,
95                                         const Standard_Integer NbIterations ){
96      math_Vector V(1,1),Aa(1,1),Bb(1,1), Tol(1,1);
97      math_MyFunctionSetWithDerivatives Ff(F);
98      V(1)=Guess;
99      Tol(1) = Tolerance;
100      Aa(1)=A;
101      Bb(1)=B;
102      math_FunctionSetRoot Sol(Ff, Tol, NbIterations);
103      Sol.Perform(Ff, V, Aa, Bb);
104      Done = Sol.IsDone();
105      if (Done) {
106        F.GetStateNumber();
107        TheRoot = Sol.Root()(1);
108        TheDerivative = Sol.Derivative()(1,1);
109        F.Value(TheRoot,TheError);
110        NbIter = Sol.NbIterations();
111      }
112    }
113
114     void math_FunctionRoot::Dump(Standard_OStream& o) const {
115
116        o<< "math_FunctionRoot ";
117        if(Done) {
118          o<< " Status = Done \n";
119          o << " Number of iterations = " << NbIter << endl;
120          o << " The Root is: " << TheRoot << endl;
121          o << "The value at the root is: " << TheError << endl;
122        }
123        else {
124          o<< " Status = not Done \n";
125        }
126     }