Laguerre polynomials
Loading...
Searching...
No Matches
Laguerre13m.h
Go to the documentation of this file.
1// Александр, Дмитрий
2
3#ifndef LAGUERRE13
4#define LAGUERRE13
5
6#include <vector>
7#include <limits>
8#include <numbers>
9#include <complex>
10#include <iostream>
11#include <algorithm>
12
13#include "BaseSolver.h"
14#include "ExtendedFunctions.h"
15
16namespace Laguerre{
17using std::complex;
18using std::vector;
19
20template<typename T>
22private:
23 //
24 static constexpr T eps = std::numeric_limits<T>::epsilon();
25
26
32 inline void laguer13(const std::vector<std::complex<T>>& a, std::complex<T>& x, int& lam){
33 std::complex<T> dx, x1, b, d, f, g, h, sq, gp, gm, g2;
34 T err, abx, abp, abm;
35 int m = a.size() - 1;
36
37 b = std::complex<T>(1.0, 0.0);
38 err = std::abs(b);
39 d = f = std::complex<T>(0.0, 0.0);
40 abx = std::abs(x);
41
42 for (int j = m - 1; j >= 0; j--) {
43 f = fma(x, f, d);
44 d = fma(x, d, b);
45 b = fma(x, b, a[j]);
46 err = fma(err, abx, std::abs(b));
47 }
48
49 if (std::abs(b) <= err * eps)
50 return; // We are on the root.
51
52 g = static_cast<T>(lam)* b / d;
53 h = static_cast<T>(2)*f / d;
54 sq = std::sqrt(fma(-g, h, static_cast<T>(lam - 1)));
55 dx = g/std::abs(static_cast<T>(1) + sq);
56 x -= dx;
57 return;
58
59 }
60
61
62public:
64 //
65 }
66
74 void operator()(std::vector<T>& poly, std::vector<std::complex<T>>& roots, std::vector<int>& conv, int itmax=80) override{
75 std::complex<T> x, _b, _c;
76 int m = poly.size() - 1;
77 std::vector<std::complex<T>> ad(m + 1);
78 std::vector<std::complex<T>> ad_v;
79 int lambda;
80 int m1;
81
82 // Copy of coefficients for successive deflation.
83 for (int i = 0; i <= m; i++)
84 ad[i] = poly[i];
85
86 auto diff = Laguerre::diff(poly, 1);
87 std::vector<T> remainder;
88 Laguerre::getRemainder(poly, diff, remainder);
89
90 bool zeros = std::all_of(remainder.begin(), remainder.end(), [](int i) { return i==0; });
91 if (zeros)
92 {
93 lambda = 2*m;
94 m1 = 1;
95 }
96 else
97 {
98 std::vector<T> remainder1;
99 Laguerre::getRemainder(diff, remainder, remainder1);
100 zeros = std::all_of(remainder1.begin(), remainder1.end(), [](int i) { return i==0; });
101 if (zeros){
102 m1 = m - remainder.size() + 1;
103 lambda = 2*m/m1;
104 }
105 }
106
107 int j = m - 1;
108 for (int i = 0; i < m1; ++i){
109 x = std::complex<T>(0.0, 0.0);
110
111 // Start at zero to favor convergence to the smallest remaining root.
112 ad_v = std::vector<std::complex<T>>(ad.cbegin(), ad.cbegin() + j + 2);
113 laguer13(ad_v, x, lambda);
114 if (std::abs(imag(x)) <= std::abs(real(x)) * eps)
115 x.imag(static_cast<T>(0));
116
117 for (int k = 0; k < lambda/2; ++k){
118 roots[j] = x;
119 conv[j] = 1;
120 _b = ad[j + 1];
121 for (int jj = j; jj >= 0; jj--) {
122 _c = ad[jj];
123 ad[jj] = _b;
124 _b = fma(x, _b, _c);
125 }
126 --j;
127 }
128 }
129 }
130
131};
132
133};
134#endif
std::vector< double > err(double q, double x)
Definition Laguerre15m.h:96
p2 de j *z j
Definition Laguerre15m_or.h:23
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 Laguerre13m.h:21
void laguer13(const std::vector< std::complex< T > > &a, std::complex< T > &x, int &lam)
Laguerre's method to find a root of a polynomial.
Definition Laguerre13m.h:32
static constexpr T eps
Definition Laguerre13m.h:24
void operator()(std::vector< T > &poly, std::vector< std::complex< T > > &roots, std::vector< int > &conv, int itmax=80) override
Find the roots of a polynomial using Laguerre's method.
Definition Laguerre13m.h:74
ModifiedLaguerre13()
Definition Laguerre13m.h:63
Definition ExtendedFunctions.h:14
void getRemainder(vector< T > dividend, vector< T > divisor, vector< T > &remainder)
Divide vectors (coefficients of polynomials)
Definition ExtendedFunctions.h:194
complex< number > fma(complex< number > a, complex< number > b, complex< number > c)
Fused multiply-add for complex numbers.
Definition ExtendedFunctions.h:82
vector< T > diff(vector< T > coeffs, int deg=1)
Diff vector.
Definition ExtendedFunctions.h:143