#include "Math/Polynomial.h"
#include "gsl/gsl_math.h"
#include "gsl/gsl_errno.h"
#include "gsl/gsl_poly.h"
#include "gsl/gsl_poly.h"
#include "complex_quartic.h"
#define DEBUG
#ifdef DEBUG
#include <iostream>
#endif
namespace ROOT {
namespace Math {
Polynomial::Polynomial(unsigned int n) :
ParamFunction( n+1, true, true),
fOrder(n),
fDerived_params(std::vector<double>(n) )
{
}
Polynomial::Polynomial(double a, double b) :
ParamFunction( 2, true, true),
fOrder(1),
fDerived_params(std::vector<double>(1) )
{
fParams[0] = b;
fParams[1] = a;
}
Polynomial::Polynomial(double a, double b, double c) :
ParamFunction( 3, true, true),
fOrder(2),
fDerived_params(std::vector<double>(2) )
{
fParams[0] = c;
fParams[1] = b;
fParams[2] = a;
}
Polynomial::Polynomial(double a, double b, double c, double d) :
ParamFunction( 4, true, true),
fOrder(3),
fDerived_params(std::vector<double>(3) )
{
fParams[0] = d;
fParams[1] = c;
fParams[2] = b;
fParams[3] = a;
}
Polynomial::Polynomial(double a, double b, double c, double d, double e) :
ParamFunction( 5, true, true),
fOrder(4),
fDerived_params(std::vector<double>(4) )
{
fParams[0] = e;
fParams[1] = d;
fParams[2] = c;
fParams[3] = b;
fParams[4] = a;
}
Polynomial::~Polynomial()
{
}
double Polynomial::DoEval (double x) const {
return gsl_poly_eval( &fParams.front(), fOrder + 1, x);
}
double Polynomial::operator() (double x, const double * p) {
return gsl_poly_eval( p, fOrder + 1, x);
}
double Polynomial::DoDerivative(double x) const{
for ( unsigned int i = 0; i < fOrder; ++i )
fDerived_params[i] = (i + 1) * Parameters()[i+1];
return gsl_poly_eval( &fDerived_params.front(), fOrder, x);
}
void Polynomial::DoParameterGradient (double x, double * grad) const {
unsigned int npar = NPar();
for (unsigned int i = 0; i < npar; ++i)
grad[i] = gsl_pow_int(x, i);
}
IGenFunction * Polynomial::Clone() const {
Polynomial * f = new Polynomial(fOrder);
f->fDerived_params = fDerived_params;
f->SetParameters( Parameters() );
return f;
}
const std::vector< std::complex <double> > & Polynomial::FindRoots(){
unsigned int n = fOrder;
while ( Parameters()[n] == 0 ) {
n--;
}
fRoots.clear();
fRoots.reserve(n);
if (n == 0) {
return fRoots;
}
else if (n == 1 ) {
if ( Parameters()[1] == 0) return fRoots;
double r = - Parameters()[0]/ Parameters()[1];
fRoots.push_back( std::complex<double> ( r, 0.0) );
}
else if (n == 2 ) {
gsl_complex z1, z2;
int nr = gsl_poly_complex_solve_quadratic(Parameters()[2], Parameters()[1], Parameters()[0], &z1, &z2);
if ( nr != 2) {
#ifdef DEBUG
std::cout << "Polynomial quadratic ::- FAILED to find roots" << std::endl;
#endif
return fRoots;
}
fRoots.push_back(std::complex<double>(z1.dat[0],z1.dat[1]) );
fRoots.push_back(std::complex<double>(z2.dat[0],z2.dat[1]) );
}
else if (n == 3 ) {
gsl_complex z1, z2, z3;
double w = Parameters()[3];
double a = Parameters()[2]/w;
double b = Parameters()[1]/w;
double c = Parameters()[0]/w;
int nr = gsl_poly_complex_solve_cubic(a, b, c, &z1, &z2, &z3);
if (nr != 3) {
#ifdef DEBUG
std::cout << "Polynomial cubic::- FAILED to find roots" << std::endl;
#endif
return fRoots;
}
fRoots.push_back(std::complex<double> (z1.dat[0],z1.dat[1]) );
fRoots.push_back(std::complex<double> (z2.dat[0],z2.dat[1]) );
fRoots.push_back(std::complex<double> (z3.dat[0],z3.dat[1]) );
}
else if (n == 4 ) {
gsl_complex z1, z2, z3, z4;
double w = Parameters()[4];
double a = Parameters()[3]/w;
double b = Parameters()[2]/w;
double c = Parameters()[1]/w;
double d = Parameters()[0]/w;
int nr = gsl_poly_complex_solve_quartic(a, b, c, d, &z1, &z2, &z3, & z4);
if (nr != 4) {
#ifdef DEBUG
std::cout << "Polynomial quartic ::- FAILED to find roots" << std::endl;
#endif
return fRoots;
}
fRoots.push_back(std::complex<double> (z1.dat[0],z1.dat[1]) );
fRoots.push_back(std::complex<double> (z2.dat[0],z2.dat[1]) );
fRoots.push_back(std::complex<double> (z3.dat[0],z3.dat[1]) );
fRoots.push_back(std::complex<double> (z4.dat[0],z4.dat[1]) );
}
else {
FindNumRoots();
}
return fRoots;
}
std::vector< double > Polynomial::FindRealRoots(){
FindRoots();
std::vector<double> roots;
roots.reserve(fOrder);
for (unsigned int i = 0; i < fOrder; ++i) {
if (fRoots[i].imag() == 0)
roots.push_back( fRoots[i].real() );
}
return roots;
}
const std::vector< std::complex <double> > & Polynomial::FindNumRoots(){
unsigned int n = fOrder;
while ( Parameters()[n] == 0 ) {
n--;
}
fRoots.clear();
fRoots.reserve(n);
if (n == 0) {
return fRoots;
}
gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc( n + 1);
std::vector<double> z(2*n);
int status = gsl_poly_complex_solve ( Parameters(), n+1, w, &z.front() );
gsl_poly_complex_workspace_free(w);
if (status != GSL_SUCCESS) return fRoots;
for (unsigned int i = 0; i < n; ++i)
fRoots.push_back(std::complex<double> (z[2*i],z[2*i+1] ) );
return fRoots;
}
}
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.