1 | /*
|
---|
2 | * Class ComplexErrorProp
|
---|
3 | *
|
---|
4 | * Defines an object describing a complex number in which there are
|
---|
5 | * errors associted with real and imaginary parts aqnd includes the
|
---|
6 | * methods for propagating the error in standard arithmetic operations
|
---|
7 | * for both uncorrelated errors only.
|
---|
8 | *
|
---|
9 | * AUTHOR: Dr Michael Thomas Flanagan
|
---|
10 | *
|
---|
11 | * DATE: 27 April 2004
|
---|
12 | * UPDATE: 19 January 2005, 28 May 2007
|
---|
13 | *
|
---|
14 | * DOCUMENTATION:
|
---|
15 | * See Michael Thomas Flanagan's library on-line web pages:
|
---|
16 | * http://www.ee.ucl.ac.uk/~mflanaga/java/ComplexErrorProp.html
|
---|
17 | * http://www.ee.ucl.ac.uk/~mflanaga/java/
|
---|
18 | *
|
---|
19 | * Copyright (c) April 2004, May 2007 Michael Thomas Flanagan
|
---|
20 | *
|
---|
21 | * PERMISSION TO COPY:
|
---|
22 | * Permission to use, copy and modify this software and its documentation for
|
---|
23 | * NON-COMMERCIAL purposes is granted, without fee, provided that an acknowledgement
|
---|
24 | * to the author, Michael Thomas Flanagan at www.ucl.ee.ac.uk/~mflanaga, appears in all copies.
|
---|
25 | *
|
---|
26 | * Dr Michael Thomas Flanagan makes no representations about the suitability
|
---|
27 | * or fitness of the software for any or for a particular purpose.
|
---|
28 | * Michael Thomas Flanagan shall not be liable for any damages suffered
|
---|
29 | * as a result of using, modifying or distributing this software or its derivatives.
|
---|
30 | *
|
---|
31 | ***************************************************************************************/
|
---|
32 |
|
---|
33 | package agents.anac.y2015.agentBuyogV2.flanagan.complex;
|
---|
34 |
|
---|
35 | import agents.anac.y2015.agentBuyogV2.flanagan.analysis.*;
|
---|
36 | import agents.anac.y2015.agentBuyogV2.flanagan.math.*;
|
---|
37 |
|
---|
38 | public class ComplexErrorProp{
|
---|
39 |
|
---|
40 | private ErrorProp eReal = new ErrorProp(); // Real part of a complex number
|
---|
41 | private ErrorProp eImag = new ErrorProp(); // Imaginary part of a complex number
|
---|
42 | private double corrCoeff = 0.0D; // correlation coefficient between real and imaginary parts
|
---|
43 | private static int monteCarloLength = 10000;// length of Monte Carlo simulation arrays
|
---|
44 |
|
---|
45 | /*********************************************************/
|
---|
46 |
|
---|
47 | // CONSTRUCTORS
|
---|
48 | // default constructor - value and error of real and imag = zero
|
---|
49 | // no correlation between real and imaginary parts
|
---|
50 | public ComplexErrorProp()
|
---|
51 | {
|
---|
52 | this.eReal.reset(0.0D, 0.0D);
|
---|
53 | this.eImag.reset(0.0D, 0.0D);
|
---|
54 | this.corrCoeff = 0.0D;
|
---|
55 | }
|
---|
56 |
|
---|
57 | // constructor - initialises both real and imag with ErrorProp - no correlation between real and imaginary parts
|
---|
58 | public ComplexErrorProp(ErrorProp eReal, ErrorProp eImag)
|
---|
59 | {
|
---|
60 | this.eReal = eReal.copy();
|
---|
61 | this.eImag = eImag.copy();
|
---|
62 | this.corrCoeff = 0.0D;
|
---|
63 | }
|
---|
64 | // constructor - initialises both real and imag with ErrorProp with correlation between real and imaginary parts
|
---|
65 | public ComplexErrorProp(ErrorProp eReal, ErrorProp eImag, double corrCoeff)
|
---|
66 | {
|
---|
67 | this.eReal = eReal.copy();
|
---|
68 | this.eImag = eImag.copy();
|
---|
69 | this.corrCoeff = corrCoeff;
|
---|
70 | }
|
---|
71 |
|
---|
72 | // constructor - initialises both real and imag with doubles - no correlation between real and imaginary parts
|
---|
73 | public ComplexErrorProp(double eRealValue, double eRealError, double eImagValue, double eImagError)
|
---|
74 | {
|
---|
75 | this.eReal.reset(eRealValue, eRealError);
|
---|
76 | this.eImag.reset(eImagValue, eImagError);
|
---|
77 | this.corrCoeff = 0.0D;
|
---|
78 | }
|
---|
79 |
|
---|
80 | // constructor - initialises both real and imag with doubles with correlation between real and imaginary parts
|
---|
81 | public ComplexErrorProp(double eRealValue, double eRealError, double eImagValue, double eImagError, double corrCoeff)
|
---|
82 | {
|
---|
83 | this.eReal.reset(eRealValue, eRealError);
|
---|
84 | this.eImag.reset(eImagValue, eImagError);
|
---|
85 | this.corrCoeff = corrCoeff;
|
---|
86 | }
|
---|
87 |
|
---|
88 | /*********************************************************/
|
---|
89 |
|
---|
90 | // PUBLIC METHODS
|
---|
91 |
|
---|
92 | // SET VALUES
|
---|
93 | // Set the values of real and imag - no correlation between real and imaginary
|
---|
94 | public void reset(ErrorProp eReal, ErrorProp eImag){
|
---|
95 | this.eReal = eReal.copy();
|
---|
96 | this.eImag = eImag.copy();
|
---|
97 | this.corrCoeff = 0.0D;
|
---|
98 | }
|
---|
99 |
|
---|
100 | // Set the values of real and imag with correlation between real and imaginary
|
---|
101 | public void reset(ErrorProp eReal, ErrorProp eImag, double corrCoeff){
|
---|
102 | this.eReal = eReal.copy();
|
---|
103 | this.eImag = eImag.copy();
|
---|
104 | this.corrCoeff = corrCoeff;
|
---|
105 | }
|
---|
106 |
|
---|
107 | // Set the values of real and imag - no correlation between real and imaginary
|
---|
108 | public void reset(double eRealValue, double eRealError, double eImagValue, double eImagError){
|
---|
109 | this.eReal.setValue(eRealValue);
|
---|
110 | this.eReal.setError(eRealError);
|
---|
111 | this.eImag.setValue(eImagValue);
|
---|
112 | this.eImag.setError(eImagError);
|
---|
113 | this.corrCoeff = 0.0D;
|
---|
114 | }
|
---|
115 |
|
---|
116 |
|
---|
117 | // Set the values of real and imag with correlation between real and imaginary
|
---|
118 | public void reset(double eRealValue, double eRealError, double eImagValue, double eImagError, double corrCoeff){
|
---|
119 | this.eReal.setValue(eRealValue);
|
---|
120 | this.eReal.setError(eRealError);
|
---|
121 | this.eImag.setValue(eImagValue);
|
---|
122 | this.eImag.setError(eImagError);
|
---|
123 | this.corrCoeff = corrCoeff;
|
---|
124 | }
|
---|
125 |
|
---|
126 | // Set the values of magnitude and phase - no correlation between real and imaginary parts
|
---|
127 | public void polar(ErrorProp eMag, ErrorProp ePhase){
|
---|
128 | polar(eMag, ePhase, 0.0D);
|
---|
129 | }
|
---|
130 |
|
---|
131 | // Set the values of magnitude and phase with correlation between real and imaginary parts
|
---|
132 | public void polar(ErrorProp eMag, ErrorProp ePhase, double corrCoeff)
|
---|
133 | {
|
---|
134 | // calculate values and errors
|
---|
135 | ErrorProp a = new ErrorProp();
|
---|
136 | a = eMag.times(ErrorProp.cos(ePhase), corrCoeff);
|
---|
137 | this.eReal = a;
|
---|
138 | a = eMag.times(ErrorProp.sin(ePhase), corrCoeff);
|
---|
139 | this.eImag = a;
|
---|
140 |
|
---|
141 | // calculate the new correlation coefficient
|
---|
142 | PsRandom rr = new PsRandom();
|
---|
143 | double[][] ran = rr.correlatedGaussianArrays(eMag.getValue(), ePhase.getValue(), eMag.getError(), ePhase.getError(), corrCoeff, monteCarloLength);
|
---|
144 |
|
---|
145 | double[] rV = new double[monteCarloLength];
|
---|
146 | double[] iV = new double[monteCarloLength];
|
---|
147 | for(int i=0; i<monteCarloLength; i++){
|
---|
148 | rV[i] = ran[0][i]*Math.cos(ran[1][i]);
|
---|
149 | iV[i] = ran[0][i]*Math.sin(ran[1][i]);
|
---|
150 | }
|
---|
151 |
|
---|
152 | this.corrCoeff = calcRho(rV, iV);
|
---|
153 | }
|
---|
154 |
|
---|
155 | /// calculates the correlation coefficient between x and y
|
---|
156 | public static double calcRho(double[] x, double[] y){
|
---|
157 | int n = x.length;
|
---|
158 | if(n!=y.length)throw new IllegalArgumentException("length of x and y must be the same");
|
---|
159 |
|
---|
160 | double meanX = 0.0D;
|
---|
161 | double meanY = 0.0D;
|
---|
162 | for(int i=0; i<n; i++){
|
---|
163 | meanX += x[i];
|
---|
164 | meanY += y[i];
|
---|
165 | }
|
---|
166 | meanX /= n;
|
---|
167 | meanY /= n;
|
---|
168 | double varX = 0.0D;
|
---|
169 | double varY = 0.0D;
|
---|
170 | double covarXY = 0.0D;
|
---|
171 | for(int i=0; i<n; i++){
|
---|
172 | varX+= Fmath.square(x[i]-meanX);
|
---|
173 | varY += Fmath.square(y[i]-meanY);
|
---|
174 | covarXY += (x[i]-meanX)*(y[i]-meanY);
|
---|
175 | }
|
---|
176 | varX = Math.sqrt(varX/(n-1));
|
---|
177 | varY = Math.sqrt(varY/(n-1));
|
---|
178 | covarXY = covarXY/(n-1);
|
---|
179 |
|
---|
180 | return covarXY/(varX*varY);
|
---|
181 | }
|
---|
182 |
|
---|
183 | // Set the values of magnitude and phase - no correlation between real and imaginary parts
|
---|
184 | public void polar(double eMagValue, double eMagError, double ePhaseValue, double ePhaseError){
|
---|
185 | ErrorProp eMag = new ErrorProp(eMagValue, eMagError);
|
---|
186 | ErrorProp ePhase = new ErrorProp(ePhaseValue, ePhaseError);
|
---|
187 | polar(eMag, ePhase, 0.0D);
|
---|
188 | }
|
---|
189 |
|
---|
190 | // Set the values of magnitude and phase with correlation between real and imaginary parts
|
---|
191 | public void polar(double eMagValue, double eMagError, double ePhaseValue, double ePhaseError, double corrCoeff){
|
---|
192 | ErrorProp eMag = new ErrorProp(eMagValue, eMagError);
|
---|
193 | ErrorProp ePhase = new ErrorProp(ePhaseValue, ePhaseError);
|
---|
194 | polar(eMag, ePhase, corrCoeff);
|
---|
195 | }
|
---|
196 |
|
---|
197 | // Set the value of real
|
---|
198 | public void setReal(ErrorProp eReal){
|
---|
199 | this.eReal = eReal.copy();
|
---|
200 | }
|
---|
201 |
|
---|
202 | // Set the value of real
|
---|
203 | public void setReal(double eRealValue, double eRealError){
|
---|
204 | this.eReal.setValue(eRealValue);
|
---|
205 | this.eReal.setError(eRealError);
|
---|
206 | }
|
---|
207 |
|
---|
208 | // Set the value of imag
|
---|
209 | public void setImag(ErrorProp eImag){
|
---|
210 | this.eImag = eImag.copy();
|
---|
211 | }
|
---|
212 |
|
---|
213 | // Set the value of imag
|
---|
214 | public void setImag(double eImagValue, double eImagError){
|
---|
215 | this.eImag.setValue(eImagValue);
|
---|
216 | this.eImag.setError(eImagError);
|
---|
217 | }
|
---|
218 |
|
---|
219 | // Set the values of an error free double as ComplexErrorProp
|
---|
220 | public void setDouble(double errorFree){
|
---|
221 | this.eReal.reset(errorFree, 0.0D);
|
---|
222 | this.eImag.reset(0.0D, 0.0D);
|
---|
223 | }
|
---|
224 |
|
---|
225 | // Set the value of the correlation coefficient between the real and imaginary parts
|
---|
226 | public void setCorrCoeff(double corrCoeff){
|
---|
227 | this.corrCoeff = corrCoeff;
|
---|
228 | }
|
---|
229 |
|
---|
230 | // set value of the Monte Carlo simulation array length
|
---|
231 | public static void setMonteCarloLength(int length){
|
---|
232 | ComplexErrorProp.monteCarloLength = length;
|
---|
233 | }
|
---|
234 |
|
---|
235 |
|
---|
236 | // GET VALUES
|
---|
237 | // Get the real part
|
---|
238 | public ErrorProp getReal(){
|
---|
239 | return eReal.copy();
|
---|
240 | }
|
---|
241 |
|
---|
242 | // Get the value of real
|
---|
243 | public double getRealValue(){
|
---|
244 | return eReal.getValue();
|
---|
245 | }
|
---|
246 |
|
---|
247 | // Get the error of real
|
---|
248 | public double getRealError(){
|
---|
249 | return eReal.getError();
|
---|
250 | }
|
---|
251 |
|
---|
252 | // Get the imag part
|
---|
253 | public ErrorProp getImag(){
|
---|
254 | return eImag.copy();
|
---|
255 | }
|
---|
256 |
|
---|
257 | // Get the value of imag
|
---|
258 | public double getImagValue(){
|
---|
259 | return eImag.getValue();
|
---|
260 | }
|
---|
261 |
|
---|
262 | // Get the error of eImag
|
---|
263 | public double getImagError(){
|
---|
264 | return eImag.getError();
|
---|
265 | }
|
---|
266 |
|
---|
267 | // Get the correlation coefficient
|
---|
268 | public double getCorrCoeff(){
|
---|
269 | return this.corrCoeff;
|
---|
270 | }
|
---|
271 |
|
---|
272 | // Get value of the Monte Carlo simulation array length
|
---|
273 | public static int getMonteCarloLength(){
|
---|
274 | return ComplexErrorProp.monteCarloLength;
|
---|
275 | }
|
---|
276 |
|
---|
277 | // COPY
|
---|
278 | // Copy a single complex error prop number [static method]
|
---|
279 | public static ComplexErrorProp copy(ComplexErrorProp a){
|
---|
280 | if(a==null){
|
---|
281 | return null;
|
---|
282 | }
|
---|
283 | else{
|
---|
284 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
285 | b.eReal=a.eReal.copy();
|
---|
286 | b.eImag=a.eImag.copy();
|
---|
287 | return b;
|
---|
288 | }
|
---|
289 | }
|
---|
290 |
|
---|
291 | // Copy a single complex error prop number [instance method]
|
---|
292 | public ComplexErrorProp copy(){
|
---|
293 | if(this==null){
|
---|
294 | return null;
|
---|
295 | }
|
---|
296 | else{
|
---|
297 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
298 | b.eReal=this.eReal.copy();
|
---|
299 | b.eImag=this.eImag.copy();
|
---|
300 | return b;
|
---|
301 | }
|
---|
302 | }
|
---|
303 |
|
---|
304 | //CLONE
|
---|
305 | // Clone a single complex error prop number
|
---|
306 | public Object clone(){
|
---|
307 | if(this==null){
|
---|
308 | return null;
|
---|
309 | }
|
---|
310 | else{
|
---|
311 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
312 | b.eReal=this.eReal.copy();
|
---|
313 | b.eImag=this.eImag.copy();
|
---|
314 | return (Object) b;
|
---|
315 | }
|
---|
316 | }
|
---|
317 |
|
---|
318 | // ADDITION
|
---|
319 | // Add two ComplexErrorProp numbers [static method]
|
---|
320 | public static ComplexErrorProp plus(ComplexErrorProp a, ComplexErrorProp b){
|
---|
321 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
322 | c.eReal=a.eReal.plus(b.eReal);
|
---|
323 | c.eImag=a.eImag.plus(b.eImag);
|
---|
324 | return c;
|
---|
325 | }
|
---|
326 |
|
---|
327 | //Add a ComplexErrorProp number to this ComplexErrorProp number [instance method]
|
---|
328 | // this ComplexErrorProp number remains unaltered
|
---|
329 | public ComplexErrorProp plus(ComplexErrorProp a){
|
---|
330 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
331 | b.eReal=this.eReal.plus(a.eReal);
|
---|
332 | b.eImag=this.eImag.plus(a.eImag);
|
---|
333 | return b;
|
---|
334 | }
|
---|
335 |
|
---|
336 | // SUBTRACTION
|
---|
337 | //Subtract two ComplexErrorProp numbers [static method]
|
---|
338 | public static ComplexErrorProp minus (ComplexErrorProp a, ComplexErrorProp b){
|
---|
339 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
340 | c.eReal=a.eReal.minus(b.eReal);
|
---|
341 | c.eImag=a.eImag.minus(b.eImag);
|
---|
342 | return c;
|
---|
343 | }
|
---|
344 |
|
---|
345 | //Subtract a ComplexErrorProp number from this ComplexErrorProp number [instance method]
|
---|
346 | // this ComplexErrorProp number remains unaltered
|
---|
347 | public ComplexErrorProp minus(ComplexErrorProp a){
|
---|
348 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
349 | b.eReal=this.eReal.minus(a.eReal);
|
---|
350 | b.eImag=this.eImag.minus(a.eImag);
|
---|
351 | return b;
|
---|
352 | }
|
---|
353 |
|
---|
354 | // MULTIPLICATION
|
---|
355 | //Multiply two ComplexErrorProp numbers [static method]
|
---|
356 | public static ComplexErrorProp times(ComplexErrorProp a, ComplexErrorProp b){
|
---|
357 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
358 | c.eReal=a.eReal.times(b.eReal).minus(a.eImag.times(b.eImag));
|
---|
359 | c.eImag=a.eReal.times(b.eImag).plus(a.eImag.times(b.eReal));
|
---|
360 | return c;
|
---|
361 | }
|
---|
362 |
|
---|
363 | //Multiply two ComplexErrorProp numbers [instance method]
|
---|
364 | public ComplexErrorProp times(ComplexErrorProp b){
|
---|
365 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
366 | c.eReal=this.eReal.times(b.eReal).minus(this.eImag.times(b.eImag));
|
---|
367 | c.eImag=this.eReal.times(b.eImag).plus(this.eImag.times(b.eReal));
|
---|
368 | return c;
|
---|
369 | }
|
---|
370 |
|
---|
371 | //Multiply this ComplexErrorProp number by a ComplexErrorProp number and replace this by the product
|
---|
372 | public void timesEquals(ComplexErrorProp a){
|
---|
373 | ComplexErrorProp b = new ComplexErrorProp();
|
---|
374 | b.eReal=a.eReal.times(this.eReal).minus(a.eImag.times(this.eImag));
|
---|
375 | b.eImag=a.eReal.times(this.eImag).plus(a.eImag.times(this.eReal));
|
---|
376 | this.eReal=b.eReal.copy();
|
---|
377 | this.eImag=b.eImag.copy();
|
---|
378 | }
|
---|
379 |
|
---|
380 |
|
---|
381 | // DIVISION
|
---|
382 | //Division of two ComplexErrorProp numbers a/b [static method]
|
---|
383 | public static ComplexErrorProp over(ComplexErrorProp a, ComplexErrorProp b){
|
---|
384 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
385 | PsRandom ran = new PsRandom();
|
---|
386 | double[] aReal = ran.gaussianArray(a.eReal.getValue(), a.eReal.getError(), ComplexErrorProp.monteCarloLength);
|
---|
387 | double[] aImag = ran.gaussianArray(a.eImag.getValue(), a.eImag.getError(), ComplexErrorProp.monteCarloLength);
|
---|
388 | double[] bReal = ran.gaussianArray(b.eReal.getValue(), b.eReal.getError(), ComplexErrorProp.monteCarloLength);
|
---|
389 | double[] bImag = ran.gaussianArray(b.eImag.getValue(), b.eImag.getError(), ComplexErrorProp.monteCarloLength);
|
---|
390 | double[] rat = new double[ComplexErrorProp.monteCarloLength];
|
---|
391 | double[] denm = new double[ComplexErrorProp.monteCarloLength];
|
---|
392 | double[] cReal = new double[ComplexErrorProp.monteCarloLength];
|
---|
393 | double[] cImag = new double[ComplexErrorProp.monteCarloLength];
|
---|
394 |
|
---|
395 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
396 |
|
---|
397 | if(Math.abs(bReal[i])>=Math.abs(bImag[i])){
|
---|
398 | rat[i] = bImag[i]/bReal[i];
|
---|
399 | denm[i] = bReal[i] + bImag[i]*rat[i];
|
---|
400 | cReal[i] = (aReal[i] + aImag[i]*rat[i])/denm[i];
|
---|
401 | cImag[i] = (aImag[i] - aReal[i]*rat[i])/denm[i];
|
---|
402 | }
|
---|
403 | else{
|
---|
404 | rat[i] = bReal[i]/bImag[i];
|
---|
405 | denm[i] = bReal[i]*rat[i] + bImag[i];
|
---|
406 | cReal[i] = (aReal[i]*rat[i] + aImag[i])/denm[i];
|
---|
407 | cImag[i] = (aImag[i]*rat[i] - aReal[i])/denm[i];
|
---|
408 | }
|
---|
409 | }
|
---|
410 | double cRealSum = 0.0D;
|
---|
411 | double cImagSum = 0.0D;
|
---|
412 | double cRealErrorSum = 0.0D;
|
---|
413 | double cImagErrorSum = 0.0D;
|
---|
414 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
415 | cRealSum += cReal[i];
|
---|
416 | cImagSum += cImag[i];
|
---|
417 | }
|
---|
418 | cRealSum /= ComplexErrorProp.monteCarloLength;
|
---|
419 | cImagSum /= ComplexErrorProp.monteCarloLength;
|
---|
420 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
421 | cRealErrorSum += Fmath.square(cRealSum - cReal[i]);
|
---|
422 | cImagErrorSum += Fmath.square(cImagSum - cImag[i]);
|
---|
423 | }
|
---|
424 | cRealErrorSum = Math.sqrt(cRealErrorSum/(ComplexErrorProp.monteCarloLength-1));
|
---|
425 | cImagErrorSum = Math.sqrt(cImagErrorSum/(ComplexErrorProp.monteCarloLength-1));
|
---|
426 | c.eReal.setError(cRealErrorSum);
|
---|
427 | c.eImag.setError(cImagErrorSum);
|
---|
428 |
|
---|
429 | double denom = 0.0D;
|
---|
430 | double ratio = 0.0D;
|
---|
431 | if(Math.abs(b.eReal.getValue())>=Math.abs(b.eImag.getValue())){
|
---|
432 | ratio=b.eImag.getValue()/b.eReal.getValue();
|
---|
433 | denom=b.eReal.getValue()+b.eImag.getValue()*ratio;
|
---|
434 | c.eReal.setValue((a.eReal.getValue()+a.eImag.getValue()*ratio)/denom);
|
---|
435 | c.eImag.setValue((a.eImag.getValue()-a.eReal.getValue()*ratio)/denom);
|
---|
436 | }
|
---|
437 | else{
|
---|
438 | ratio=b.eReal.getValue()/b.eImag.getValue();
|
---|
439 | denom=b.eReal.getValue()*ratio+b.eImag.getValue();
|
---|
440 | c.eReal.setValue((a.eReal.getValue()*ratio+a.eImag.getValue())/denom);
|
---|
441 | c.eImag.setValue((a.eImag.getValue()*ratio-a.eReal.getValue())/denom);
|
---|
442 | }
|
---|
443 | return c;
|
---|
444 | }
|
---|
445 | //Division of this ComplexErrorProp number by a ComplexErrorProp number [instance method]
|
---|
446 | // this ComplexErrorProp number remains unaltered
|
---|
447 | public ComplexErrorProp over(ComplexErrorProp b){
|
---|
448 | ComplexErrorProp c = new ComplexErrorProp();
|
---|
449 | PsRandom ran = new PsRandom();
|
---|
450 | double[] aReal = ran.gaussianArray(this.eReal.getValue(), this.eReal.getError(), ComplexErrorProp.monteCarloLength);
|
---|
451 | double[] aImag = ran.gaussianArray(this.eImag.getValue(), this.eImag.getError(), ComplexErrorProp.monteCarloLength);
|
---|
452 | double[] bReal = ran.gaussianArray(b.eReal.getValue(), b.eReal.getError(), ComplexErrorProp.monteCarloLength);
|
---|
453 | double[] bImag = ran.gaussianArray(b.eImag.getValue(), b.eImag.getError(), ComplexErrorProp.monteCarloLength);
|
---|
454 | double[] rat = new double[ComplexErrorProp.monteCarloLength];
|
---|
455 | double[] denm = new double[ComplexErrorProp.monteCarloLength];
|
---|
456 | double[] cReal = new double[ComplexErrorProp.monteCarloLength];
|
---|
457 | double[] cImag = new double[ComplexErrorProp.monteCarloLength];
|
---|
458 |
|
---|
459 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
460 |
|
---|
461 | if(Math.abs(bReal[i])>=Math.abs(bImag[i])){
|
---|
462 | rat[i] = bImag[i]/bReal[i];
|
---|
463 | denm[i] = bReal[i] + bImag[i]*rat[i];
|
---|
464 | cReal[i] = (aReal[i] + aImag[i]*rat[i])/denm[i];
|
---|
465 | cImag[i] = (aImag[i] - aReal[i]*rat[i])/denm[i];
|
---|
466 | }
|
---|
467 | else{
|
---|
468 | rat[i] = bReal[i]/bImag[i];
|
---|
469 | denm[i] = bReal[i]*rat[i] + bImag[i];
|
---|
470 | cReal[i] = (aReal[i]*rat[i] + aImag[i])/denm[i];
|
---|
471 | cImag[i] = (aImag[i]*rat[i] - aReal[i])/denm[i];
|
---|
472 | }
|
---|
473 | }
|
---|
474 | double cRealSum = 0.0D;
|
---|
475 | double cImagSum = 0.0D;
|
---|
476 | double cRealErrorSum = 0.0D;
|
---|
477 | double cImagErrorSum = 0.0D;
|
---|
478 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
479 | cRealSum += cReal[i];
|
---|
480 | cImagSum += cImag[i];
|
---|
481 | }
|
---|
482 | cRealSum /= ComplexErrorProp.monteCarloLength;
|
---|
483 | cImagSum /= ComplexErrorProp.monteCarloLength;
|
---|
484 | for(int i=0; i<ComplexErrorProp.monteCarloLength; i++){
|
---|
485 | cRealErrorSum += Fmath.square(cRealSum - cReal[i]);
|
---|
486 | cImagErrorSum += Fmath.square(cImagSum - cImag[i]);
|
---|
487 | }
|
---|
488 | cRealErrorSum = Math.sqrt(cRealErrorSum/(ComplexErrorProp.monteCarloLength-1));
|
---|
489 | cImagErrorSum = Math.sqrt(cImagErrorSum/(ComplexErrorProp.monteCarloLength-1));
|
---|
490 | c.eReal.setError(cRealErrorSum);
|
---|
491 | c.eImag.setError(cImagErrorSum);
|
---|
492 |
|
---|
493 | double denom = 0.0D;
|
---|
494 | double ratio = 0.0D;
|
---|
495 | if(Math.abs(b.eReal.getValue())>=Math.abs(b.eImag.getValue())){
|
---|
496 | ratio=b.eImag.getValue()/b.eReal.getValue();
|
---|
497 | denom=b.eReal.getValue()+b.eImag.getValue()*ratio;
|
---|
498 | c.eReal.setValue((this.eReal.getValue()+this.eImag.getValue()*ratio)/denom);
|
---|
499 | c.eImag.setValue((this.eImag.getValue()-this.eReal.getValue()*ratio)/denom);
|
---|
500 | }
|
---|
501 | else{
|
---|
502 | ratio=b.eReal.getValue()/b.eImag.getValue();
|
---|
503 | denom=b.eReal.getValue()*ratio+b.eImag.getValue();
|
---|
504 | c.eReal.setValue((this.eReal.getValue()*ratio+this.eImag.getValue())/denom);
|
---|
505 | c.eImag.setValue((this.eImag.getValue()*ratio-this.eReal.getValue())/denom);
|
---|
506 | }
|
---|
507 | return c;
|
---|
508 | }
|
---|
509 |
|
---|
510 | //Exponential [static method]
|
---|
511 | public static ComplexErrorProp exp(ComplexErrorProp aa){
|
---|
512 | ComplexErrorProp bb = new ComplexErrorProp();
|
---|
513 | ErrorProp pre = ErrorProp.exp(aa.eReal);
|
---|
514 | bb.eReal = pre.times(ErrorProp.cos(aa.eImag),aa.corrCoeff);
|
---|
515 | bb.eImag = pre.times(ErrorProp.sin(aa.eImag),aa.corrCoeff);
|
---|
516 | return bb;
|
---|
517 | }
|
---|
518 |
|
---|
519 | //Exponential [instance method]
|
---|
520 | public ComplexErrorProp exp(){
|
---|
521 | ComplexErrorProp bb = new ComplexErrorProp();
|
---|
522 | ErrorProp pre = ErrorProp.exp(this.eReal);
|
---|
523 | bb.eReal = pre.times(ErrorProp.cos(this.eImag),this.corrCoeff);
|
---|
524 | bb.eImag = pre.times(ErrorProp.sin(this.eImag),this.corrCoeff);
|
---|
525 | return bb;
|
---|
526 |
|
---|
527 | }
|
---|
528 |
|
---|
529 | //Absolute value (modulus) [static method]
|
---|
530 | public static ErrorProp abs(ComplexErrorProp aa){
|
---|
531 | ErrorProp bb = new ErrorProp();
|
---|
532 | double realV = aa.eReal.getValue();
|
---|
533 | double imagV = aa.eImag.getValue();
|
---|
534 |
|
---|
535 | double rmod = Math.abs(realV);
|
---|
536 | double imod = Math.abs(imagV);
|
---|
537 | double ratio = 0.0D;
|
---|
538 | double res = 0.0D;
|
---|
539 |
|
---|
540 | if(rmod==0.0){
|
---|
541 | res=imod;
|
---|
542 | }
|
---|
543 | else{
|
---|
544 | if(imod==0.0){
|
---|
545 | res=rmod;
|
---|
546 | }
|
---|
547 | if(rmod>=imod){
|
---|
548 | ratio=imagV/realV;
|
---|
549 | res=rmod*Math.sqrt(1.0 + ratio*ratio);
|
---|
550 | }
|
---|
551 | else
|
---|
552 | {
|
---|
553 | ratio=realV/imagV;
|
---|
554 | res=imod*Math.sqrt(1.0 + ratio*ratio);
|
---|
555 | }
|
---|
556 | }
|
---|
557 | bb.setValue(res);
|
---|
558 |
|
---|
559 | double realE = aa.eReal.getError();
|
---|
560 | double imagE = aa.eImag.getError();
|
---|
561 | res = hypotWithRho(2.0D*realE*realV, 2.0D*imagE*imagV, aa.corrCoeff);
|
---|
562 | bb.setError(res);
|
---|
563 |
|
---|
564 | return bb;
|
---|
565 | }
|
---|
566 |
|
---|
567 | //Absolute value (modulus) [instance method]
|
---|
568 | public ErrorProp abs(){
|
---|
569 | ErrorProp aa = new ErrorProp();
|
---|
570 | double realV = this.eReal.getValue();
|
---|
571 | double imagV = this.eImag.getValue();
|
---|
572 |
|
---|
573 | double rmod = Math.abs(realV);
|
---|
574 | double imod = Math.abs(imagV);
|
---|
575 | double ratio = 0.0D;
|
---|
576 | double res = 0.0D;
|
---|
577 |
|
---|
578 | if(rmod==0.0){
|
---|
579 | res=imod;
|
---|
580 | }
|
---|
581 | else{
|
---|
582 | if(imod==0.0){
|
---|
583 | res=rmod;
|
---|
584 | }
|
---|
585 | if(rmod>=imod){
|
---|
586 | ratio=imagV/realV;
|
---|
587 | res=rmod*Math.sqrt(1.0 + ratio*ratio);
|
---|
588 | }
|
---|
589 | else
|
---|
590 | {
|
---|
591 | ratio=realV/imagV;
|
---|
592 | res=imod*Math.sqrt(1.0 + ratio*ratio);
|
---|
593 | }
|
---|
594 | }
|
---|
595 | aa.setValue(res);
|
---|
596 |
|
---|
597 | double realE = this.eReal.getError();
|
---|
598 | double imagE = this.eImag.getError();
|
---|
599 | res = hypotWithRho(2.0D*realE*realV, 2.0D*imagE*imagV, this.corrCoeff);
|
---|
600 | aa.setError(res);
|
---|
601 |
|
---|
602 | return aa;
|
---|
603 | }
|
---|
604 |
|
---|
605 | //Argument of a ComplexErrorProp [static method]
|
---|
606 | public static ErrorProp arg(ComplexErrorProp a){
|
---|
607 | ErrorProp b = new ErrorProp();
|
---|
608 | b = ErrorProp.atan2(a.eReal, a.eImag, a.corrCoeff);
|
---|
609 | return b;
|
---|
610 | }
|
---|
611 |
|
---|
612 | //Argument of a ComplexErrorProp [instance method]
|
---|
613 | public ErrorProp arg(double rho){
|
---|
614 | ErrorProp a = new ErrorProp();
|
---|
615 | a = ErrorProp.atan2(this.eReal, this.eImag, this.corrCoeff);
|
---|
616 | return a;
|
---|
617 | }
|
---|
618 |
|
---|
619 | // Returns sqrt(a*a+b*b + 2*a*b*rho) [without unecessary overflow or underflow]
|
---|
620 | public static double hypotWithRho(double aa, double bb, double rho){
|
---|
621 | double amod=Math.abs(aa);
|
---|
622 | double bmod=Math.abs(bb);
|
---|
623 | double cc = 0.0D, ratio = 0.0D;
|
---|
624 | if(amod==0.0){
|
---|
625 | cc=bmod;
|
---|
626 | }
|
---|
627 | else{
|
---|
628 | if(bmod==0.0){
|
---|
629 | cc=amod;
|
---|
630 | }
|
---|
631 | else{
|
---|
632 | if(amod>=bmod){
|
---|
633 | ratio=bmod/amod;
|
---|
634 | cc=amod*Math.sqrt(1.0 + ratio*ratio + 2.0*rho*ratio);
|
---|
635 | }
|
---|
636 | else{
|
---|
637 | ratio=amod/bmod;
|
---|
638 | cc=bmod*Math.sqrt(1.0 + ratio*ratio + 2.0*rho*ratio);
|
---|
639 | }
|
---|
640 | }
|
---|
641 | }
|
---|
642 | return cc;
|
---|
643 | }
|
---|
644 |
|
---|
645 | // TRUNCATION
|
---|
646 | // Rounds the mantissae of both the value and error parts of Errorprop to prec places
|
---|
647 | public static ComplexErrorProp truncate(ComplexErrorProp x, int prec){
|
---|
648 | if(prec<0)return x;
|
---|
649 |
|
---|
650 | double rV = x.eReal.getValue();
|
---|
651 | double rE = x.eReal.getError();
|
---|
652 | double iV = x.eImag.getValue();
|
---|
653 | double iE = x.eImag.getError();
|
---|
654 | ComplexErrorProp y = new ComplexErrorProp();
|
---|
655 |
|
---|
656 | rV = Fmath.truncate(rV, prec);
|
---|
657 | rE = Fmath.truncate(rE, prec);
|
---|
658 | iV = Fmath.truncate(iV, prec);
|
---|
659 | iE = Fmath.truncate(iE, prec);
|
---|
660 |
|
---|
661 | y.reset(rV, rE, iV, iE);
|
---|
662 | return y;
|
---|
663 | }
|
---|
664 |
|
---|
665 | // instance method
|
---|
666 | public ComplexErrorProp truncate(int prec){
|
---|
667 | if(prec<0)return this;
|
---|
668 |
|
---|
669 | double rV = this.eReal.getValue();
|
---|
670 | double rE = this.eReal.getError();
|
---|
671 | double iV = this.eImag.getValue();
|
---|
672 | double iE = this.eImag.getError();
|
---|
673 |
|
---|
674 | ComplexErrorProp y = new ComplexErrorProp();
|
---|
675 |
|
---|
676 | rV = Fmath.truncate(rV, prec);
|
---|
677 | rE = Fmath.truncate(rE, prec);
|
---|
678 | iV = Fmath.truncate(iV, prec);
|
---|
679 | iE = Fmath.truncate(iE, prec);
|
---|
680 |
|
---|
681 | y.reset(rV, rE, iV, iE);
|
---|
682 | return y;
|
---|
683 | }
|
---|
684 |
|
---|
685 | // CONVERSIONS
|
---|
686 | // Format a ComplexErrorProp number as a string
|
---|
687 | // Overides java.lang.String.toString()
|
---|
688 | public String toString(){
|
---|
689 | return "Real part: " + this.eReal.getValue() + ", error = " + this.eReal.getError() + "; Imaginary part: " + this.eImag.getValue() + ", error = " + this.eImag.getError();
|
---|
690 | }
|
---|
691 |
|
---|
692 | // Format a ComplexErrorProp number as a string
|
---|
693 | // See static method above for comments
|
---|
694 | public static String toString(ComplexErrorProp aa){
|
---|
695 | return "Real part: " + aa.eReal.getValue() + ", error = " + aa.eReal.getError() + "; Imaginary part: " + aa.eImag.getValue() + ", error = " + aa.eImag.getError();
|
---|
696 | }
|
---|
697 |
|
---|
698 | //PRINT AN COMPLEX ERROR NUMBER
|
---|
699 | // Print to terminal window with text (message) and a line return
|
---|
700 | public void println(String message){
|
---|
701 | System.out.println(message + " " + this.toString());
|
---|
702 | }
|
---|
703 |
|
---|
704 | // Print to terminal window without text (message) but with a line return
|
---|
705 | public void println(){
|
---|
706 | System.out.println(" " + this.toString());
|
---|
707 | }
|
---|
708 |
|
---|
709 | // Print to terminal window with text (message) but without line return
|
---|
710 | public void print(String message){
|
---|
711 | System.out.print(message + " " + this.toString());
|
---|
712 | }
|
---|
713 |
|
---|
714 | // Print to terminal window without text (message) and without line return
|
---|
715 | public void print(){
|
---|
716 | System.out.print(" " + this.toString());
|
---|
717 | }
|
---|
718 | } |
---|