@@ -147,43 +147,40 @@ IGenFunction * Polynomial::Clone() const {
147147 return f;
148148}
149149
150+ std::vector<std::complex <double >> Polynomial::FindRoots () const
151+ {
150152
151- const std::vector< std::complex <double > > & Polynomial::FindRoots (){
152-
153-
154- // check if order is correct
155- unsigned int n = fOrder ;
156- while ( Parameters ()[n] == 0 ) {
153+ // check if order is correct
154+ unsigned int n = fOrder ;
155+ while (Parameters ()[n] == 0 ) {
157156 n--;
158- }
159-
160- fRoots .clear ();
161- fRoots .reserve (n);
157+ }
162158
159+ std::vector<std::complex <double >> roots;
163160
164- if (n == 0 ) {
165- return fRoots ;
166- }
167- else if (n == 1 ) {
168- if ( Parameters ()[ 1 ] == 0 ) return fRoots ;
161+ if (n == 0 ) {
162+ return roots ;
163+ } else if (n == 1 ) {
164+ if (Parameters ()[ 1 ] == 0 )
165+ return roots ;
169166 double r = - Parameters ()[0 ]/ Parameters ()[1 ];
170- fRoots .push_back ( std::complex <double > ( r, 0.0 ) );
171- }
172- // quadratic equations
173- else if (n == 2 ) {
167+ roots .push_back (std::complex <double >( r, 0.0 ));
168+ }
169+ // quadratic equations
170+ else if (n == 2 ) {
174171 gsl_complex z1, z2;
175172 int nr = gsl_poly_complex_solve_quadratic (Parameters ()[2 ], Parameters ()[1 ], Parameters ()[0 ], &z1, &z2);
176173 if ( nr != 2 ) {
177174#ifdef DEBUG
178175 std::cout << " Polynomial quadratic ::- FAILED to find roots" << std::endl;
179176#endif
180- return fRoots ;
177+ return roots ;
181178 }
182- fRoots .push_back (std::complex <double >(z1.dat [0 ],z1.dat [1 ]) );
183- fRoots .push_back (std::complex <double >(z2.dat [0 ],z2.dat [1 ]) );
184- }
185- // cubic equations
186- else if (n == 3 ) {
179+ roots .push_back (std::complex <double >(z1.dat [0 ], z1.dat [1 ]));
180+ roots .push_back (std::complex <double >(z2.dat [0 ], z2.dat [1 ]));
181+ }
182+ // cubic equations
183+ else if (n == 3 ) {
187184 gsl_complex z1, z2, z3;
188185 // renormmalize params in this case
189186 double w = Parameters ()[3 ];
@@ -195,15 +192,14 @@ const std::vector< std::complex <double> > & Polynomial::FindRoots(){
195192#ifdef DEBUG
196193 std::cout << " Polynomial cubic::- FAILED to find roots" << std::endl;
197194#endif
198- return fRoots ;
199-
195+ return roots;
200196 }
201- fRoots .push_back (std::complex <double > (z1.dat [0 ],z1.dat [1 ]) );
202- fRoots .push_back (std::complex <double > (z2.dat [0 ],z2.dat [1 ]) );
203- fRoots .push_back (std::complex <double > (z3.dat [0 ],z3.dat [1 ]) );
204- }
205- // quartic equations
206- else if (n == 4 ) {
197+ roots .push_back (std::complex <double >(z1.dat [0 ], z1.dat [1 ]));
198+ roots .push_back (std::complex <double >(z2.dat [0 ], z2.dat [1 ]));
199+ roots .push_back (std::complex <double >(z3.dat [0 ], z3.dat [1 ]));
200+ }
201+ // quartic equations
202+ else if (n == 4 ) {
207203 // quartic eq.
208204 gsl_complex z1, z2, z3, z4;
209205 // renormalize params in this case
@@ -217,60 +213,55 @@ const std::vector< std::complex <double> > & Polynomial::FindRoots(){
217213#ifdef DEBUG
218214 std::cout << " Polynomial quartic ::- FAILED to find roots" << std::endl;
219215#endif
220- return fRoots ;
216+ return roots ;
221217 }
222- fRoots .push_back (std::complex <double > (z1.dat [0 ],z1.dat [1 ]) );
223- fRoots .push_back (std::complex <double > (z2.dat [0 ],z2.dat [1 ]) );
224- fRoots .push_back (std::complex <double > (z3.dat [0 ],z3.dat [1 ]) );
225- fRoots .push_back (std::complex <double > (z4.dat [0 ],z4.dat [1 ]) );
226- }
227- else {
228- // for higher order polynomial use numerical fRoots
229- FindNumRoots ();
230- }
231-
232- return fRoots ;
233-
234- }
235-
236-
237- std::vector< double > Polynomial::FindRealRoots (){
238- FindRoots ();
239- std::vector<double > roots;
240- roots.reserve (fOrder );
241- for (unsigned int i = 0 ; i < fOrder ; ++i) {
242- if (fRoots [i].imag () == 0 )
243- roots.push_back ( fRoots [i].real () );
244- }
245- return roots;
218+ roots.push_back (std::complex <double >(z1.dat [0 ], z1.dat [1 ]));
219+ roots.push_back (std::complex <double >(z2.dat [0 ], z2.dat [1 ]));
220+ roots.push_back (std::complex <double >(z3.dat [0 ], z3.dat [1 ]));
221+ roots.push_back (std::complex <double >(z4.dat [0 ], z4.dat [1 ]));
222+ } else {
223+ // for higher order polynomial use numerical roots
224+ return FindNumRoots ();
225+ }
226+
227+ return roots;
246228}
247- const std::vector< std::complex <double > > & Polynomial::FindNumRoots (){
248-
249-
250- // check if order is correct
251- unsigned int n = fOrder ;
252- while ( Parameters ()[n] == 0 ) {
253- n--;
254- }
255- fRoots .clear ();
256- fRoots .reserve (n);
257-
258229
259- if (n == 0 ) {
260- return fRoots ;
261- }
262-
263- gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc ( n + 1 );
264- std::vector<double > z (2 *n);
265- int status = gsl_poly_complex_solve ( Parameters (), n+1 , w, &z.front () );
266- gsl_poly_complex_workspace_free (w);
267- if (status != GSL_SUCCESS) return fRoots ;
268- for (unsigned int i = 0 ; i < n; ++i)
269- fRoots .push_back (std::complex <double > (z[2 *i],z[2 *i+1 ] ) );
230+ std::vector<double > Polynomial::FindRealRoots () const
231+ {
232+ auto roots = FindRoots ();
233+ std::vector<double > realRoots;
234+ for (const auto &r : roots)
235+ if (std::abs (r.imag ()) < std::numeric_limits<double >::epsilon ())
236+ realRoots.push_back (r.real ());
270237
271- return fRoots ;
238+ return realRoots ;
272239}
240+ std::vector<std::complex <double >> Polynomial::FindNumRoots () const
241+ {
273242
243+ // check if order is correct
244+ unsigned int n = fOrder ;
245+ while (Parameters ()[n] == 0 ) {
246+ n--;
247+ }
248+
249+ std::vector<std::complex <double >> roots;
250+ if (n == 0 ) {
251+ return roots;
252+ }
253+
254+ gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc (n + 1 );
255+ std::vector<double > z (2 * n);
256+ int status = gsl_poly_complex_solve (Parameters (), n + 1 , w, &z.front ());
257+ gsl_poly_complex_workspace_free (w);
258+ if (status != GSL_SUCCESS)
259+ return roots;
260+ for (unsigned int i = 0 ; i < n; ++i)
261+ roots.push_back (std::complex <double >(z[2 * i], z[2 * i + 1 ]));
262+
263+ return roots;
264+ }
274265
275266} // namespace Math
276267} // namespace ROOT
0 commit comments