BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
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{
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)
21 return x;
22 if (polinom(degree, x, kf) < 0)
23 edgeNegativ = x;
24 else
25 edgePositiv = x;
26 }
27} // dihot
28
29void stepUp(int level, float** A, float** B, int* currentRootsCount)
30{
31
32 float major = 0;
33 for (int i = 0; i < level; i++) {
34 float s = fabs(A[level][i]);
35 if (s > major)
36 major = s;
37 }
38 major += 1.0;
39
40 currentRootsCount[level] = 0;
41
42 for (int i = 0; i <= currentRootsCount[level - 1]; i++) {
43 int signLeft, signRight;
44 float edgeLeft, edgeRight;
45 float edgeNegativ, edgePositiv;
46
47 if (i == 0)
48 edgeLeft = -major;
49 else
50 edgeLeft = B[level - 1][i - 1];
51
52 float rb = polinom(level, edgeLeft, A[level]);
53
54 if (rb == 0) {
55 B[level][currentRootsCount[level]] = edgeLeft;
56 currentRootsCount[level]++;
57 continue;
58 }
59
60 if (rb > 0)
61 signLeft = 1;
62 else
63 signLeft = -1;
64
65 if (i == currentRootsCount[level - 1])
66 edgeRight = major;
67 else
68 edgeRight = B[level - 1][i];
69
70 rb = polinom(level, edgeRight, A[level]);
71
72 if (rb == 0) {
73 B[level][currentRootsCount[level]] = edgeRight;
74 currentRootsCount[level]++;
75 continue;
76 }
77
78 if (rb > 0)
79 signRight = 1;
80 else
81 signRight = -1;
82 if (signLeft == signRight)
83 continue;
84
85 if (signLeft < 0) {
86 edgeNegativ = edgeLeft;
87 edgePositiv = edgeRight;
88 } else {
89 edgeNegativ = edgeRight;
90 edgePositiv = edgeLeft;
91 }
92
93 B[level][currentRootsCount[level]] = dihot(level, edgeNegativ, edgePositiv, A[level]);
94 currentRootsCount[level]++;
95 }
96 return;
97} // stepUp
98
99void polynomRealRoots(float* rootsArray, int n, float* kf_, int& rootsCount)
100{
101
102 float* kf = new float[n + 1];
103
104 float** A = new float*[n + 1];
105 float** B = new float*[n + 1];
106
107 int* currentRootsCount = new int[n + 1];
108
109 for (int i = 1; i <= n; i++) {
110 A[i] = new float[i];
111 B[i] = new float[i];
112 }
113
114 for (int i = 0; i <= n; i++)
115 kf[i] = kf_[n - i];
116
117 for (int i = 0; i < n; i++)
118 A[n][i] = kf[i] / kf[n];
119
120 for (int i1 = n, i = n - 1; i > 0; i1 = i, i--) {
121 for (int j1 = i, j = i - 1; j >= 0; j1 = j, j--) {
122 A[i][j] = A[i1][j1] * j1 / i1;
123 }
124 }
125
126 currentRootsCount[1] = 1;
127 B[1][0] = -A[1][0];
128
129 for (int i = 2; i <= n; i++)
130 stepUp(i, A, B, currentRootsCount);
131
132 rootsCount = currentRootsCount[n];
133 for (int i = 0; i < rootsCount; i++)
134 rootsArray[i] = B[n][i];
135
136 for (int i = 1; i <= n; i++) {
137 delete[] A[i];
138 delete[] B[i];
139 }
140 delete[] A;
141 delete[] B;
142 delete[] currentRootsCount;
143 delete[] kf;
144} // polynomRealRoots
145
146//*************************************************************************
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)
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:20362