25 static constexpr T
eps = std::numeric_limits<T>::epsilon();
26 static constexpr T
big = std::numeric_limits<T>::max();
27 static constexpr T
small = std::numeric_limits<T>::min();
29 static constexpr T
PI = std::numbers::pi_v<T>;
30 static constexpr T
pi2 =
PI*
static_cast<T
>(2);
41 inline T
cross(std::vector<int>& h, std::vector<T>& a,
int c,
int i) {
46 return fms(a[i]-a_hc,
static_cast<T
>(h_c-h_c1), a[h_c]-a_hc,
static_cast<T
>(i-h_c1));
56 inline void conv_hull(
int n, std::vector<T>& a, std::vector<int>& h,
int& c) {
59 for (
int i = n - 1; i >= 0; --i) {
60 while (c >= 2 &&
cross(h, a, c, i) <
eps)
75 inline void estimates(vector<T>& alpha,
int deg, std::vector<std::complex<T>>& roots, std::vector<int>& conv,
int& nz) {
76 int c, i,
j,
k, nzeros;
78 std::vector<int> h(
deg + 1);
79 std::vector<T> a(
deg + 1);
82 for (i = 0; i <
deg + 1; ++i)
83 a[i] = alpha[i] > 0 ? log(alpha[i]) : -
big;
87 th =
pi2/
static_cast<T
>(
deg);
90 for (i = c - 1; i >= 0; --i) {
91 nzeros = h[i] - h[i + 1];
92 T one_div_nzeros =
static_cast<T
>(1.0 / nzeros);
93 a1 = pow(alpha[h[i + 1]], one_div_nzeros);
94 a2 = pow(alpha[h[i]], one_div_nzeros);
104 if (a1 <= a2 *
small){
108 for (
j =
k;
j <
k + nzeros; ++
j){
110 roots[
j] = {0.0, 0.0};
114 T sigma_thh =
fma(th, h[i],
static_cast<T
>(0.7));
119 for (
j =
k;
j <
k + nzeros; ++
j)
126 ang =
pi2 /
static_cast<T
>(nzeros);
127 for (
j = 0;
j < nzeros; ++
j){
128 T arg =
fma(ang,
j, sigma_thh);
129 roots[
k +
j] = r * std::complex<T>(cos(arg), sin(arg));
149 inline void rcheck_lag(std::vector<T>& p, vector<T>& alpha,
int deg, complex<T>&
b, complex<T>& c, complex<T>
z, T r,
int& conv, T& berr, T& cond) {
152 complex<T> a, zz, zz2;
155 zz = complex<T>(1, 0) /
z;
157 rr =
static_cast<T
>(1) / r;
163 for (
k = 1;
k <
deg + 1; ++
k) {
166 a =
fma(zz, a, p[
k]);
167 berr =
fma(rr, berr, alpha[
k]);
171 bool condition = abs(a) >
eps * berr;
172 b = condition ?
b/a :
b;
173 c = condition ?
fms(zz2,
fma(-
static_cast<T
>(2)*zz,
b,
static_cast<T
>(
deg)), zz2*zz2,
fms(complex<T>(2.0, 0), c / a,
b,
b)) : c;
174 b = condition ?
fms(zz, complex<T>(
deg, 0) , zz2,
b) :
b;
176 cond = (!condition)*(berr / fabs(
fms(complex<T>(
deg, 0), a, zz,
b))) + (condition)*cond;
177 berr = (!condition)*(fabs(a) / berr) + (condition)*berr;
212 inline void check_lag(std::vector<T>& p, std::vector<T>& alpha,
int deg, std::complex<T>&
b, std::complex<T>& c, std::complex<T>
z, T r,
int& conv, T& berr, T& cond) {
222 for (
k =
deg - 1;
k >= 0; --
k) {
226 berr =
fma(r, berr, alpha[
k]);
230 bool condition = abs(a) >
eps * berr;
231 b = condition ?
b/a :
b;
233 c = condition ?
fms(
b,
b, std::complex<T>(2, 0), c/a) : c;
235 cond = (!condition)*(berr / (r * fabs(
b))) + (condition)*cond;
236 berr = (!condition)*(fabs(a) / berr) + (condition)*berr;
267 void modify_lag(
int deg, std::complex<T>&
b, std::complex<T>& c, std::complex<T>
z,
int j, std::vector<std::complex<T>>& roots) {
271 for (
int k = 0;
k <
j - 1; ++
k) {
272 t =
static_cast<T
>(1.0) / (
z - roots[
k]);
277 for (
int k =
j + 1;
k <=
deg; ++
k) {
278 t =
static_cast<T
>(1.0) / (
z - roots[
k]);
284 t = sqrt(
fms(complex<T>(
static_cast<T
>(
deg - 1), 0), (
static_cast<T
>(
deg) * c),
b,
b));
288 c = abs(
b) > abs(c) ?
static_cast<T
>(
deg) /
b :
static_cast<T
>(
deg) / c;
303 void operator()(std::vector<T>& poly, std::vector<std::complex<T>>& roots, std::vector<int>& conv,
int itmax)
override{
304 int deg = roots.size();
305 std::vector<T> berr(
deg);
306 std::vector<T> cond(
deg);
309 std::vector<T> alpha(
deg + 1);
310 std::complex<T>
b, c,
z;
313 for (i = 0; i <=
deg; i++)
314 alpha[i] = fabs(poly[i]);
317 std::cout <<
"Warning: leading coefficient is too small." << std::endl;
326 for (i = 0; i <=
deg; ++i)
327 alpha[i] *=
fma(
static_cast<T
>(3.8),
static_cast<T
>(i),
static_cast<T
>(1));
330 for (i = 1; i <= itmax; ++i)
331 for (
j = 0;
j <
deg; ++
j) {
348 if (*std::min_element(conv.begin(), conv.end()) == 1)
351 std::cout <<
"Some root approximations did not converge or experienced overflow/underflow.\n";
354 for (
j = 0;
j <
deg; ++
j){
360 z =
static_cast<T
>(1.0) /
z;
361 r =
static_cast<T
>(1.0) / r;
366 for (i = 1; i <
deg + 1; ++i) {
369 berr[
j] =
fma(r, berr[
j], alpha[i]);
372 cond[
j] = berr[
j] / fabs(
fms(complex<T>(
deg, 0),
b,
z, c));
373 berr[
j] = fabs(
b) / berr[
j];
378 berr[
j] = alpha[
deg];
380 for (i =
deg - 1; i >= 0; --i) {
383 berr[
j] =
fma(r, berr[
j], alpha[i]);
386 cond[
j] = berr[
j] / (r * fabs(c));
387 berr[
j] = fabs(
b) / berr[
j];
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
Definition BaseSolver.h:7
Definition Laguerre18m.h:22
void modify_lag(int deg, std::complex< T > &b, std::complex< T > &c, std::complex< T > z, int j, std::vector< std::complex< T > > &roots)
Modify Laguerre correction based on Aberth's method.
Definition Laguerre18m.h:267
static constexpr T small
Definition Laguerre18m.h:27
void operator()(std::vector< T > &poly, std::vector< std::complex< T > > &roots, std::vector< int > &conv, int itmax) override
Find the roots of a polynomial using Laguerre's method.
Definition Laguerre18m.h:303
void conv_hull(int n, std::vector< T > &a, std::vector< int > &h, int &c)
Calculate the convex hull of a set of points. Dont forget to calculate Andrews alghoritm to vector a!
Definition Laguerre18m.h:56
T cross(std::vector< int > &h, std::vector< T > &a, int c, int i)
Calculate the determinant between two points.
Definition Laguerre18m.h:41
ModifiedLaguerre18()
Definition Laguerre18m.h:292
static constexpr T big
Definition Laguerre18m.h:26
void estimates(vector< T > &alpha, int deg, std::vector< std::complex< T > > &roots, std::vector< int > &conv, int &nz)
Estimate roots of a polynomial.
Definition Laguerre18m.h:75
void check_lag(std::vector< T > &p, std::vector< T > &alpha, int deg, std::complex< T > &b, std::complex< T > &c, std::complex< T > z, T r, int &conv, T &berr, T &cond)
Perform Laguerre correction, compute backward error, and condition.
Definition Laguerre18m.h:212
static constexpr T PI
Definition Laguerre18m.h:29
void rcheck_lag(std::vector< T > &p, vector< T > &alpha, int deg, complex< T > &b, complex< T > &c, complex< T > z, T r, int &conv, T &berr, T &cond)
Perform Laguerre correction, compute backward error, and condition.
Definition Laguerre18m.h:149
static constexpr T pi2
Definition Laguerre18m.h:30
static constexpr T eps
Definition Laguerre18m.h:25
Definition ExtendedFunctions.h:14
bool complexnotfinite(complex< T > a, T big)
Check if a complex number contains NaN or Inf values.
Definition ExtendedFunctions.h:30
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
complex< number > fma(complex< number > a, complex< number > b, complex< number > c)
Fused multiply-add for complex numbers.
Definition ExtendedFunctions.h:82