BmnRoot
Loading...
Searching...
No Matches
PolynomRealRoots.h
Go to the documentation of this file.
1/* Copyright (C) 2020 Facility for Antiproton and Ion Research in Europe,
2 Darmstadt SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pierre-Alain Loizeau [committer] */
4
5#include <cmath>
6
7//*************************************************************************
8float polinom(int n, float x, float *k) {
9 float s = 1;
10 for (int i = n - 1; i >= 0; i--)
11 s = s * x + k[i];
12 return s;
13} // polinom
14
15float dihot(int degree, float edgeNegativ, float edgePositiv, float *kf) {
16 for (;;) {
17 float x = 0.5 * (edgeNegativ + edgePositiv);
18 if (std::abs(x - edgeNegativ) < 1e-3 || std::abs(x - edgePositiv) < 1e-3)
19 return x;
20 if (polinom(degree, x, kf) < 0)
21 edgeNegativ = x;
22 else
23 edgePositiv = x;
24 }
25} // dihot
26
27void stepUp(int level, float **A, float **B, int *currentRootsCount) {
28
29 float major = 0;
30 for (int i = 0; i < level; i++) {
31 float s = fabs(A[level][i]);
32 if (s > major)
33 major = s;
34 }
35 major += 1.0;
36
37 currentRootsCount[level] = 0;
38
39 for (int i = 0; i <= currentRootsCount[level - 1]; i++) {
40 int signLeft, signRight;
41 float edgeLeft, edgeRight;
42 float edgeNegativ, edgePositiv;
43
44 if (i == 0)
45 edgeLeft = -major;
46 else
47 edgeLeft = B[level - 1][i - 1];
48
49 float rb = polinom(level, edgeLeft, A[level]);
50
51 if (rb == 0) {
52 B[level][currentRootsCount[level]] = edgeLeft;
53 currentRootsCount[level]++;
54 continue;
55 }
56
57 if (rb > 0)
58 signLeft = 1;
59 else
60 signLeft = -1;
61
62 if (i == currentRootsCount[level - 1])
63 edgeRight = major;
64 else
65 edgeRight = B[level - 1][i];
66
67 rb = polinom(level, edgeRight, A[level]);
68
69 if (rb == 0) {
70 B[level][currentRootsCount[level]] = edgeRight;
71 currentRootsCount[level]++;
72 continue;
73 }
74
75 if (rb > 0)
76 signRight = 1;
77 else
78 signRight = -1;
79 if (signLeft == signRight)
80 continue;
81
82 if (signLeft < 0) {
83 edgeNegativ = edgeLeft;
84 edgePositiv = edgeRight;
85 } else {
86 edgeNegativ = edgeRight;
87 edgePositiv = edgeLeft;
88 }
89
90 B[level][currentRootsCount[level]] =
91 dihot(level, edgeNegativ, edgePositiv, A[level]);
92 currentRootsCount[level]++;
93 }
94 return;
95} // stepUp
96
97void polynomRealRoots(float *rootsArray, int n, float *kf_, int &rootsCount) {
98
99 float *kf = new float[n + 1];
100
101 float **A = new float *[n + 1];
102 float **B = new float *[n + 1];
103
104 int *currentRootsCount = new int[n + 1];
105
106 for (int i = 1; i <= n; i++) {
107 A[i] = new float[i];
108 B[i] = new float[i];
109 }
110
111 for (int i = 0; i <= n; i++)
112 kf[i] = kf_[n - i];
113
114 for (int i = 0; i < n; i++)
115 A[n][i] = kf[i] / kf[n];
116
117 for (int i1 = n, i = n - 1; i > 0; i1 = i, i--) {
118 for (int j1 = i, j = i - 1; j >= 0; j1 = j, j--) {
119 A[i][j] = A[i1][j1] * j1 / i1;
120 }
121 }
122
123 currentRootsCount[1] = 1;
124 B[1][0] = -A[1][0];
125
126 for (int i = 2; i <= n; i++)
127 stepUp(i, A, B, currentRootsCount);
128
129 rootsCount = currentRootsCount[n];
130 for (int i = 0; i < rootsCount; i++)
131 rootsArray[i] = B[n][i];
132
133 for (int i = 1; i <= n; i++) {
134 delete[] A[i];
135 delete[] B[i];
136 }
137 delete[] A;
138 delete[] B;
139 delete[] currentRootsCount;
140 delete[] kf;
141} // polynomRealRoots
142
143//*************************************************************************
friend F32vec4 fabs(const F32vec4 &a)
Definition P4_F32vec4.h:52
int i
Definition P4_F32vec4.h:22
float polinom(int n, float x, float *k)
void polynomRealRoots(float *rootsArray, int n, float *kf_, int &rootsCount)
float dihot(int degree, float edgeNegativ, float edgePositiv, float *kf)
void stepUp(int level, float **A, float **B, int *currentRootsCount)