CbmRoot
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, Darmstadt
2 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{
10 float s = 1;
11 for (int i = n - 1; i >= 0; i--)
12 s = s * x + k[i];
13 return s;
14} //polinom
15
16float dihot(int degree, float edgeNegativ, float edgePositiv, float* kf)
17{
18 for (;;) {
19 float x = 0.5 * (edgeNegativ + edgePositiv);
20 if (std::abs(x - edgeNegativ) < 1e-3 || std::abs(x - edgePositiv) < 1e-3) return x;
21 if (polinom(degree, x, kf) < 0) edgeNegativ = x;
22 else
23 edgePositiv = x;
24 }
25} //dihot
26
27void stepUp(int level, float** A, float** B, int* currentRootsCount)
28{
29
30 float major = 0;
31 for (int i = 0; i < level; i++) {
32 float s = fabs(A[level][i]);
33 if (s > major) 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) edgeLeft = -major;
45 else
46 edgeLeft = B[level - 1][i - 1];
47
48 float rb = polinom(level, edgeLeft, A[level]);
49
50 if (rb == 0) {
51 B[level][currentRootsCount[level]] = edgeLeft;
52 currentRootsCount[level]++;
53 continue;
54 }
55
56 if (rb > 0) signLeft = 1;
57 else
58 signLeft = -1;
59
60 if (i == currentRootsCount[level - 1]) edgeRight = major;
61 else
62 edgeRight = B[level - 1][i];
63
64 rb = polinom(level, edgeRight, A[level]);
65
66 if (rb == 0) {
67 B[level][currentRootsCount[level]] = edgeRight;
68 currentRootsCount[level]++;
69 continue;
70 }
71
72 if (rb > 0) signRight = 1;
73 else
74 signRight = -1;
75 if (signLeft == signRight) continue;
76
77 if (signLeft < 0) {
78 edgeNegativ = edgeLeft;
79 edgePositiv = edgeRight;
80 }
81 else {
82 edgeNegativ = edgeRight;
83 edgePositiv = edgeLeft;
84 }
85
86 B[level][currentRootsCount[level]] = dihot(level, edgeNegativ, edgePositiv, A[level]);
87 currentRootsCount[level]++;
88 }
89 return;
90} //stepUp
91
92void polynomRealRoots(float* rootsArray, int n, float* kf_, int& rootsCount)
93{
94
95 float* kf = new float[n + 1];
96
97 float** A = new float*[n + 1];
98 float** B = new float*[n + 1];
99
100 int* currentRootsCount = new int[n + 1];
101
102 for (int i = 1; i <= n; i++) {
103 A[i] = new float[i];
104 B[i] = new float[i];
105 }
106
107 for (int i = 0; i <= n; i++)
108 kf[i] = kf_[n - i];
109
110 for (int i = 0; i < n; i++)
111 A[n][i] = kf[i] / kf[n];
112
113 for (int i1 = n, i = n - 1; i > 0; i1 = i, i--) {
114 for (int j1 = i, j = i - 1; j >= 0; j1 = j, j--) {
115 A[i][j] = A[i1][j1] * j1 / i1;
116 }
117 }
118
119 currentRootsCount[1] = 1;
120 B[1][0] = -A[1][0];
121
122 for (int i = 2; i <= n; i++)
123 stepUp(i, A, B, currentRootsCount);
124
125 rootsCount = currentRootsCount[n];
126 for (int i = 0; i < rootsCount; i++)
127 rootsArray[i] = B[n][i];
128
129 for (int i = 1; i <= n; i++) {
130 delete[] A[i];
131 delete[] B[i];
132 }
133 delete[] A;
134 delete[] B;
135 delete[] currentRootsCount;
136 delete[] kf;
137} //polynomRealRoots
138
139//*************************************************************************
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)