25 #include "Laguerre.hh"
26 #include "Base/Debug/Error.hh"
27 #include <Base/Common/BIASpragma.hh>
33 int LaguerreSolver::Solve(
const std::vector< double >& coeffs,
34 std::vector< std::complex<double> >& roots,
37 std::vector< std::complex<double> > complcoeffs;
38 for(
unsigned int i=0; i<coeffs.size(); i++)
41 complcoeffs.push_back(complex<double>(coeffs[i],0));
43 return(Solve(complcoeffs,roots,eps));
46 int LaguerreSolver::Solve(
const std::vector< std::complex<double> >& coeffs,
47 std::vector< std::complex<double> >& roots,
52 complex<double> x,b,c;
54 int m = coeffs.size()-1;
55 vector< complex<double> > ad(m+1);
56 for (
int j=0;j<=m;j++)
60 for (
int j=m-1;j>=0;j--)
63 vector< complex<double> > ad_v(j+2);
64 for (
int jj=0;jj<j+2;jj++)
68 iter = _Laguerre(ad_v,x);
70 if (abs(imag(x)) <= 2.0*eps*abs(real(x)))
72 x=complex<double>(real(x),0.0);
76 for (
int jj=j;jj>=0;jj--)
87 iter = _Laguerre(coeffs,roots[j]);
96 if(real(roots[i])<=real(x))
break;
104 int LaguerreSolver::_Laguerre(
const std::vector< std::complex<double> >& coeffs,
105 std::complex<double>& x)
110 const int MAXIT = MT * MR;
111 const double EPS = numeric_limits<double>::epsilon();
112 static const double frac[MR+1] = {0.0,0.5,0.25,0.75,0.13,0.38,0.62,0.88,1.0};
113 complex<double> dx,x1,b,d,f,g,h,sq,gp,gm,g2;
114 unsigned int m=coeffs.size()-1;
115 for (
int it=1;it<=MAXIT;it++)
122 for (
int j=m-1;j>=0;j--)
130 if (abs(b) <= err)
return iter;
134 sq=sqrt(
double(m-1)*(
double(m)*h-g2));
145 dx = ((double) m)/gp;
149 dx = std::polar(1+abx,((
double)it));
165 BIASWARN(
"too many iterations");