0024044: Performance improvements: Foundation Classes (math)
[occt.git] / src / math / math_FunctionAllRoots.cxx
CommitLineData
b311480e 1// Copyright (c) 1997-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
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.
8//
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.
11//
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.
18
7fd59977 19//#ifndef DEB
20#define No_Standard_RangeError
21#define No_Standard_OutOfRange
22#define No_Standard_DimensionError
23//#endif
24
25#include <math_FunctionAllRoots.ixx>
26
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>
32
b311480e 33math_FunctionAllRoots::math_FunctionAllRoots (
7fd59977 34 math_FunctionWithDerivative& F,
35 const math_FunctionSample& S,
36 const Standard_Real EpsX, const Standard_Real EpsF,
37 const Standard_Real EpsNul) {
38
39 done=Standard_False;
40
41
42
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;
49
50 Nbp=S.NbPoints();
51 bid=F.Value(S.GetParameter(1),val);
52 PNul=Abs(val)<=EpsNul;
53 if (!PNul) {valsav=val;}
54 InterNul=Standard_False;
55 Nuld=Standard_False;
56 Nulf=Standard_False;
57
58 i=2;
59 fini=(i>Nbp);
60
61 while (!fini) {
62
63 bid=F.Value(S.GetParameter(i),val);
64 Nul=Abs(val)<=EpsNul;
65 if (!Nul) {
66 valsav=val;
67 }
68 if (InterNul && (!Nul)) {
69 InterNul=Standard_False;
70 pdeb.Append(DebNul);
71 ideb.Append(Indd);
72 if (val>0.0) {
73 cst=EpsNul;
74 }
75 else {
76 cst=-EpsNul;
77 }
78 math_FunctionRoots Res1(F,S.GetParameter(i-1),S.GetParameter(i),10,
79 EpsX,EpsF,0.0,cst);
80 Standard_NumericError_Raise_if((!Res1.IsDone()) ||
81 (Res1.IsAllNull()) ||
82 (Res1.NbSolutions()==0), " ");
83
84 FinNul=Res1.Value(1);
85 Indf=Res1.StateNumber(1);
86
87 cst=-cst;
88 math_FunctionRoots Res2(F,S.GetParameter(i-1),S.GetParameter(i),10,
89 EpsX,EpsF,0.0,cst);
90 Standard_NumericError_Raise_if((!Res2.IsDone()) ||
91 (Res2.IsAllNull())," ");
92
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);
98 }
99 }
100 pfin.Append(FinNul);
101 ifin.Append(Indf);
102 }
103 else if ((!InterNul) && PNul && Nul) {
104 InterNul=Standard_True;
105 if (i==2) {
106 DebNul=S.GetParameter(1);
107 bid = F.Value(DebNul,valbid);
108 Indd = F.GetStateNumber();
109 Nuld=Standard_True;
110 }
111 else {
112 if (valsav>0.0) {
113 cst=EpsNul;
114 }
115 else {
116 cst=-EpsNul;
117 }
118 math_FunctionRoots Res1(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
119 EpsX,EpsF,0.0,cst);
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());
125
126 cst=-cst;
127 math_FunctionRoots Res3(F,S.GetParameter(i-2),S.GetParameter(i-1),10,
128 EpsX,EpsF,0.0,cst);
129 Standard_NumericError_Raise_if((!Res3.IsDone()) ||
130 (Res3.IsAllNull()), " ");
131
132 if (Res3.NbSolutions()!=0) {
133 if (Res3.Value(Res3.NbSolutions()) > DebNul) {
134 DebNul = Res3.Value(Res3.NbSolutions());
135 Indd = Res3.StateNumber(Res3.NbSolutions());
136 }
137 }
138 }
139 }
140 i=i+1;
141 PNul=Nul;
142 fini=(i>Nbp);
143 }
144
145 if (InterNul) { // rajouter l intervalle finissant au dernier pt
146 pdeb.Append(DebNul);
147 ideb.Append(Indd);
148 FinNul = S.GetParameter(Nbp);
149 bid = F.Value(FinNul,valbid);
150 Indf = F.GetStateNumber();
151 pfin.Append(FinNul);
152 ifin.Append(Indf);
153 Nulf=Standard_True;
154 }
155
156 if (pdeb.Length()==0) { // Pas d intervalle nul
157
158 math_FunctionRoots Res(F,S.GetParameter(1),S.GetParameter(Nbp),Nbp,
159 EpsX,EpsF,0.0);
160 Standard_NumericError_Raise_if((!Res.IsDone()) ||
161 (Res.IsAllNull()), " ");
162
163 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
164 piso.Append(Res.Value(j));
165 iiso.Append(Res.StateNumber(j));
166 }
167 }
168 else {
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
173
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()), " ");
181
182 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
183 piso.Append(Res.Value(j));
184 iiso.Append(Res.StateNumber(j));
185 }
186 }
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()), " ");
195
196 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
197 piso.Append(Res.Value(j));
198 iiso.Append(Res.StateNumber(j));
199 }
200 }
201 if (!Nulf) { // Recherche des solutions entre la fin du
202 // dernier intervalle nul et Value(Nbp).
203
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),
210 EpsX,EpsF,0.0);
211 Standard_NumericError_Raise_if((!Res.IsDone()) ||
212 (Res.IsAllNull()), " ");
213
214 for (Standard_Integer j=1; j<=Res.NbSolutions(); j++) {
215 piso.Append(Res.Value(j));
216 iiso.Append(Res.StateNumber(j));
217 }
218 }
219 }
220 done=Standard_True;
221 }
222
223
224void math_FunctionAllRoots::Dump(Standard_OStream& o) const {
225
226 o<< "math_FunctionAllRoots ";
227 if(done) {
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;
231 }
232 else {
233 o<< " Status = not Done \n";
234 }
235}