1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#include <iostream>
#include <cmath>
#include <complex>
#include <cstdlib>
using namespace std;
typedef complex<double> dcomp;
// "poly" evaluates at x a polynomial of the form:
// f(x) = pow(x, n) + a1*pow(x, n - 1) + a2*pow(x, n - 2) + . . . + a(n - 2)*x*x + a(n - 1)*x + a(n)
// where the vector A = {a1, a2, a3, . . . , a(n - 2), a(n - 1), a(n)}
dcomp poly(double A[], int n, dcomp x)
{
dcomp y = pow(x, n);
for (int i = 0; i < n; i++)
y += A[i]*pow(x, (n - i - 1) );
return y;
}
// polyroot uses the Durand-Kerner method to find all roots (real and complex) of a polynomial of the form:
// f(x) = pow(x, n) + a1*pow(x, n - 1) + a2*pow(x, n - 2) + . . . + a(n - 2)*x*x + a(n - 1)*x + a(n)
// where the vector A = {a1, a2, a3, . . . , a(n - 2), a(n - 1), a(n)}
dcomp * polyroot(double A[], int n)
{
int iterations = 1000;
dcomp z = dcomp (0.4, 0.9);
int size = sizeof(z);
dcomp * R = new dcomp [size*n];
//R = (dcomp *) malloc(size*n);
for (int i = 0; i < n; i++)
R[i] = pow(z, i);
for (int i = 0; i < iterations; i++)
{
for (int j = 0; j < n; j ++)
{
dcomp B = poly(A, n, R[j]);
for (int k = 0; k < n; k++)
{
if (k != j)
B /= R[j] - R[k];
}
R[j] -= B;
}
}
return R;
}
// TEST
int main()
{
// Test the Durand-Kerner method for finding complex roots of a polynomial
double A[3] = {-3, 3, -5};
int m = 3;
dcomp * R = polyroot(A, m);
for (int i = 0; i < 3; i++)
cout << "R[" << i << "] = " << R[i] << endl;
delete R;
R = 0;
cout << "\n\n";
double B[6] = { 0, -29, -58, 54, 216, 216 };
int n = 6;
dcomp * S = polyroot(B, n);
for (int i = 0; i < 6; i++)
cout << "S[" << i << "] = " << S[i] << endl;
delete S;
S = 0;
return 0;
}
|