Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Polynomial.cxx
Go to the documentation of this file.
1// @(#)root/mathmore:$Id$
2// Authors: L. Moneta, A. Zsenei 08/2005
3
4 /**********************************************************************
5 * *
6 * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT *
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License *
10 * as published by the Free Software Foundation; either version 2 *
11 * of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this library (see file COPYING); if not, write *
20 * to the Free Software Foundation, Inc., 59 Temple Place, Suite *
21 * 330, Boston, MA 02111-1307 USA, or contact the author. *
22 * *
23 **********************************************************************/
24
25// Implementation file for class Polynomial
26//
27// Created by: Lorenzo Moneta at Wed Nov 10 17:46:19 2004
28//
29// Last update: Wed Nov 10 17:46:19 2004
30//
31
32#include "Math/Polynomial.h"
33
34
35#include "gsl/gsl_math.h"
36#include "gsl/gsl_errno.h"
37#include "gsl/gsl_poly.h"
38#include "complex_quartic.h"
39
40#define DEBUG
41#ifdef DEBUG
42#include <iostream>
43#endif
44
45namespace ROOT {
46namespace Math {
47
48
50 // number of par is order + 1
51 ParFunc( n+1 ),
52 fOrder(n),
53 fDerived_params(std::vector<double>(n) )
54{
55}
56
57 //order 1
58Polynomial::Polynomial(double a, double b) :
59 ParFunc( 2 ),
60 fOrder(1),
61 fDerived_params(std::vector<double>(1) )
62{
63 fParams[0] = b;
64 fParams[1] = a;
65}
66
67// order 2
68Polynomial::Polynomial(double a, double b, double c) :
69 ParFunc( 3 ),
70 fOrder(2),
71 fDerived_params(std::vector<double>(2) )
72{
73 fParams[0] = c;
74 fParams[1] = b;
75 fParams[2] = a;
76}
77
78// order 3 (cubic)
79Polynomial::Polynomial(double a, double b, double c, double d) :
80 // number of par is order + 1
81 ParFunc( 4 ),
82 fOrder(3),
83 fDerived_params(std::vector<double>(3) )
84{
85 fParams[0] = d;
86 fParams[1] = c;
87 fParams[2] = b;
88 fParams[3] = a;
89}
90
91// order 3 (quartic)
92Polynomial::Polynomial(double a, double b, double c, double d, double e) :
93 // number of par is order + 1
94 ParFunc( 5 ),
95 fOrder(4),
96 fDerived_params(std::vector<double>(4) )
97{
98 fParams[0] = e;
99 fParams[1] = d;
100 fParams[2] = c;
101 fParams[3] = b;
102 fParams[4] = a;
103}
104
105
106
107// Polynomial::Polynomial(const Polynomial &)
108// {
109// }
110
111// Polynomial & Polynomial::operator = (const Polynomial &rhs)
112// {
113// if (this == &rhs) return *this; // time saving self-test
114
115// return *this;
116// }
117
118
119double Polynomial::DoEvalPar (double x, const double * p) const {
120
121 return gsl_poly_eval( p, fOrder + 1, x);
122
123}
124
125
126
127double Polynomial::DoDerivative(double x) const{
128
129 for ( unsigned int i = 0; i < fOrder; ++i )
130 fDerived_params[i] = (i + 1) * Parameters()[i+1];
131
132 return gsl_poly_eval( &fDerived_params.front(), fOrder, x);
133
134}
135
136double Polynomial::DoParameterDerivative (double x, const double *, unsigned int ipar) const {
137
138 return gsl_pow_int(x, ipar);
139}
140
141
142
144 Polynomial * f = new Polynomial(fOrder);
145 f->fDerived_params = fDerived_params;
146 f->SetParameters( Parameters() );
147 return f;
148}
149
150std::vector<std::complex<double>> Polynomial::FindRoots() const
151{
152
153 // check if order is correct
154 unsigned int n = fOrder;
155 while (Parameters()[n] == 0) {
156 n--;
157 }
158
159 std::vector<std::complex<double>> roots;
160
161 if (n == 0) {
162 return roots;
163 } else if (n == 1) {
164 if (Parameters()[1] == 0)
165 return roots;
166 double r = - Parameters()[0]/ Parameters()[1];
167 roots.push_back(std::complex<double>(r, 0.0));
168 }
169 // quadratic equations
170 else if (n == 2) {
173 if ( nr != 2) {
174#ifdef DEBUG
175 std::cout << "Polynomial quadratic ::- FAILED to find roots" << std::endl;
176#endif
177 return roots;
178 }
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) {
185 // renormmalize params in this case
186 double w = Parameters()[3];
187 double a = Parameters()[2]/w;
188 double b = Parameters()[1]/w;
189 double c = Parameters()[0]/w;
190 int nr = gsl_poly_complex_solve_cubic(a, b, c, &z1, &z2, &z3);
191 if (nr != 3) {
192#ifdef DEBUG
193 std::cout << "Polynomial cubic::- FAILED to find roots" << std::endl;
194#endif
195 return roots;
196 }
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) {
203 // quartic eq.
204 gsl_complex z1, z2, z3, z4;
205 // renormalize params in this case
206 double w = Parameters()[4];
207 double a = Parameters()[3]/w;
208 double b = Parameters()[2]/w;
209 double c = Parameters()[1]/w;
210 double d = Parameters()[0]/w;
211 int nr = gsl_poly_complex_solve_quartic(a, b, c, d, &z1, &z2, &z3, & z4);
212 if (nr != 4) {
213#ifdef DEBUG
214 std::cout << "Polynomial quartic ::- FAILED to find roots" << std::endl;
215#endif
216 return roots;
217 }
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;
228}
229
230std::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());
237
238 return realRoots;
239}
240std::vector<std::complex<double>> Polynomial::FindNumRoots() const
241{
242
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
255 std::vector<double> z(2 * n);
256 int status = gsl_poly_complex_solve(Parameters(), n + 1, w, &z.front());
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}
265
266} // namespace Math
267} // namespace ROOT
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h:157
const double * Parameters() const override
Access the parameter values.
Parametric Function class describing polynomials of order n.
Definition Polynomial.h:66
std::vector< std::complex< double > > FindRoots() const
Find the polynomial roots.
Polynomial(unsigned int n=0)
Construct a Polynomial function of order n.
std::vector< std::complex< double > > FindNumRoots() const
Find the polynomial roots using always an iterative numerical methods The numerical method used is fr...
double DoEvalPar(double x, const double *p) const override
Implementation of the evaluation function using the x value and the parameters.
IGenFunction * Clone() const override
Clone a function.
double DoParameterDerivative(double x, const double *p, unsigned int ipar) const override
Evaluate the gradient, to be implemented by the derived classes.
double DoDerivative(double x) const override
Function to evaluate the derivative with respect each coordinate. To be implemented by the derived cl...
std::vector< double > FindRealRoots() const
Find the only the real polynomial roots.
std::vector< double > fDerived_params
Definition Polynomial.h:166
int gsl_poly_complex_solve_quartic(double a, double b, double c, double d, gsl_complex *z0, gsl_complex *z1, gsl_complex *z2, gsl_complex *z3)
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Namespace for new Math classes and functions.
TCanvas * roots()
Definition roots.C:1
int gsl_poly_complex_solve_cubic(double a, double b, double c, gsl_complex *z0, gsl_complex *z1, gsl_complex *z2)