1 // Copyright (c) 1997-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #define No_Standard_RangeError
17 #define No_Standard_OutOfRange
18 #define No_Standard_DimensionError
21 #include <math_FunctionAllRoots.ixx>
23 #include <Standard_NumericError.hxx>
24 #include <Standard_OutOfRange.hxx>
25 #include <math_FunctionRoots.hxx>
26 #include <math_FunctionWithDerivative.hxx>
27 #include <math_FunctionSample.hxx>
29 math_FunctionAllRoots::math_FunctionAllRoots (
30 math_FunctionWithDerivative& F,
31 const math_FunctionSample& S,
32 const Standard_Real EpsX, const Standard_Real EpsF,
33 const Standard_Real EpsNul) {
39 Standard_Boolean Nul, PNul, InterNul, Nuld, Nulf;
40 Standard_Real DebNul = 0., FinNul = 0.;
41 Standard_Integer Indd = 0, Indf = 0;
42 Standard_Real cst,val,valsav=0,valbid;
43 Standard_Boolean fini;
44 Standard_Integer Nbp,i;
47 F.Value(S.GetParameter(1),val);
48 PNul=Abs(val)<=EpsNul;
49 if (!PNul) {valsav=val;}
50 InterNul=Standard_False;
59 F.Value(S.GetParameter(i),val);
64 if (InterNul && (!Nul)) {
65 InterNul=Standard_False;
74 math_FunctionRoots Res1(F,S.GetParameter(i-1),S.GetParameter(i),10,
76 Standard_NumericError_Raise_if((!Res1.IsDone()) ||
78 (Res1.NbSolutions()==0), " ");
81 Indf=Res1.StateNumber(1);
84 math_FunctionRoots Res2(F,S.GetParameter(i-1),S.GetParameter(i),10,
86 Standard_NumericError_Raise_if((!Res2.IsDone()) ||
87 (Res2.IsAllNull())," ");
89 //-- || (Res2.NbSolutions()!=0), " "); lbr le 13 mai 87 (!=0 -> ==0)
90 if (Res2.NbSolutions()!=0) {
91 if (Res2.Value(1) < FinNul) {
92 FinNul = Res2.Value(1);
93 Indf = Res2.StateNumber(1);
99 else if ((!InterNul) && PNul && Nul) {
100 InterNul=Standard_True;
102 DebNul=S.GetParameter(1);
103 F.Value(DebNul,valbid);
104 Indd = F.GetStateNumber();
114 math_FunctionRoots Res1(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
116 Standard_NumericError_Raise_if((!Res1.IsDone()) ||
117 (Res1.IsAllNull()) ||
118 (Res1.NbSolutions()==0), " ");
119 DebNul=Res1.Value(Res1.NbSolutions());
120 Indd = Res1.StateNumber(Res1.NbSolutions());
123 math_FunctionRoots Res3(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
125 Standard_NumericError_Raise_if((!Res3.IsDone()) ||
126 (Res3.IsAllNull()), " ");
128 if (Res3.NbSolutions()!=0) {
129 if (Res3.Value(Res3.NbSolutions()) > DebNul) {
130 DebNul = Res3.Value(Res3.NbSolutions());
131 Indd = Res3.StateNumber(Res3.NbSolutions());
141 if (InterNul) { // rajouter l intervalle finissant au dernier pt
144 FinNul = S.GetParameter(Nbp);
145 F.Value(FinNul,valbid);
146 Indf = F.GetStateNumber();
152 if (pdeb.Length()==0) { // Pas d intervalle nul
154 math_FunctionRoots Res(F,S.GetParameter(1),S.GetParameter(Nbp),Nbp,
156 Standard_NumericError_Raise_if((!Res.IsDone()) ||
157 (Res.IsAllNull()), " ");
159 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
160 piso.Append(Res.Value(j));
161 iiso.Append(Res.StateNumber(j));
165 Standard_Integer NbpMin = 3;
166 Standard_Integer Nbrpt;
167 if (!Nuld) { // Recherche des solutions entre S.GetParameter(1)
168 // et le debut du 1er intervalle nul
170 Nbrpt=(Standard_Integer ) IntegerPart(
171 Abs((pdeb.Value(1)-S.GetParameter(1))/
172 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
173 math_FunctionRoots Res(F,S.GetParameter(1),pdeb.Value(1),
174 Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
175 Standard_NumericError_Raise_if((!Res.IsDone()) ||
176 (Res.IsAllNull()), " ");
178 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
179 piso.Append(Res.Value(j));
180 iiso.Append(Res.StateNumber(j));
183 for (Standard_Integer k=2; k<=pdeb.Length(); k++) {
184 Nbrpt=(Standard_Integer )
185 IntegerPart(Abs((pdeb.Value(k)-pfin.Value(k-1))/
186 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
187 math_FunctionRoots Res(F,pfin.Value(k-1),pdeb.Value(k),
188 Max(Nbrpt, NbpMin), EpsX,EpsF,0.0);
189 Standard_NumericError_Raise_if((!Res.IsDone()) ||
190 (Res.IsAllNull()), " ");
192 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
193 piso.Append(Res.Value(j));
194 iiso.Append(Res.StateNumber(j));
197 if (!Nulf) { // Recherche des solutions entre la fin du
198 // dernier intervalle nul et Value(Nbp).
200 Nbrpt=(Standard_Integer )
201 IntegerPart(Abs((S.GetParameter(Nbp)-
202 pfin.Value(pdeb.Length()))/
203 (S.GetParameter(Nbp)-S.GetParameter(1)))*Nbp);
204 math_FunctionRoots Res(F,pfin.Value(pdeb.Length()),
205 S.GetParameter(Nbp), Max(Nbrpt, NbpMin),
207 Standard_NumericError_Raise_if((!Res.IsDone()) ||
208 (Res.IsAllNull()), " ");
210 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
211 piso.Append(Res.Value(j));
212 iiso.Append(Res.StateNumber(j));
220 void math_FunctionAllRoots::Dump(Standard_OStream& o) const {
222 o<< "math_FunctionAllRoots ";
224 o<< " Status = Done \n";
225 o << " Number of null intervals = " << pdeb.Length() << endl;
226 o << " Number of points where the function is null: " << piso.Length() << endl;
229 o<< " Status = not Done \n";