1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
20 #define No_Standard_RangeError
21 #define No_Standard_OutOfRange
22 #define No_Standard_DimensionError
25 #include <math_FunctionAllRoots.ixx>
27 #include <Standard_NumericError.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <math_FunctionRoots.hxx>
30 #include <math_FunctionWithDerivative.hxx>
31 #include <math_FunctionSample.hxx>
33 math_FunctionAllRoots::math_FunctionAllRoots (
34 math_FunctionWithDerivative& F,
35 const math_FunctionSample& S,
36 const Standard_Real EpsX, const Standard_Real EpsF,
37 const Standard_Real EpsNul) {
43 Standard_Boolean Nul, PNul, InterNul, Nuld, Nulf;
44 Standard_Real DebNul,FinNul;
45 Standard_Integer Indd,Indf;
46 Standard_Real cst,val,valsav=0,valbid;
47 Standard_Boolean bid,fini;
48 Standard_Integer Nbp,i;
51 bid=F.Value(S.GetParameter(1),val);
52 PNul=Abs(val)<=EpsNul;
53 if (!PNul) {valsav=val;}
54 InterNul=Standard_False;
63 bid=F.Value(S.GetParameter(i),val);
68 if (InterNul && (!Nul)) {
69 InterNul=Standard_False;
78 math_FunctionRoots Res1(F,S.GetParameter(i-1),S.GetParameter(i),10,
80 Standard_NumericError_Raise_if((!Res1.IsDone()) ||
82 (Res1.NbSolutions()==0), " ");
85 Indf=Res1.StateNumber(1);
88 math_FunctionRoots Res2(F,S.GetParameter(i-1),S.GetParameter(i),10,
90 Standard_NumericError_Raise_if((!Res2.IsDone()) ||
91 (Res2.IsAllNull())," ");
93 //-- || (Res2.NbSolutions()!=0), " "); lbr le 13 mai 87 (!=0 -> ==0)
94 if (Res2.NbSolutions()!=0) {
95 if (Res2.Value(1) < FinNul) {
96 FinNul = Res2.Value(1);
97 Indf = Res2.StateNumber(1);
103 else if ((!InterNul) && PNul && Nul) {
104 InterNul=Standard_True;
106 DebNul=S.GetParameter(1);
107 bid = F.Value(DebNul,valbid);
108 Indd = F.GetStateNumber();
118 math_FunctionRoots Res1(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
120 Standard_NumericError_Raise_if((!Res1.IsDone()) ||
121 (Res1.IsAllNull()) ||
122 (Res1.NbSolutions()==0), " ");
123 DebNul=Res1.Value(Res1.NbSolutions());
124 Indd = Res1.StateNumber(Res1.NbSolutions());
127 math_FunctionRoots Res3(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
129 Standard_NumericError_Raise_if((!Res3.IsDone()) ||
130 (Res3.IsAllNull()), " ");
132 if (Res3.NbSolutions()!=0) {
133 if (Res3.Value(Res3.NbSolutions()) > DebNul) {
134 DebNul = Res3.Value(Res3.NbSolutions());
135 Indd = Res3.StateNumber(Res3.NbSolutions());
145 if (InterNul) { // rajouter l intervalle finissant au dernier pt
148 FinNul = S.GetParameter(Nbp);
149 bid = F.Value(FinNul,valbid);
150 Indf = F.GetStateNumber();
156 if (pdeb.Length()==0) { // Pas d intervalle nul
158 math_FunctionRoots Res(F,S.GetParameter(1),S.GetParameter(Nbp),Nbp,
160 Standard_NumericError_Raise_if((!Res.IsDone()) ||
161 (Res.IsAllNull()), " ");
163 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
164 piso.Append(Res.Value(j));
165 iiso.Append(Res.StateNumber(j));
169 Standard_Integer NbpMin = 3;
170 Standard_Integer Nbrpt;
171 if (!Nuld) { // Recherche des solutions entre S.GetParameter(1)
172 // et le debut du 1er intervalle nul
174 Nbrpt=(Standard_Integer ) IntegerPart(
175 Abs((pdeb.Value(1)-S.GetParameter(1))/
176 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
177 math_FunctionRoots Res(F,S.GetParameter(1),pdeb.Value(1),
178 Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
179 Standard_NumericError_Raise_if((!Res.IsDone()) ||
180 (Res.IsAllNull()), " ");
182 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
183 piso.Append(Res.Value(j));
184 iiso.Append(Res.StateNumber(j));
187 for (Standard_Integer k=2; k<=pdeb.Length(); k++) {
188 Nbrpt=(Standard_Integer )
189 IntegerPart(Abs((pdeb.Value(k)-pfin.Value(k-1))/
190 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
191 math_FunctionRoots Res(F,pfin.Value(k-1),pdeb.Value(k),
192 Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
193 Standard_NumericError_Raise_if((!Res.IsDone()) ||
194 (Res.IsAllNull()), " ");
196 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
197 piso.Append(Res.Value(j));
198 iiso.Append(Res.StateNumber(j));
201 if (!Nulf) { // Recherche des solutions entre la fin du
202 // dernier intervalle nul et Value(Nbp).
204 Nbrpt=(Standard_Integer )
205 IntegerPart(Abs((S.GetParameter(Nbp)-
206 pfin.Value(pdeb.Length()))/
207 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
208 math_FunctionRoots Res(F,pfin.Value(pdeb.Length()),
209 S.GetParameter(Nbp), Max(Nbrpt, NbpMin),
211 Standard_NumericError_Raise_if((!Res.IsDone()) ||
212 (Res.IsAllNull()), " ");
214 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
215 piso.Append(Res.Value(j));
216 iiso.Append(Res.StateNumber(j));
224 void math_FunctionAllRoots::Dump(Standard_OStream& o) const {
226 o<< "math_FunctionAllRoots ";
228 o<< " Status = Done \n";
229 o << " Number of null intervals = " << pdeb.Length() << endl;
230 o << " Number of points where the function is null: " << piso.Length() << endl;
233 o<< " Status = not Done \n";