10const double eps = std::numeric_limits<double>::epsilon();
11const double big = std::numeric_limits<double>::max();
12const double small = std::numeric_limits<double>::min();
23double cross(std::vector<int>& h, std::vector<double>& a,
int c,
int i) {
27 double a_hc = a[h_c1];
28 double det =
Laguerre::fms(a[i]-a_hc, (
double)(h_c-h_c1), a[h_c]-a_hc, (
double)(i-h_c1));
40void conv_hull(
int n, std::vector<double>& a, std::vector<int>& h,
int& c) {
43 for (
int i = n - 1; i >= 0; i--) {
44 while (c >= 2 &&
cross(h, a, c, i) <
eps)
60void estimates(std::vector<double>& alpha,
int deg, std::vector<std::complex<double>>& roots, std::vector<int>& conv,
int& nz) {
61 int c, i,
j,
k, nzeros;
62 double a1, a2, ang, r, th;
63 std::vector<int> h(
deg + 1);
64 std::vector<double> a(
deg + 1);
65 const double pi2 = 6.2831853071795865;
66 const double sigma = 0.7;
69 for (i = 0; i <
deg + 1; i++) {
81 for (i = c - 1; i >= 0; i--) {
82 nzeros = h[i] - h[i + 1];
83 a1 = pow(alpha[h[i + 1]], 1.0 / nzeros);
84 a2 = pow(alpha[h[i]], 1.0 / nzeros);
86 if (a1 <= a2 *
small) {
90 for (
j =
k;
j <
k + nzeros;
j++)
92 for (
j =
k;
j <
k + nzeros;
j++)
93 roots[
j] = {0.0, 0.0};
94 }
else if (a1 >= a2 *
big) {
98 for (
j =
k;
j <
k + nzeros;
j++)
101 for (
j = 0;
j < nzeros;
j++)
102 roots[
k +
j] = r * std::complex<double>(cos(ang *
j + th * h[i] + sigma), sin(ang *
j + th * h[i] + sigma));
107 for (
j = 0;
j < nzeros;
j++)
108 roots[
k +
j] = r * std::complex<double>(cos(ang *
j + th * h[i] + sigma), sin(ang *
j + th * h[i] + sigma));
121 double re_a = real(a);
122 double im_a = imag(a);
123 return std::isnan(re_a) || std::isnan(im_a) || (abs(re_a) >
big) || (abs(im_a) >
big);
140void rcheck_lag(std::vector<double>& p, std::vector<double>& alpha,
int deg, std::complex<double>&
b, std::complex<double>& c, std::complex<double>
z,
double r,
int& conv,
double& berr,
double& cond) {
143 std::complex<double> a, zz;
153 for (
k = 1;
k <
deg + 1;
k++) {
157 berr = rr * berr + alpha[
k];
161 if (abs(a) >
eps * berr) {
164 c = pow(zz, 2) * ((double)
deg - 2.0 * zz *
b + pow(zz, 2) * (pow(
b, 2) - c));
165 b = zz * ((double)
deg - zz *
b);
170 cond = berr / abs((
double)
deg * a - zz *
b);
171 berr = abs(a) / berr;
190void check_lag(std::vector<double>& p, std::vector<double>& alpha,
int deg, std::complex<double>&
b, std::complex<double>& c, std::complex<double>
z,
double r,
int& conv,
double& berr,
double& cond) {
192 std::complex<double> a;
200 for (
k =
deg - 1;
k >= 0;
k--) {
204 berr = r * berr + alpha[
k];
208 if (abs(a) >
eps * berr) {
210 c = pow(
b, 2) - 2.0 * (c / a);
215 cond = berr / (r * abs(
b));
216 berr = abs(a) / berr;
231void modify_lag(
int deg, std::complex<double>&
b, std::complex<double>& c, std::complex<double>
z,
int j, std::vector<std::complex<double>>& roots) {
232 std::complex<double> t;
235 for (
int k = 0;
k <
j - 1;
k++) {
236 t = 1.0 / (
z - roots[
k]);
241 for (
int k =
j + 1;
k <=
deg;
k++) {
242 t = 1.0 / (
z - roots[
k]);
249 (
double)(
deg - 1) * (
250 (
double)
deg * c - pow(
b, 2)
256 if (abs(
b) > abs(c)) {
274void laguerre(std::vector<double>& poly,
int deg, std::vector<std::complex<double>>& roots, std::vector<int>& conv,
int itmax) {
277 std::vector<double> berr(
deg);
278 std::vector<double> cond(
deg);
279 std::vector<double> alpha(
deg + 1);
280 std::complex<double>
b, c,
z;
283 for (i = 0; i <=
deg; i++)
284 alpha[i] = abs(poly[i]);
287 std::cout <<
"Warning: leading coefficient too small." << std::endl;
317 for (i = 1; i <=
deg + 1; i++)
318 alpha[i - 1] = alpha[i - 1] * (3.8 * (i - 1) + 1);
320 for (i = 1; i <= itmax; i++) {
321 for (
j = 0;
j <
deg;
j++) {
333 roots[
j] = roots[
j] - c;
345 if (*std::min_element(conv.begin(), conv.end()) == 1) {
349 std::cout <<
"Some root approximations did not converge or experienced overflow/underflow." << std::endl;
352 for (
j = 0;
j <
deg;
j++) {
364 for (i = 1; i <
deg + 1; i++) {
368 berr[
j] = r * berr[
j] + alpha[i];
371 cond[
j] = berr[
j] / abs((
double)
deg *
b -
z * c);
372 berr[
j] = abs(
b) / berr[
j];
376 berr[
j] = alpha[
deg];
378 for (i =
deg - 1; i >= 0; i--) {
382 berr[
j] = r * berr[
j] + alpha[i];
385 cond[
j] = berr[
j] / (r * abs(c));
386 berr[
j] = abs(
b) / berr[
j];
const double big
Definition L18_or.h:11
const double small
Definition L18_or.h:12
const double eps
Definition L18_or.h:10
bool check_nan_inf(std::complex< double > a)
Check if a complex number contains NaN or Inf values.
Definition L18_or.h:120
void rcheck_lag(std::vector< double > &p, std::vector< double > &alpha, int deg, std::complex< double > &b, std::complex< double > &c, std::complex< double > z, double r, int &conv, double &berr, double &cond)
Perform Laguerre correction, compute backward error, and condition.
Definition L18_or.h:140
void estimates(std::vector< double > &alpha, int deg, std::vector< std::complex< double > > &roots, std::vector< int > &conv, int &nz)
Estimate roots of a polynomial.
Definition L18_or.h:60
double cross(std::vector< int > &h, std::vector< double > &a, int c, int i)
Calculate the determinant between two points.
Definition L18_or.h:23
void modify_lag(int deg, std::complex< double > &b, std::complex< double > &c, std::complex< double > z, int j, std::vector< std::complex< double > > &roots)
Modify Laguerre correction based on Aberth's method.
Definition L18_or.h:231
void check_lag(std::vector< double > &p, std::vector< double > &alpha, int deg, std::complex< double > &b, std::complex< double > &c, std::complex< double > z, double r, int &conv, double &berr, double &cond)
Perform Laguerre correction, compute backward error, and condition.
Definition L18_or.h:190
void laguerre(std::vector< double > &poly, int deg, std::vector< std::complex< double > > &roots, std::vector< int > &conv, int itmax)
Find the roots of a polynomial using Laguerre's method.
Definition L18_or.h:274
void conv_hull(int n, std::vector< double > &a, std::vector< int > &h, int &c)
Calculate the convex hull of a set of points.
Definition L18_or.h:40
c0 z
Definition Laguerre15m_or.h:21
p2 de j *z j
Definition Laguerre15m_or.h:23
cohn_schur ra local deg
Definition Laguerre15m_or.h:3
cohn_schur ra local b
Definition Laguerre15m_or.h:3
cohn_schur ra local k
Definition Laguerre15m_or.h:3
number fms(number a, number b, number c, number d)
Fused multiply-substract a*b+(-d*c)+d*c+(-d*c)
Definition ExtendedFunctions.h:63