|
7 | 7 | import sys |
8 | 8 | import math |
9 | 9 |
|
10 | | -from orbit.core.orbit_utils import Function, SplineCH, Matrix, Polynomial |
| 10 | +from orbit.core.orbit_utils import Function, SplineCH |
| 11 | +from orbit.core.orbit_utils import PhaseVector, Matrix |
| 12 | +from orbit.core.orbit_utils import Polynomial |
11 | 13 |
|
12 | 14 |
|
13 | 15 | class PolynomialFit: |
@@ -60,68 +62,42 @@ def fitSpline(self, spline): |
60 | 62 |
|
61 | 63 | def _makePolynomial(self): |
62 | 64 | nPoints = len(self.x_y_err_arr) |
63 | | - if nPoints < (self.order + 1): |
| 65 | + if(nPoints < (self.order + 1)): |
64 | 66 | self.order = nPoints - 1 |
65 | | - # check if just one of errors is zero |
66 | | - infoZeroErr = 1.0 |
67 | | - for [x, y, err] in self.x_y_err_arr: |
68 | | - infoZeroErr *= err |
69 | | - for i in range(nPoints): |
70 | | - [x, y, err] = self.x_y_err_arr[i] |
71 | | - sigma = 1.0 |
72 | | - if infoZeroErr != 0.0: |
73 | | - sigma = 1.0 / (err * err) |
74 | | - self.x_y_err_arr[i][2] = sigma |
75 | | - # now make A matrix |
76 | | - aMatr = Matrix(nPoints, self.order + 1) |
| 67 | + #---- now make A and A^T matrices and y-vector |
| 68 | + aMtr = Matrix(nPoints, self.order + 1) |
| 69 | + yVct = PhaseVector(nPoints) |
77 | 70 | for i in range(nPoints): |
| 71 | + y = self.x_y_err_arr[i][1] |
| 72 | + yVct.set(i,y) |
78 | 73 | for j in range(self.order + 1): |
79 | 74 | x = self.x_y_err_arr[i][0] |
80 | | - aMatr.set(i, j, math.pow(x, j)) |
81 | | - aTCa = Matrix(self.order + 1, self.order + 1) |
82 | | - for i in range(self.order + 1): |
83 | | - for j in range(self.order + 1): |
84 | | - a = 0.0 |
85 | | - for k in range(nPoints): |
86 | | - sigma = self.x_y_err_arr[k][2] |
87 | | - a += aMatr.get(k, i) * sigma * aMatr.get(k, j) |
88 | | - aTCa.set(i, j, a) |
| 75 | + aMtr.set(i, j, math.pow(x, j)) |
| 76 | + aMtrT = aMtr.transpose() |
89 | 77 | # now the resuting coefficients and errors |
90 | | - aTCaI = aTCa.invert() |
91 | | - if aTCaI == None: |
92 | | - print("python PolynomialFit: Problem with data.") |
93 | | - for i in range(nPoints): |
94 | | - x = self.x_y_err_arr[i][0] |
95 | | - y = self.x_y_err_arr[i][1] |
96 | | - err = self.x_y_err_arr[i][2] |
97 | | - print(" x,y,err = %12.5g %12.5g %12.5g " % (x, y, err)) |
98 | | - print("Stop.") |
99 | | - sys.exit(1) |
100 | | - e = aTCaI.mult(aTCa) |
101 | | - coef_arr = [0.0] * (self.order + 1) |
102 | | - err_arr = [0.0] * (self.order + 1) |
| 78 | + ATA_inv = (aMtrT.mult(aMtr)).invert() |
| 79 | + coeffVct = (ATA_inv.mult(aMtrT)).mult(yVct) |
| 80 | + # polinimial coefficients have been found -> coeffVct |
| 81 | + coef_arr = [0.0] * (self.order + 1) |
| 82 | + self.polynomial.order(self.order) |
103 | 83 | for i in range(self.order + 1): |
104 | | - err_arr[i] = math.sqrt(math.fabs(aTCaI.get(i, i))) |
| 84 | + coef_arr[i] = coeffVct.get(i) |
| 85 | + self.polynomial.coefficient(i,coef_arr[i]) |
| 86 | + #---- here we estimate errors by deviation y_fit from y_init only |
| 87 | + #---- It means that we do not pay attention to different weights |
| 88 | + #---- of the initial Y data errors |
| 89 | + coeff_err_arr = [0.0] * (self.order + 1) |
105 | 90 | for i in range(self.order + 1): |
106 | | - coef_arr[i] = 0.0 |
107 | | - for j in range(self.order + 1): |
108 | | - for k in range(nPoints): |
109 | | - sigma = self.x_y_err_arr[k][2] |
110 | | - y = self.x_y_err_arr[k][1] |
111 | | - coef_arr[i] += aTCaI.get(i, j) * aMatr.get(k, j) * sigma * y |
112 | | - # polinimial coefficients have been found |
113 | | - self.polynomial.order(self.order) |
114 | | - for i in range(len(coef_arr)): |
115 | | - self.polynomial.coefficient(i, coef_arr[i]) |
116 | | - # now let's calculate errors |
117 | | - if infoZeroErr == 0.0: |
118 | | - total_sigma = 0.0 |
119 | | - for k in range(nPoints): |
120 | | - x = self.x_y_err_arr[k][0] |
121 | | - y = self.x_y_err_arr[k][1] |
122 | | - total_sigma += (self.polynomial.value(x) - y) ** 2 |
123 | | - total_sigma = math.sqrt(total_sigma / (nPoints - 2)) |
124 | | - for i in range(len(err_arr)): |
125 | | - err_arr[i] *= total_sigma |
| 91 | + coeff_err_arr[i] = math.sqrt(ATA_inv.get(i,i)) |
| 92 | + total_sigma = 0.0 |
| 93 | + for k in range(nPoints): |
| 94 | + x = self.x_y_err_arr[k][0] |
| 95 | + y = self.x_y_err_arr[k][1] |
| 96 | + total_sigma += (self.polynomial.value(x) - y) ** 2 |
| 97 | + degrees_of_freedom = int(abs(nPoints - (self.order + 1))) |
| 98 | + if(degrees_of_freedom == 0): degrees_of_freedom = 1 |
| 99 | + total_sigma = math.sqrt(total_sigma / degrees_of_freedom) |
| 100 | + for i in range(self.order + 1): |
| 101 | + coeff_err_arr[i] *= total_sigma |
126 | 102 | # set the resulting coefficients and errors array |
127 | | - self.coef_err_arr = [coef_arr, err_arr] |
| 103 | + self.coef_err_arr = [coef_arr, coeff_err_arr] |
0 commit comments