source: src/main/java/agents/anac/y2015/agentBuyogV2/flanagan/circuits/ImpedSpecRegression.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 127.2 KB
Line 
1/* Class ImpedSpecRegression
2*
3* Non-linear regression procedures for fitting impedance
4* spectroscopy and electrochemical impedance spectroscopy
5* data to user supplied circuit or one of a range of precompiled
6* circuit models.
7*
8* User supplied circuit models require the interface ImpedSpecModel
9*
10* WRITTEN BY: Dr Michael Thomas Flanagan
11*
12* DATE: 9 June 2007 (Derived from impedance spectroscopy programs, 2004 - 2007)
13* UPDATE: 16 October 2007, 5 July 2008
14*
15* DOCUMENTATION:
16* See Michael T Flanagan's Java library on-line web pages:
17* http://www.ee.ucl.ac.uk/~mflanaga/java/
18* http://www.ee.ucl.ac.uk/~mflanaga/java/ImpedSpecRegression.html
19*
20* Copyright (c) June 2007 Michael Thomas Flanagan
21*
22* PERMISSION TO COPY:
23* Permission to use, copy and modify this software and its documentation for
24* NON-COMMERCIAL purposes is granted, without fee, provided that an acknowledgement
25* to the author, Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies.
26*
27* Dr Michael Thomas Flanagan makes no representations about the suitability
28* or fitness of the software for any or for a particular purpose.
29* Michael Thomas Flanagan shall not be liable for any damages suffered
30* as a result of using, modifying or distributing this software or its derivatives.
31*
32****************************************************************************************/
33
34package agents.anac.y2015.agentBuyogV2.flanagan.circuits;
35
36import java.lang.reflect.Array;
37import java.text.*;
38import java.util.*;
39
40import agents.anac.y2015.agentBuyogV2.flanagan.analysis.ErrorProp;
41import agents.anac.y2015.agentBuyogV2.flanagan.analysis.Regression;
42import agents.anac.y2015.agentBuyogV2.flanagan.analysis.RegressionFunction2;
43import agents.anac.y2015.agentBuyogV2.flanagan.analysis.Stat;
44import agents.anac.y2015.agentBuyogV2.flanagan.complex.Complex;
45import agents.anac.y2015.agentBuyogV2.flanagan.complex.ComplexErrorProp;
46import agents.anac.y2015.agentBuyogV2.flanagan.io.*;
47import agents.anac.y2015.agentBuyogV2.flanagan.math.Conv;
48import agents.anac.y2015.agentBuyogV2.flanagan.math.Fmath;
49import agents.anac.y2015.agentBuyogV2.flanagan.plot.*;
50
51import java.lang.Object;
52
53
54public class ImpedSpecRegression extends Regression{
55
56 private String regressionTitle = null; // Title for output graphs and text file
57 private boolean fileType = false; // = true if 'n' number to be added to file name
58
59 private Complex appliedVoltage = null; // magnitude of the applied voltage as complex
60 private boolean appliedVoltageSet = false; // = true when applied voltage entered
61 private Complex appliedVoltageError = null; // error of the applied voltage as complex
62 private boolean voltageErrorSet = false; // = true when applied voltage error entered
63
64 private Complex referenceImpedance = null; // reference impedance
65 private boolean referenceSet = false; // = true when reference impedance entered
66
67 private double[] frequencies = null; // frequencies [Hz]
68 private double[] omegas = null; // radial frequencies
69 private double[] log10frequencies = null; // log10[frequencies/Hz]
70 private double[] log10omegas = null; // log10[radial frequencies]
71 private int numberOfFrequencies = 0; // number of points in the simulation
72 private boolean frequenciesSet = false; // = true when frequencies entered
73
74 private Complex[] voltages = null; // voltages
75 private Complex[] voltageWeights = null; // voltage weights
76 private double[] voltageMagnitudes = null; // magnitude of the voltages
77 private double[] voltageMagnitudeWeights = null; // voltage magnitude weights
78 private double[] voltagePhasesRad = null; // voltage phases [radians]of the voltages
79 private double[] voltagePhaseWeightsRad = null; // voltage phase weights [radians]
80 private double[] voltagePhasesDeg = null; // voltage phases [degrees]of the voltages
81 private double[] voltagePhaseWeightsDeg = null; // voltage phase weights [degrees]
82 private double[] realV = null; // real part of the voltage
83 private double[] realVweights = null; // real part of the voltage - weights
84 private double[] imagV = null; // imaginary part of the voltages
85 private double[] imagVweights = null; // imaginary part of the voltage - weights
86
87 private boolean weightsSet = true; // = false if no weights provided
88
89 private int dataEnteredTypePointer = -1; // = 0; real and imag voltage
90 // = 1: complex voltage
91 // = 2: voltage magnitude and radians
92 // = 3: voltage magnitude and degreees
93 // = 4; real and imag impedance
94 // = 5: complex mpedance
95 // = 6: mpedance magnitude and radians
96 // = 7: mpedance magnitude and degreees
97 // Entered data type
98 private String[] dataEnteredType = {"Complex voltage (as real and imaginary parts)", "Complex voltage (as Complex)", "Voltage Magnitude and phase (in radians)", "Voltage Magnitude and phase (in degrees)", "Complex impedance (as real and imaginary parts)", "Complex impedance (as Complex)", "Magnitude and phase (in radians)", "Magnitude and phase (in degrees)"};
99 private boolean voltageOrImpedance = true; // = true: data entered as test circuit voltages
100 // = false: data entered as test circuit impedances
101
102 private Complex[] impedances = null; // model impedances
103 private Complex[] impedanceWeights = null; // model impedance weights
104 private double[] impedanceMagnitudes = null; // magnitude of the impedances
105 private double[] impedanceMagnitudeWeights = null; // impedance magnitude weights
106 private double[] impedancePhasesRad = null; // impedance phases [radians]of the impedances
107 private double[] impedancePhaseWeightsRad = null; // impedance phase weights [radians]
108 private double[] impedancePhasesDeg = null; // impedance phases [degrees]of the impedances
109 private double[] impedancePhaseWeightsDeg = null; // impedance phase weights [degrees]
110 private double[] realZ = null; // real part of the model impedance
111 private double[] realZweights = null; // real part of the model impedance - weights
112 private double[] imagZ = null; // imaginary part of the model impedance
113 private double[] imagZweights = null; // imaginary part of the model impedance - weights
114 private boolean impedancesSet = false; // = true when impedances calculated
115
116
117 private double[] xRegression = null; // regression x-axis data
118 private double[][] yRegression = null; // regression y-axis data
119 private double[][] wRegression = null; // regression weights
120
121 private int modelNumber = 0; // model number
122 private int numberOfParameters = 0; // number of model parameters
123 private String[] parameterSymbols = null; // model parameter symbols
124 private boolean modelSet = false; // = true when a model number is entered
125 private boolean estimatesNeeded = false; // = true when a no estimates are to be entered and they are yet to be calculated
126
127 private boolean supressDefaultConstraints = false; // = true when in-built constraints on parameters supressed
128 private boolean supressAddedConstraints = false; // = true when added constraints on parameters supressed
129 private boolean supressAllConstraints = false; // = true when all constraints on parameters supressed
130
131 private ArrayList<Object> constraints = null; // user added constraints
132 private int numberOfAddedConstraints = -1; // number of user added constraints
133
134 private boolean constraintsAdded = false; // = true when user added constraints on parameters entered
135
136 private double[] initialEstimates = null; // initial estimates of parameter values
137 private double[] initialSteps = null; // initial steps of parameter values
138
139 private double[] bestEstimates = null; // best estimates of parameter values
140 private double[] standardDeviations = null; // standard deviations of the best estimates
141 private double[] coefficientsOfVariation = null; // coefficients of variation of the best estimates
142 private double[][] correlationCoefficients = null; // correlation coefficients of the best estimates
143 private double[] preMinimumGradients = null; // gradient before the minimum for each parameter
144 private double[] postMinimumGradients = null; // gradient after the minimum for each parameter
145
146 private int degreesOfFreedom = 0; // degrees of freedom
147 private double sumOfSquares = 0.0D; // sum of squares at minimum
148 private double reducedSumOfSquares = 0.0D; // reduced sum of squares at minimum
149 private double chiSquare = Double.NaN; // chiSquare
150 private double reducedChiSquare = Double.NaN; // reducedChiSquare
151 private double[] realZresiduals = null; // Real[Z] residuals
152 private double[] imagZresiduals = null; // Imag[Z] residuals
153
154 private double[] calculatedRealZ = null; // calculated Real[Z]
155 private double[] calculatedImagZ = null; // calculated Imag[Z]
156 private Complex[] calculatedImpedances = null; // calculated model impedances
157 private double[] calculatedImpedanceMagnitudes = null; // calculated impedance magnitudes
158 private double[] calculatedImpedancePhasesRad = null; // calculated impedance phases (radians)
159 private double[] calculatedImpedancePhasesDeg = null; // calculated impedance phases (degrees)
160
161 private double[] calculatedRealV = null; // calculated Real[voltage]
162 private double[] calculatedImagV = null; // calculated Imag[voltage]
163 private Complex[] calculatedVoltages = null; // calculated voltages
164 private double[] calculatedVoltageMagnitudes = null; // calculated voltage magnitudes
165 private double[] calculatedVoltagePhasesRad = null; // calculated voltage phases (radians)
166 private double[] calculatedVoltagePhasesDeg = null; // calculated voltage phases (degrees)
167
168 ArrayList<Object> results = null; // ArrayList with elements
169 // 0: number of frequencies
170 // 1: number of parameters
171 // 2: degrees of freedom
172 // 3: initial estimates
173 // 4: initial step sizes
174 // 5: best estimates
175 // 6: standard deviations
176 // 7: coefficients of variation
177 // 8: gradients about the minimum
178 // 9: reduced sum of squares
179 // 10: chi square
180 // 11: reduced chi square
181
182
183 private boolean estimatesSet = false; // = true when parameter estimates entered
184
185 private ImpedSpecModel userModel = null; // supplied user model
186 private boolean userModelSet = false; // = true if user model supplied
187 private RegressionFunction2 regressionFunction = null; // Regression function
188 private double tolerance = 1e-9; // tolerance in regression exit test
189 private int maximumIterations = 10000; // maximum iterations in regression procedure
190 private int numberOfIterations1 = -1; // number of iterations taken in the first regression
191 private int numberOfIterations2 = -1; // number of iterations taken in the second regression
192 private boolean regressionDone = false; // = true when regression completed
193
194 private int numberOfLineFrequencies = 8000; // number of points on calculated line plots
195 private boolean logOrLinear = true; // = true - log plot
196 // = false - linear plot
197 private double[] lineFrequencies = null; // frequencies for clculating theoretical lines
198 private double[] log10lineFrequencies = null; // log10 of the frequencies for clculating theoretical lines
199
200
201 // CONSTRUCTORS
202
203 // Constructor
204 public ImpedSpecRegression(){
205 this.regressionTitle = " ";
206 }
207
208 // Constructor setting title
209 public ImpedSpecRegression(String regressionTitle){
210 this.regressionTitle = regressionTitle;
211 }
212
213 // ENTER DATA
214
215 // Enter the applied voltage
216 public void setAppliedVoltage(double voltage){
217 this.appliedVoltage = new Complex(voltage, 0.0D);
218 this.appliedVoltageError = new Complex(0.0D, 0.0D);
219 this.appliedVoltageSet = true;
220 if(this.referenceSet && this.frequenciesSet)this.calculateExperimentalImpedances();
221 }
222
223 // Enter the setApplied voltage with error
224 public void appliedVoltage(double voltage, double voltageError){
225 this.appliedVoltage = new Complex(voltage, 0.0D);
226 this.appliedVoltageSet = true;
227 this.appliedVoltage = new Complex(voltageError, 0.0D);
228 this.voltageErrorSet = true;
229 if(this.referenceSet && this.frequenciesSet)this.calculateExperimentalImpedances();
230 }
231
232 // Enter the reference impedance - resistive
233 public void setReferenceImpedance(double resistance){
234 this.referenceImpedance = new Complex(resistance, 0.0D);
235 this.referenceSet = true;
236 if(this.appliedVoltageSet && this.frequenciesSet)this.calculateExperimentalImpedances();
237 }
238
239 // Enter the reference impedance - reactive
240 public void setReferenceImpedance(double real, double imag){
241 this.referenceImpedance = new Complex(real, imag);
242 this.referenceSet = true;
243 if(this.appliedVoltageSet && this.frequenciesSet)this.calculateExperimentalImpedances();
244 }
245
246 // Enter the reference impedance - reactive
247 public void setReferenceImpedance(Complex impedance){
248 this.referenceImpedance = impedance;
249 this.referenceSet = true;
250 if(this.appliedVoltageSet && this.frequenciesSet)this.calculateExperimentalImpedances();
251 }
252
253 // Enter data as frequencies and real and imaginary parts of the test circuit voltages - no weights
254 public void voltageDataAsComplex(double[] frequencies, double[] real, double[] imag){
255
256 double[] realWeight = new double[frequencies.length];
257 double[] imagWeight = new double[frequencies.length];
258 this.weightsSet = false;
259 this.voltageDataAsComplex(frequencies, real, imag, realWeight, imagWeight);
260 }
261
262
263 // Enter data as frequencies and real and imaginary parts of the test circuit voltages - weights provided
264 public void voltageDataAsComplex(double[] frequencies, double[] real, double[] imag, double[] realWeight, double[] imagWeight){
265
266 this.numberOfFrequencies = frequencies.length;
267 if(this.numberOfFrequencies!=real.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of Real[voltages], " + real.length);
268 if(this.numberOfFrequencies!=imag.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of Imag[voltages], " + imag.length);
269 if(this.numberOfFrequencies!=realWeight.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of real weights, " + realWeight.length);
270 if(this.numberOfFrequencies!=imagWeight.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of imag weights, " + imagWeight.length);
271
272 this.frequencies = Conv.copy(frequencies);
273 this.setAllFrequencyArrays();
274 this.setCalculatedArrayLengths();
275
276 this.realV = Conv.copy(real);
277 this.imagV = Conv.copy(imag);
278 this.realVweights = Conv.copy(realWeight);
279 this.imagVweights = Conv.copy(imagWeight);
280 this.voltageMagnitudes = new double[this.numberOfFrequencies];
281 this.voltagePhasesDeg = new double[this.numberOfFrequencies];
282 this.voltagePhasesRad = new double[this.numberOfFrequencies];
283 this.voltages = Complex.oneDarray(this.numberOfFrequencies);
284 for(int i=0; i<this.numberOfFrequencies; i++){
285 this.voltages[i] = new Complex(realV[i], imagV[i]);
286 this.voltageMagnitudes[i] = this.voltages[i].abs();
287 this.voltagePhasesRad[i] = this.voltages[i].arg();
288 this.voltagePhasesDeg[i] = Math.toDegrees(this.voltagePhasesRad[i]);
289 }
290 this.frequenciesSet = true;
291
292 this.setImpedanceArrayLengths();
293 this.calculateExperimentalImpedances();
294 this.dataEnteredTypePointer = 4;
295 this.voltageOrImpedance = true;
296 if(this.estimatesNeeded)this.setInitialEstimates();
297 }
298
299 // Enter data as frequencies and Complex test circuit voltages - no weights provided
300 public void voltageDataAsComplex(double[] frequencies, Complex[] voltages){
301
302 Complex[] weights = Complex.oneDarray(voltages.length, 0.0D, 0.0D);
303 this.weightsSet = false;
304 this.voltageDataAsComplex(frequencies, voltages, weights);
305 }
306
307 // Enter data as frequencies and Complex voltages - weights provided
308 // reference - voltage
309 public void voltageDataAsComplex(double[] frequencies, Complex[] voltages, Complex[] weights){
310
311 this.numberOfFrequencies = frequencies.length;
312 if(this.numberOfFrequencies!=voltages.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of voltages, " + voltages.length);
313 if(this.numberOfFrequencies!=weights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of weights, " + weights.length);
314
315 this.frequencies = Conv.copy(frequencies);
316 this.setAllFrequencyArrays();
317 this.setCalculatedArrayLengths();
318
319 this.voltages = Complex.copy(voltages);
320 this.voltageWeights = Complex.copy(weights);
321 this.voltageMagnitudes = new double[this.numberOfFrequencies];
322 this.voltagePhasesDeg = new double[this.numberOfFrequencies];
323 this.voltagePhasesRad = new double[this.numberOfFrequencies];
324 this.realV = new double[this.numberOfFrequencies];
325 this.imagV = new double[this.numberOfFrequencies];
326 this.realVweights = new double[this.numberOfFrequencies];
327 this.imagVweights = new double[this.numberOfFrequencies];
328
329 for(int i=0; i<this.numberOfFrequencies; i++){
330 this.realV[i] = this.voltages[i].getReal();
331 this.imagV[i] = this.voltages[i].getImag();
332 this.realVweights[i] = weights[i].getReal();
333 this.imagVweights[i] = weights[i].getImag();
334 this.voltageMagnitudes[i] = this.voltages[i].abs();
335 this.voltagePhasesRad[i] = this.voltages[i].arg();
336 this.voltagePhasesDeg[i] = Math.toDegrees(this.voltagePhasesRad[i]);
337 }
338 this.frequenciesSet = true;
339
340 this.setImpedanceArrayLengths();
341 this.calculateExperimentalImpedances();
342 this.voltageOrImpedance = true;
343 this.dataEnteredTypePointer = 1;
344 if(this.estimatesNeeded)this.setInitialEstimates();
345 }
346
347 // Enter data as frequencies and magnitudes and phases (radians) of the test circuit voltages - no weights
348 public void voltageDataAsPhasorRad(double[] frequencies, double[] voltageMagnitudes, double[] voltagePhasesRad){
349
350 double[] voltageMagWeights = new double[frequencies.length];
351 double[] voltagePhaseWeights = new double[frequencies.length];
352 this.weightsSet = false;
353 this.voltageDataAsPhasorRad(frequencies, voltageMagnitudes, voltagePhasesRad, voltageMagWeights, voltagePhaseWeights);
354 }
355
356 // Enter data as frequencies and magnitudes and phases (radians) of the voltages - weights provided
357 public void voltageDataAsPhasorRad(double[] frequencies, double[] voltageMagnitudes, double[] voltagePhasesRad, double[] voltageMagWeights, double[] voltagePhaseWeights){
358
359 this.numberOfFrequencies = frequencies.length;
360 if(this.numberOfFrequencies!=voltageMagnitudes.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitudes, " + voltageMagnitudes.length);
361 if(this.numberOfFrequencies!=voltagePhasesRad.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phases, " + voltagePhasesRad.length);
362 if(this.numberOfFrequencies!=voltageMagWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitude weights, " + voltageMagWeights.length);
363 if(this.numberOfFrequencies!=voltagePhaseWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phase weights, " + voltagePhaseWeights.length);
364
365 this.frequencies = Conv.copy(frequencies);
366 this.setAllFrequencyArrays();
367 this.setCalculatedArrayLengths();
368
369 this.voltageMagnitudes = Conv.copy(voltageMagnitudes);
370 this.voltageMagnitudeWeights = Conv.copy(voltageMagWeights);
371 this.voltagePhaseWeightsRad = Conv.copy(voltagePhaseWeights);
372 this.voltages= Complex.oneDarray(this.numberOfFrequencies);
373 this.voltagePhasesDeg = new double[this.numberOfFrequencies];
374 this.realV = new double[this.numberOfFrequencies];
375 this.imagV = new double[this.numberOfFrequencies];
376 this.realVweights = new double[this.numberOfFrequencies];
377 this.imagVweights = new double[this.numberOfFrequencies];
378
379 for(int i=0; i<this.numberOfFrequencies; i++){
380 this.voltagePhasesDeg[i] = Math.toDegrees(this.voltagePhasesRad[i]);
381 this.voltages[i].polar(voltageMagnitudes[i], voltagePhasesRad[i]);
382 this.realV[i] = this.voltages[i].getReal();
383 this.imagV[i] = this.voltages[i].getImag();
384 ErrorProp mag = new ErrorProp(voltageMagnitudes[i], voltageMagnitudeWeights[i]);
385 ErrorProp phase = new ErrorProp(voltagePhasesRad[i], voltagePhaseWeights[i]);
386 ComplexErrorProp volt = new ComplexErrorProp();
387 volt.polar(mag, phase);
388 this.realVweights[i] = volt.getRealError();
389 this.imagVweights[i] = volt.getImagError();
390 }
391 this.frequenciesSet = true;
392
393 this.setImpedanceArrayLengths();
394 this.calculateExperimentalImpedances();
395 this.voltageOrImpedance = true;
396 this.dataEnteredTypePointer = 2;
397 if(this.estimatesNeeded)this.setInitialEstimates();
398 }
399
400 // Enter data as frequencies and magnitudes and phases (degrees) of the test circuit voltages - no weights
401 public void voltageDataAsPhasorDeg(double[] frequencies, double[] voltageMagnitudes, double[] voltagePhasesRad){
402
403 double[] voltageMagWeights = new double[frequencies.length];
404 double[] voltagePhaseWeights = new double[frequencies.length];
405 this.weightsSet = false;
406 this.voltageDataAsPhasorDeg(frequencies, voltageMagnitudes, voltagePhasesRad, voltageMagWeights, voltagePhaseWeights);
407 }
408
409 // Enter data as frequencies and magnitudes and phases of the voltages (degrees)
410 public void voltageDataAsPhasorDeg(double[] frequencies, double[] voltageMagnitudes, double[] voltagePhasesDeg, double[] voltageMagWeights, double[] voltagePhaseWeights){
411
412 this.numberOfFrequencies = frequencies.length;
413 if(this.numberOfFrequencies!=voltageMagnitudes.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitudes, " + voltageMagnitudes.length);
414 if(this.numberOfFrequencies!=voltagePhasesDeg.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phases, " + voltagePhasesDeg.length);
415 if(this.numberOfFrequencies!=voltageMagWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitude weights, " + voltageMagWeights.length);
416 if(this.numberOfFrequencies!=voltagePhaseWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phase weights, " + voltagePhaseWeights.length);
417
418 this.frequencies = Conv.copy(frequencies);
419 this.setAllFrequencyArrays();
420 this.setCalculatedArrayLengths();
421
422 this.voltageMagnitudes = Conv.copy(voltageMagnitudes);
423 this.voltagePhasesDeg = Conv.copy(voltagePhasesDeg);
424 this.voltages = Complex.oneDarray(this.numberOfFrequencies);
425 this.voltagePhasesRad = new double[this.numberOfFrequencies];
426 this.voltagePhaseWeightsRad = new double[this.numberOfFrequencies];
427 this.voltageMagnitudeWeights = Conv.copy(voltageMagWeights);
428 this.voltagePhaseWeightsDeg = Conv.copy(voltagePhaseWeights);
429 this.realV = new double[this.numberOfFrequencies];
430 this.imagV = new double[this.numberOfFrequencies];
431 this.realVweights = new double[this.numberOfFrequencies];
432 this.imagVweights = new double[this.numberOfFrequencies];
433 for(int i=0; i<this.numberOfFrequencies; i++){
434 this.voltagePhasesRad[i] = Math.toRadians(this.voltagePhasesDeg[i]);
435 this.voltagePhaseWeightsRad[i] = Math.toRadians(voltagePhaseWeights[i]);
436 this.voltages[i].polar(voltageMagnitudes[i], voltagePhasesRad[i]);
437 this.realV[i] = this.voltages[i].getReal();
438 this.imagV[i] = this.voltages[i].getImag();
439 ErrorProp mag = new ErrorProp(voltageMagnitudes[i], voltageMagnitudeWeights[i]);
440 ErrorProp phase = new ErrorProp(voltagePhasesRad[i], this.voltagePhaseWeightsRad[i]);
441 ComplexErrorProp volt = new ComplexErrorProp();
442 volt.polar(mag, phase);
443 this.realVweights[i] = volt.getRealError();
444 this.imagVweights[i] = volt.getImagError();
445
446 }
447 this.frequenciesSet = true;
448
449 this.setImpedanceArrayLengths();
450 this.calculateExperimentalImpedances();
451 this.voltageOrImpedance = true;
452 this.dataEnteredTypePointer = 3;
453 if(this.estimatesNeeded)this.setInitialEstimates();
454 }
455
456 // Enter data as frequencies and real and imaginary parts of the impedances - no weights
457 public void impedanceDataAsComplex(double[] frequencies, double[] real, double[] imag){
458
459 double[] realWeight = new double[frequencies.length];
460 double[] imagWeight = new double[frequencies.length];
461 this.weightsSet = false;
462 this.impedanceDataAsComplex(frequencies, real, imag, realWeight, imagWeight);
463 }
464
465
466 // Enter data as frequencies and real and imaginary parts of the impedances - weights provided
467 public void impedanceDataAsComplex(double[] frequencies, double[] real, double[] imag, double[] realWeight, double[] imagWeight){
468
469 this.numberOfFrequencies = frequencies.length;
470 if(this.numberOfFrequencies!=real.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of Real[impedances], " + real.length);
471 if(this.numberOfFrequencies!=imag.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of Imag[impedances], " + imag.length);
472 if(this.numberOfFrequencies!=realWeight.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of real weights, " + realWeight.length);
473 if(this.numberOfFrequencies!=imagWeight.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of imag weights, " + imagWeight.length);
474
475 this.frequencies = Conv.copy(frequencies);
476 this.setAllFrequencyArrays();
477 this.setCalculatedArrayLengths();
478
479 this.realZ = Conv.copy(real);
480 this.imagZ = Conv.copy(imag);
481 this.realZweights = Conv.copy(realWeight);
482 this.imagZweights = Conv.copy(imagWeight);
483 this.impedanceMagnitudes = new double[this.numberOfFrequencies];
484 this.impedancePhasesDeg = new double[this.numberOfFrequencies];
485 this.impedancePhasesRad = new double[this.numberOfFrequencies];
486 this.impedances = Complex.oneDarray(this.numberOfFrequencies);
487 for(int i=0; i<this.numberOfFrequencies; i++){
488 this.impedances[i] = new Complex(realZ[i], imagZ[i]);
489 this.impedanceMagnitudes[i] = this.impedances[i].abs();
490 this.impedancePhasesRad[i] = this.impedances[i].arg();
491 this.impedancePhasesDeg[i] = Math.toDegrees(this.impedancePhasesRad[i]);
492 }
493 this.frequenciesSet = true;
494 this.impedancesSet = true;
495
496 this.dataEnteredTypePointer = 4;
497 this.voltageOrImpedance = false;
498 if(this.estimatesNeeded)this.setInitialEstimates();
499 }
500
501 // Enter data as frequencies and Complex impedances - no weights provided
502 public void impedanceDataAsComplex(double[] frequencies, Complex[] impedances){
503
504 Complex[] weights = Complex.oneDarray(impedances.length, 0.0D, 0.0D);
505 this.weightsSet = false;
506 this.impedanceDataAsComplex(frequencies, impedances, weights);
507 }
508
509 // Enter data as frequencies and Complex impedances - weights provided
510 public void impedanceDataAsComplex(double[] frequencies, Complex[] impedances, Complex[] weights){
511
512 this.numberOfFrequencies = frequencies.length;
513 if(this.numberOfFrequencies!=impedances.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of impedances, " + impedances.length);
514 if(this.numberOfFrequencies!=weights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of weights, " + weights.length);
515
516 this.frequencies = Conv.copy(frequencies);
517 this.setAllFrequencyArrays();
518 this.setCalculatedArrayLengths();
519
520 this.impedances = Complex.copy(impedances);
521 this.impedanceWeights = Complex.copy(weights);
522 this.impedanceMagnitudes = new double[this.numberOfFrequencies];
523 this.impedancePhasesDeg = new double[this.numberOfFrequencies];
524 this.impedancePhasesRad = new double[this.numberOfFrequencies];
525 this.realZ = new double[this.numberOfFrequencies];
526 this.imagZ = new double[this.numberOfFrequencies];
527 this.realZweights = new double[this.numberOfFrequencies];
528 this.imagZweights = new double[this.numberOfFrequencies];
529
530 for(int i=0; i<this.numberOfFrequencies; i++){
531 this.realZ[i] = this.impedances[i].getReal();
532 this.imagZ[i] = this.impedances[i].getImag();
533 this.realZweights[i] = weights[i].getReal();
534 this.imagZweights[i] = weights[i].getImag();
535 this.impedanceMagnitudes[i] = this.impedances[i].abs();
536 this.impedancePhasesRad[i] = this.impedances[i].arg();
537 this.impedancePhasesDeg[i] = Math.toDegrees(this.impedancePhasesRad[i]);
538 }
539 this.frequenciesSet = true;
540 this.impedancesSet = true;
541
542 this.voltageOrImpedance = false;
543 this.dataEnteredTypePointer = 5;
544 if(this.estimatesNeeded)this.setInitialEstimates();
545 }
546
547 // Enter data as frequencies and magnitudes and phases (radians) of the impedances - no weights
548 public void impedanceDataAsPhasorRad(double[] frequencies, double[] impedanceMagnitudes, double[] impedancePhasesRad){
549
550 double[] impedanceMagWeights = new double[frequencies.length];
551 double[] impedancePhaseWeights = new double[frequencies.length];
552 this.weightsSet = false;
553 this.impedanceDataAsPhasorRad(frequencies, impedanceMagnitudes, impedancePhasesRad, impedanceMagWeights, impedancePhaseWeights);
554 }
555
556 // Enter data as frequencies and magnitudes and phases (radians) of the impedances - weights provided
557 public void impedanceDataAsPhasorRad(double[] frequencies, double[] impedanceMagnitudes, double[] impedancePhasesRad, double[] impedanceMagWeights, double[] impedancePhaseWeights){
558
559 this.numberOfFrequencies = frequencies.length;
560 if(this.numberOfFrequencies!=impedanceMagnitudes.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitudes, " + impedanceMagnitudes.length);
561 if(this.numberOfFrequencies!=impedancePhasesRad.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phases, " + impedancePhasesRad.length);
562 if(this.numberOfFrequencies!=impedanceMagWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitude weights, " + impedanceMagWeights.length);
563 if(this.numberOfFrequencies!=impedancePhaseWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phase weights, " + impedancePhaseWeights.length);
564
565 this.frequencies = Conv.copy(frequencies);
566 this.setAllFrequencyArrays();
567 this.setCalculatedArrayLengths();
568
569 this.impedanceMagnitudes = Conv.copy(impedanceMagnitudes);
570 this.impedanceMagnitudeWeights = Conv.copy(impedanceMagWeights);
571 this.impedancePhaseWeightsRad = Conv.copy(impedancePhaseWeights);
572 this.impedances= Complex.oneDarray(this.numberOfFrequencies);
573 this.impedancePhasesDeg = new double[this.numberOfFrequencies];
574 this.realZ = new double[this.numberOfFrequencies];
575 this.imagZ = new double[this.numberOfFrequencies];
576 this.realZweights = new double[this.numberOfFrequencies];
577 this.imagZweights = new double[this.numberOfFrequencies];
578
579 for(int i=0; i<this.numberOfFrequencies; i++){
580 this.impedancePhasesDeg[i] = Math.toDegrees(this.impedancePhasesRad[i]);
581 this.impedances[i].polar(impedanceMagnitudes[i], impedancePhasesRad[i]);
582 this.realZ[i] = this.impedances[i].getReal();
583 this.imagZ[i] = this.impedances[i].getImag();
584 ErrorProp mag = new ErrorProp(impedanceMagnitudes[i], impedanceMagnitudeWeights[i]);
585 ErrorProp phase = new ErrorProp(impedancePhasesRad[i], impedancePhaseWeights[i]);
586 ComplexErrorProp volt = new ComplexErrorProp();
587 volt.polar(mag, phase);
588 this.realZweights[i] = volt.getRealError();
589 this.imagZweights[i] = volt.getImagError();
590 }
591 this.frequenciesSet = true;
592 this.impedancesSet = true;
593
594 this.voltageOrImpedance = false;
595 this.dataEnteredTypePointer = 6;
596 if(this.estimatesNeeded)this.setInitialEstimates();
597 }
598
599 // Enter data as frequencies and magnitudes and phases (degrees) of the impedances - no weights
600 public void impedanceDataAsPhasorDeg(double[] frequencies, double[] impedanceMagnitudes, double[] impedancePhasesRad){
601
602 double[] impedanceMagWeights = new double[frequencies.length];
603 double[] impedancePhaseWeights = new double[frequencies.length];
604 this.weightsSet = false;
605 this.impedanceDataAsPhasorDeg(frequencies, impedanceMagnitudes, impedancePhasesRad, impedanceMagWeights, impedancePhaseWeights);
606 }
607
608 // Enter data as frequencies and magnitudes and phases of the impedances (degrees)
609 public void impedanceDataAsPhasorDeg(double[] frequencies, double[] impedanceMagnitudes, double[] impedancePhasesDeg, double[] impedanceMagWeights, double[] impedancePhaseWeights){
610
611 this.numberOfFrequencies = frequencies.length;
612 if(this.numberOfFrequencies!=impedanceMagnitudes.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitudes, " + impedanceMagnitudes.length);
613 if(this.numberOfFrequencies!=impedancePhasesDeg.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phases, " + impedancePhasesDeg.length);
614 if(this.numberOfFrequencies!=impedanceMagWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of magnitude weights, " + impedanceMagWeights.length);
615 if(this.numberOfFrequencies!=impedancePhaseWeights.length)throw new IllegalArgumentException("The number of frequencies, " + this.numberOfFrequencies + ", does not equal the number of phase weights, " + impedancePhaseWeights.length);
616
617 this.frequencies = Conv.copy(frequencies);
618 this.setAllFrequencyArrays();
619 this.setCalculatedArrayLengths();
620
621 this.impedanceMagnitudes = Conv.copy(impedanceMagnitudes);
622 this.impedancePhasesDeg = Conv.copy(impedancePhasesDeg);
623 this.impedances = Complex.oneDarray(this.numberOfFrequencies);
624 this.impedancePhasesRad = new double[this.numberOfFrequencies];
625 this.impedancePhaseWeightsRad = new double[this.numberOfFrequencies];
626 this.impedanceMagnitudeWeights = Conv.copy(impedanceMagWeights);
627 this.impedancePhaseWeightsDeg = Conv.copy(impedancePhaseWeights);
628 this.realZ = new double[this.numberOfFrequencies];
629 this.imagZ = new double[this.numberOfFrequencies];
630 this.realZweights = new double[this.numberOfFrequencies];
631 this.imagZweights = new double[this.numberOfFrequencies];
632
633 for(int i=0; i<this.numberOfFrequencies; i++){
634 this.impedancePhasesRad[i] = Math.toRadians(this.impedancePhasesDeg[i]);
635 this.impedancePhaseWeightsRad[i] = Math.toRadians(impedancePhaseWeights[i]);
636 this.impedances[i].polar(impedanceMagnitudes[i], impedancePhasesRad[i]);
637 this.realZ[i] = this.impedances[i].getReal();
638 this.imagZ[i] = this.impedances[i].getImag();
639 ErrorProp mag = new ErrorProp(impedanceMagnitudes[i], impedanceMagnitudeWeights[i]);
640 ErrorProp phase = new ErrorProp(impedancePhasesRad[i], this.impedancePhaseWeightsRad[i]);
641 ComplexErrorProp volt = new ComplexErrorProp();
642 volt.polar(mag, phase);
643 this.realZweights[i] = volt.getRealError();
644 this.imagZweights[i] = volt.getImagError();
645
646 }
647 this.frequenciesSet = true;
648 this.impedancesSet = true;
649
650 this.voltageOrImpedance = false;
651 this.dataEnteredTypePointer = 7;
652 if(this.estimatesNeeded)this.setInitialEstimates();
653 }
654
655 // Set all frequency
656 private void setAllFrequencyArrays(){
657
658 this.log10frequencies = new double[this.numberOfFrequencies];
659 this.omegas = new double[this.numberOfFrequencies];
660 this.log10omegas = new double[this.numberOfFrequencies];
661 for(int i=0; i<this.numberOfFrequencies; i++){
662 this.log10frequencies[i] = Math.log10(frequencies[i]);
663 this.omegas[i] = 2.0D*Math.PI*frequencies[i];
664 this.log10omegas[i] = Math.log10(omegas[i]);
665 }
666 this.frequenciesSet = true;
667 }
668
669 // Set all calculted array lengths
670 private void setCalculatedArrayLengths(){
671
672 this.realZresiduals = new double[this.numberOfFrequencies];
673 this.imagZresiduals = new double[this.numberOfFrequencies];
674 this.calculatedRealZ = new double[this.numberOfFrequencies];
675 this.calculatedImagZ = new double[this.numberOfFrequencies];
676 this.calculatedImpedances = Complex.oneDarray(this.numberOfFrequencies);
677 this.calculatedImpedanceMagnitudes = new double[this.numberOfFrequencies];
678 this.calculatedImpedancePhasesRad = new double[this.numberOfFrequencies];
679 this.calculatedImpedancePhasesDeg = new double[this.numberOfFrequencies];
680
681 if(this.appliedVoltageSet && this.referenceSet){
682 this.calculatedRealV = new double[this.numberOfFrequencies];
683 this.calculatedImagV = new double[this.numberOfFrequencies];
684 this.calculatedVoltages = Complex.oneDarray(this.numberOfFrequencies);
685 this.calculatedVoltageMagnitudes = new double[this.numberOfFrequencies];
686 this.calculatedVoltagePhasesRad = new double[this.numberOfFrequencies];
687 this.calculatedVoltagePhasesDeg = new double[this.numberOfFrequencies];
688 }
689 }
690
691 // Set the impedance array lengths
692 private void setImpedanceArrayLengths(){
693
694 this.realZ = new double[this.numberOfFrequencies];
695 this.imagZ = new double[this.numberOfFrequencies];
696 this.realZweights = new double[this.numberOfFrequencies];
697 this.imagZweights = new double[this.numberOfFrequencies];
698 this.impedances = Complex.oneDarray(this.numberOfFrequencies);
699 this.impedanceMagnitudes = new double[this.numberOfFrequencies];
700 this.impedancePhasesRad = new double[this.numberOfFrequencies];
701 this.impedancePhasesDeg = new double[this.numberOfFrequencies];
702 }
703
704 // Calculate the experimental impedances if voltages have been entered
705 private void calculateExperimentalImpedances(){
706 if(this.referenceSet && this.appliedVoltageSet){
707 for(int i=0; i<this.numberOfFrequencies; i++){
708 // voltage divider calculation
709
710 this.impedances[i] = (this.referenceImpedance.times(this.voltages[i])).over(this.appliedVoltage.minus(this.voltages[i]));
711
712 this.realZ[i] = this.impedances[i].getReal();
713 this.imagZ[i] = this.impedances[i].getImag();
714
715 this.impedanceMagnitudes[i] = this.impedances[i].abs();
716 this.impedancePhasesRad[i] = this.impedances[i].arg();
717 this.impedancePhasesDeg[i] = Math.toDegrees(this.impedancePhasesRad[i]);
718
719 if(this.weightsSet && this.voltageErrorSet){
720 ComplexErrorProp appliedV = new ComplexErrorProp(this.appliedVoltage.getReal(), this.appliedVoltageError.getReal(), this.appliedVoltage.getImag(), this.appliedVoltageError.getImag());
721 ComplexErrorProp expertlV = new ComplexErrorProp(this.realV[i], this.realVweights[i], this.imagV[i], this.imagVweights[i]);
722 ComplexErrorProp refImped = new ComplexErrorProp(this.referenceImpedance.getReal(), 0.0D, this.referenceImpedance.getImag(), 0.0D);
723 ComplexErrorProp eVoverAv = (expertlV.over(appliedV)).times(refImped);
724 this.realZweights[i] = eVoverAv.getRealError();
725 this.imagZweights[i] = eVoverAv.getImagError();
726 }
727 this.impedancesSet = true;
728 }
729 }
730 }
731
732
733 // ENTER THE MODEL
734
735 // Enter user supplied model, parameter symbols, initial estimates and initial steps
736 public void setModel(ImpedSpecModel userModel, String[] symbols, double[] initialEstimates, double[] initialSteps){
737
738 this.userModel = userModel;
739 this.parameterSymbols = symbols;
740 this.numberOfParameters = symbols.length;
741 if(this.numberOfParameters!=initialEstimates.length)throw new IllegalArgumentException("The number of parameter symbols, " + this.numberOfParameters + ", does not equal the number of initial estimates, " + initialEstimates.length);
742 if(this.numberOfParameters!=initialSteps.length)throw new IllegalArgumentException("The number of parameter symbols, " + this.numberOfParameters + ", does not equal the number of initial steps, " + initialSteps.length);
743 this.initialEstimates = initialEstimates;
744 this.initialSteps = initialSteps;
745 this.setEstimateArrayDimensions();
746 this.estimatesSet = true;
747 this.userModelSet = true;
748 }
749
750 // Enter user supplied model, parameter symbols, initial estimates and initial steps calculated as 10% of initial estimates
751 public void setModel(ImpedSpecModel userModel, String[] symbols, double[] initialEstimates){
752
753 this.userModel = userModel;
754 this.parameterSymbols = symbols;
755 this.numberOfParameters = symbols.length;
756 if(this.numberOfParameters!=initialEstimates.length)throw new IllegalArgumentException("The number of parameter symbols, " + this.numberOfParameters + ", does not equal the number of initial estimates, " + initialEstimates.length);
757 this.initialEstimates = initialEstimates;
758 this.initialSteps = new double[this.numberOfParameters];
759 for(int i=0; i<this.numberOfParameters; i++)this.initialSteps[i] = Math.abs(this.initialEstimates[i])*0.1D;
760 this.setEstimateArrayDimensions();
761 this.estimatesSet = true;
762 this.userModelSet = true;
763 }
764
765 // Enter the model number, initial estimates and initial steps
766 public void setModel(int modelNumber, double[] initialEstimates, double[] initialSteps){
767
768 this.numberOfParameters = initialEstimates.length;
769 if(this.numberOfParameters!=Impedance.modelComponents(modelNumber).length)throw new IllegalArgumentException("The number of parameter estimates, " + this.numberOfParameters + ", does not equal the number of parameters, " + Impedance.modelComponents(modelNumber).length + ", in model number " + modelNumber);
770 if(this.numberOfParameters!=initialSteps.length)throw new IllegalArgumentException("The number of parameter estimates, " + this.numberOfParameters + ", does not equal the number of parameter steps, " + initialSteps.length);
771
772 this.modelNumber = modelNumber;
773 this.initialEstimates = initialEstimates;
774 this.initialSteps = initialSteps;
775 this.parameterSymbols = Impedance.modelComponents(modelNumber);
776 this.setEstimateArrayDimensions();
777 this.estimatesSet = true;
778 this.modelSet = true;
779 }
780
781 // Enter the model number and initial estimates - parameter steps calculated as 10% of initial estimated
782 public void setModel(int modelNumber, double[] initialEstimates){
783
784 this.numberOfParameters = initialEstimates.length;
785 if(this.numberOfParameters!=Impedance.modelComponents(modelNumber).length)throw new IllegalArgumentException("The number of parameter estimates, " + this.numberOfParameters + ", does not equal the number of parameters, " + Impedance.modelComponents(modelNumber).length + ", in model number " + modelNumber);
786
787 this.modelNumber = modelNumber;
788 this.initialEstimates = initialEstimates;
789 this.parameterSymbols = Impedance.modelComponents(modelNumber);
790 this.initialSteps = new double[this.numberOfParameters];
791 for(int i=0; i<this.numberOfParameters; i++)this.initialSteps[i] = Math.abs(this.initialEstimates[i])*0.1D;
792 this.setEstimateArrayDimensions();
793 this.estimatesSet = true;
794 this.modelSet = true;
795 }
796
797 // Enter the model number - parameters estimated by the method
798 public void setModel(int modelNumber){
799
800 this.modelNumber = modelNumber;
801 this.parameterSymbols = Impedance.modelComponents(modelNumber);
802 this.numberOfParameters = this.parameterSymbols.length;
803
804 this.setEstimateArrayDimensions();
805
806 // initial estimates
807 this.setInitialEstimates();
808 this.estimatesSet = true;
809
810 this.modelSet = true;
811 }
812
813 // Set dimensions of best estimates and associated arrays
814 private void setEstimateArrayDimensions(){
815
816 this.bestEstimates = new double[this.numberOfParameters];
817 this.standardDeviations = new double[this.numberOfParameters];
818 this.coefficientsOfVariation = new double[this.numberOfParameters];
819 this.preMinimumGradients = new double[this.numberOfParameters];
820 this.postMinimumGradients = new double[this.numberOfParameters];
821
822 this.correlationCoefficients = new double[this.numberOfParameters][this.numberOfParameters];
823 }
824
825 // Provide initial estimates for a given model number
826 private void setInitialEstimates(){
827 if(this.impedancesSet && this.frequenciesSet){
828
829 this.degreesOfFreedom = this.numberOfFrequencies - this.numberOfParameters;
830 if(this.degreesOfFreedom<=0)throw new IllegalArgumentException("Degrees of freedom, " + this.degreesOfFreedom + ", are less than 1");
831
832 double meanRealZ = Stat.mean(this.realZ);
833 double minRealZ = Fmath.minimum(this.realZ);
834 int indexMinRealZ = Fmath.indexOf(this.realZ, minRealZ);
835 double maxRealZ = Fmath.maximum(this.realZ);
836 int indexMaxRealZ = Fmath.indexOf(this.realZ, maxRealZ);
837
838 double meanImagZ = Stat.mean(this.imagZ);
839 double minImagZ = Fmath.minimum(this.imagZ);
840 int indexMinImagZ = Fmath.indexOf(this.imagZ, minImagZ);
841 double maxImagZ = Fmath.maximum(this.imagZ);
842 int indexMaxImagZ = Fmath.indexOf(this.imagZ, maxImagZ);
843
844 double imagBig = Math.max(Math.abs(minImagZ),Math.abs(maxImagZ));
845 int bigIndex = Fmath.indexOf(this.imagZ, imagBig);
846 if(bigIndex==-1)bigIndex = Fmath.indexOf(this.imagZ, -imagBig);
847 if(bigIndex==-1)bigIndex = this.numberOfFrequencies/2;
848
849 double geometricFreqMean = Stat.geometricMean(this.log10frequencies);
850
851 switch(this.modelNumber){
852 case 1: this.initialEstimates = new double[this.numberOfParameters];
853 this.initialEstimates[0] = meanRealZ;
854 break;
855 case 2: this.initialEstimates = new double[this.numberOfParameters];
856 double sumC = 0.0;
857 for(int i=0; i<this.numberOfFrequencies; i++)sumC += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
858 this.initialEstimates[0] = sumC/this.numberOfFrequencies;
859 break;
860 case 3: this.initialEstimates = new double[this.numberOfParameters];
861 double sumL = 0.0;
862 for(int i=0; i<this.numberOfFrequencies; i++)sumL += Math.abs(this.imagZ[i]/this.omegas[i]);
863 this.initialEstimates[0] = sumL/this.numberOfFrequencies;
864 break;
865 case 4: this.initialEstimates = new double[this.numberOfParameters];
866 double sumW = 0.0;
867 for(int i=0; i<this.numberOfFrequencies; i++){
868 sumW += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
869 sumW += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
870 }
871 this.initialEstimates[0] = sumW/(2.0D*this.numberOfFrequencies);
872 break;
873 case 5: this.initialEstimates = new double[this.numberOfParameters];
874 double sumF = 0.0;
875 for(int i=0; i<this.numberOfFrequencies; i++){
876 sumF += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
877 sumF += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
878 }
879 this.initialEstimates[0] = sumF/(2.0D*this.numberOfFrequencies);
880 this.initialEstimates[1] = Math.abs(meanRealZ/this.initialEstimates[0]);
881 break;
882 case 6: this.initialEstimates = new double[this.numberOfParameters];
883 double sumQ = 0.0;
884 for(int i=0; i<this.numberOfFrequencies; i++)sumQ += this.imagZ[i]/this.realZ[i];
885 sumQ /= this.numberOfFrequencies;
886 double theta = Math.abs(Math.atan(sumQ));
887 double cosTheta = Math.cos(theta);
888 double sinTheta = Math.sin(theta);
889 this.initialEstimates[1] = theta/(Math.PI/2.0);
890 double sigmaQ = 0.0;
891 for(int i=0; i<this.numberOfFrequencies; i++){
892 sigmaQ += Math.abs(realZ[i]/(cosTheta*Math.pow(this.omegas[i], this.initialEstimates[1])));
893 sigmaQ += Math.abs(imagZ[i]/(sinTheta*Math.pow(this.omegas[i], this.initialEstimates[1])));
894 }
895 this.initialEstimates[0] = sigmaQ/(2.0D*this.numberOfFrequencies);
896 break;
897 case 7: this.initialEstimates = new double[this.numberOfParameters];
898 this.initialEstimates[0] = meanRealZ;
899 double sumC7 = 0.0;
900 for(int i=0; i<this.numberOfFrequencies; i++)sumC7 += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
901 this.initialEstimates[1] = sumC7/this.numberOfFrequencies;
902 break;
903 case 8: this.initialEstimates = new double[this.numberOfParameters];
904 this.initialEstimates[0] = meanRealZ;
905 double sumL8 = 0.0;
906 for(int i=0; i<this.numberOfFrequencies; i++)sumL8 += Math.abs(this.imagZ[i]/this.omegas[i]);
907 this.initialEstimates[1] = sumL8/this.numberOfFrequencies;
908 break;
909 case 9: this.initialEstimates = new double[this.numberOfParameters];
910 double sumL9 = 0.0;
911 double sumC9 = 0.0;
912 for(int i=1; i<this.numberOfFrequencies; i++){
913 double cC9 = ((this.frequencies[i] - this.frequencies[i-1])/this.frequencies[i])/(this.imagZ[i]*this.frequencies[i-1] - this.imagZ[i-1]*this.frequencies[i]);
914 double lL9 = (this.imagZ[i] + 1.0D/(cC9*this.frequencies[i]))/this.frequencies[i];
915 sumL9 += lL9;
916 sumC9 += cC9;
917 }
918 this.initialEstimates[0] = sumL9/(this.numberOfFrequencies - 1);
919 this.initialEstimates[1] = sumC9/(this.numberOfFrequencies - 1);
920 break;
921 case 10: this.initialEstimates = new double[this.numberOfParameters];
922 this.initialEstimates[0] = maxRealZ;
923 this.initialEstimates[1] = 1.0D/(maxRealZ*this.frequencies[indexMinImagZ]);
924 break;
925 case 11: this.initialEstimates = new double[this.numberOfParameters];
926 this.initialEstimates[0] = maxRealZ;
927 this.initialEstimates[1] = maxRealZ/this.frequencies[indexMaxImagZ];
928 break;
929 case 12: this.initialEstimates = new double[this.numberOfParameters];
930 double cL12 = 1/this.frequencies[indexMinImagZ];
931 double sumL12 = 0.0;
932 double sumC12 = 0.0;
933 for(int i=1; i<this.numberOfFrequencies; i++){
934 double c12 = this.imagZ[i]*(this.frequencies[i]*cL12 - 1.0/this.frequencies[i]);
935 sumL12 += c12;
936 sumC12 += cL12/c12;
937 }
938 this.initialEstimates[0] = sumL12/this.numberOfFrequencies;
939 this.initialEstimates[1] = sumC12/this.numberOfFrequencies;
940 break;
941 case 13: this.initialEstimates = new double[this.numberOfParameters];
942 this.initialEstimates[2] = minRealZ;
943 this.initialEstimates[0] = maxRealZ - minRealZ;
944 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
945 break;
946 case 14: this.initialEstimates = new double[this.numberOfParameters];
947 this.initialEstimates[2] = minRealZ;
948 this.initialEstimates[0] = maxRealZ - minRealZ;
949 double sumL14 = 0.0;
950 double sumC14 = 0.0;
951 for(int i=1; i<this.numberOfFrequencies; i++){
952 double cC14 = ((this.frequencies[i] - this.frequencies[i-1])/this.frequencies[i])/(this.imagZ[i]*this.frequencies[i-1] - this.imagZ[i-1]*this.frequencies[i]);
953 double lL14 = (this.imagZ[i] + 1.0D/(cC14*this.frequencies[i]))/this.frequencies[i];
954 sumL14 += lL14;
955 sumC14 += cC14;
956 }
957 this.initialEstimates[3] = sumL14/(this.numberOfFrequencies - 1);
958 this.initialEstimates[1] = sumC14/(this.numberOfFrequencies - 1);
959 break;
960 case 15: this.initialEstimates = new double[this.numberOfParameters];
961 this.initialEstimates[2] = minRealZ;
962 this.initialEstimates[0] = maxRealZ - minRealZ;
963 double cL15 = 1/this.frequencies[indexMinImagZ];
964 double sumL15 = 0.0;
965 double sumC15 = 0.0;
966 for(int i=1; i<this.numberOfFrequencies; i++){
967 double c15 = this.imagZ[i]*(this.frequencies[i]*cL15 - 1.0/this.frequencies[i]);
968 sumL15 += c15;
969 sumC15 += cL15/c15;
970 }
971 this.initialEstimates[3] = sumL15/this.numberOfFrequencies;
972 this.initialEstimates[1] = sumC15/this.numberOfFrequencies;
973 break;
974 case 16: this.initialEstimates = new double[this.numberOfParameters];
975 this.initialEstimates[0] = maxRealZ;
976 double sumC16 = 0.0;
977 for(int i=0; i<this.numberOfFrequencies; i++)sumC16 += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
978 this.initialEstimates[1] = 2.0D*sumC16/this.numberOfFrequencies;
979 this.initialEstimates[2] = this.initialEstimates[1];
980 break;
981 case 17: this.initialEstimates = new double[this.numberOfParameters];
982 this.initialEstimates[0] = maxRealZ;
983 double sumC17 = 0.0;
984 for(int i=0; i<this.numberOfFrequencies; i++)sumC17 += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
985 this.initialEstimates[1] = sumC17/(2.0D*this.numberOfFrequencies);
986 this.initialEstimates[2] = this.initialEstimates[1];
987 case 18: this.initialEstimates = new double[this.numberOfParameters];
988 this.initialEstimates[0] = minRealZ;
989 this.initialEstimates[2] = maxRealZ - minRealZ;
990 double sumC18 = 0.0;
991 for(int i=0; i<this.numberOfFrequencies; i++)sumC18 += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
992 this.initialEstimates[1] = 2.0D*sumC18/this.numberOfFrequencies;
993 this.initialEstimates[3] = this.initialEstimates[1];
994 break;
995 case 19: this.initialEstimates = new double[this.numberOfParameters];
996 this.initialEstimates[0] = maxRealZ/2.0D;
997 this.initialEstimates[2] = this.initialEstimates[0];
998 this.initialEstimates[1] = 2.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
999 this.initialEstimates[3] = this.initialEstimates[1];
1000 break;
1001 case 20: this.initialEstimates = new double[this.numberOfParameters];
1002 this.initialEstimates[4] = minRealZ;
1003 this.initialEstimates[0] = (maxRealZ - minRealZ)/2.0D;
1004 this.initialEstimates[2] = this.initialEstimates[0];
1005 this.initialEstimates[1] = 2.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1006 this.initialEstimates[3] = this.initialEstimates[1];
1007 break;
1008 case 21: this.initialEstimates = new double[this.numberOfParameters];
1009 this.initialEstimates[4] = minRealZ;
1010 this.initialEstimates[0] = (maxRealZ - minRealZ)/2.0D;
1011 this.initialEstimates[2] = this.initialEstimates[0];
1012 double sumC21 = 0.0;
1013 for(int i=0; i<this.numberOfFrequencies; i++)sumC21 += 1.0D/Math.abs(this.imagZ[i]*this.omegas[i]);
1014 this.initialEstimates[1] = sumC21/(2.0D*this.numberOfFrequencies);
1015 this.initialEstimates[3] = this.initialEstimates[1];
1016 break;
1017 case 22: this.initialEstimates = new double[this.numberOfParameters];
1018 this.initialEstimates[0] = maxRealZ/3.0D;
1019 this.initialEstimates[2] = this.initialEstimates[0];
1020 this.initialEstimates[4] = this.initialEstimates[0];
1021 this.initialEstimates[1] = 3.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1022 this.initialEstimates[3] = this.initialEstimates[1];
1023 this.initialEstimates[5] = this.initialEstimates[1];
1024 break;
1025 case 23: this.initialEstimates = new double[this.numberOfParameters];
1026 this.initialEstimates[6] = minRealZ;
1027 this.initialEstimates[0] = (maxRealZ - minRealZ)/3.0D;
1028 this.initialEstimates[2] = this.initialEstimates[0];
1029 this.initialEstimates[4] = this.initialEstimates[0];
1030 this.initialEstimates[1] = 3.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1031 this.initialEstimates[3] = this.initialEstimates[1];
1032 this.initialEstimates[5] = this.initialEstimates[1];
1033 break;
1034 case 24: this.initialEstimates = new double[this.numberOfParameters];
1035 this.initialEstimates[3] = minRealZ;
1036 this.initialEstimates[0] = maxRealZ - minRealZ;
1037 double sumW24 = 0.0;
1038 if(indexMinImagZ<this.numberOfFrequencies-3){
1039 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1040 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1041 sumW24 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1042 sumW24 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1043 }
1044 this.initialEstimates[2] = sumW24/(2.0D*(this.numberOfFrequencies - indexMinImagZ));
1045 }
1046 else{
1047 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*geometricFreqMean);
1048 for(int i=0; i<this.numberOfFrequencies; i++){
1049 sumW24 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1050 sumW24 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1051 }
1052 this.initialEstimates[2] = sumW24/(2.0D*this.numberOfFrequencies);
1053 }
1054 break;
1055 case 25: this.initialEstimates = new double[this.numberOfParameters];
1056 this.initialEstimates[4] = minRealZ;
1057 this.initialEstimates[0] = maxRealZ - minRealZ;
1058 double sumF25 = 0.0;
1059 if(indexMinImagZ<this.numberOfFrequencies-3){
1060 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1061 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1062 sumF25 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1063 sumF25 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1064 }
1065 this.initialEstimates[2] = sumF25/(2.0D*(this.numberOfFrequencies - indexMinImagZ));
1066 this.initialEstimates[3] = Math.abs(meanRealZ/this.initialEstimates[2]);
1067 }
1068 else{
1069 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*geometricFreqMean);
1070 for(int i=0; i<this.numberOfFrequencies; i++){
1071 sumF25 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1072 sumF25 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1073 }
1074 this.initialEstimates[2] = sumF25/(2.0D*this.numberOfFrequencies);
1075 this.initialEstimates[3] = Math.abs(meanRealZ/this.initialEstimates[2]);
1076 }
1077 break;
1078 case 26: this.initialEstimates = new double[this.numberOfParameters];
1079 this.initialEstimates[4] = minRealZ;
1080 this.initialEstimates[0] = maxRealZ - minRealZ;
1081 double sumQ26 = 0.0;
1082 if(indexMinImagZ<this.numberOfFrequencies-3){
1083 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1084 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++)sumQ26 += this.imagZ[i]/this.realZ[i];
1085 sumQ26 /= (this.numberOfFrequencies - indexMinImagZ);
1086 double theta26 = Math.abs(Math.atan(sumQ26));
1087 double cosTheta26 = Math.cos(theta26);
1088 double sinTheta26 = Math.sin(theta26);
1089 this.initialEstimates[3] = theta26/(Math.PI/2.0);
1090 double sigmaQ26 = 0.0;
1091 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1092 sigmaQ26 += Math.abs(realZ[i]/(cosTheta26*Math.pow(this.omegas[i], this.initialEstimates[1])));
1093 sigmaQ26 += Math.abs(imagZ[i]/(sinTheta26*Math.pow(this.omegas[i], this.initialEstimates[1])));
1094 }
1095 this.initialEstimates[2] = sigmaQ26/(2.0D*(this.numberOfFrequencies - indexMinImagZ));
1096 }
1097 else{
1098 this.initialEstimates[1] = 1.0D/(this.initialEstimates[0]*geometricFreqMean);
1099 for(int i=0; i<this.numberOfFrequencies; i++)sumQ26 += this.imagZ[i]/this.realZ[i];
1100 sumQ26 /= this.numberOfFrequencies;
1101 double theta26 = Math.abs(Math.atan(sumQ26));
1102 double cosTheta26 = Math.cos(theta26);
1103 double sinTheta26 = Math.sin(theta26);
1104 this.initialEstimates[3] = theta26/(Math.PI/2.0);
1105 double sigmaQ26 = 0.0;
1106 for(int i=0; i<this.numberOfFrequencies; i++){
1107 sigmaQ26 += Math.abs(realZ[i]/(cosTheta26*Math.pow(this.omegas[i], this.initialEstimates[1])));
1108 sigmaQ26 += Math.abs(imagZ[i]/(sinTheta26*Math.pow(this.omegas[i], this.initialEstimates[1])));
1109 }
1110 this.initialEstimates[2] = sigmaQ26/(2.0D*this.numberOfFrequencies);
1111 }
1112 break;
1113 case 27: this.initialEstimates = new double[this.numberOfParameters];
1114 this.initialEstimates[0] = maxRealZ/2.0D;
1115 this.initialEstimates[2] = this.initialEstimates[0];
1116 double sumW27 = 0.0;
1117 if(indexMinImagZ<this.numberOfFrequencies-3){
1118 this.initialEstimates[1] = 2.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1119 this.initialEstimates[3] = this.initialEstimates[1];
1120 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1121 sumW27 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1122 sumW27 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1123 }
1124 this.initialEstimates[4] = sumW27/(2.0D*(this.numberOfFrequencies - indexMinImagZ));
1125 }
1126 else{
1127 this.initialEstimates[1] = 2.0D/(this.initialEstimates[0]*geometricFreqMean);
1128 this.initialEstimates[3] = this.initialEstimates[1];
1129 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1130 sumW27 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1131 sumW27 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1132 }
1133 this.initialEstimates[4] = sumW27/(2.0D*this.numberOfFrequencies);
1134 }
1135 break;
1136 case 28: this.initialEstimates = new double[this.numberOfParameters];
1137 this.initialEstimates[6] = minRealZ;
1138 this.initialEstimates[0] = (maxRealZ - minRealZ)/2.0D;
1139 this.initialEstimates[2] = this.initialEstimates[0];
1140 double sumW28 = 0.0;
1141 if(indexMinImagZ<this.numberOfFrequencies-3){
1142 this.initialEstimates[1] = 3.0D/(this.initialEstimates[0]*this.frequencies[indexMinImagZ]);
1143 this.initialEstimates[3] = this.initialEstimates[1];
1144 this.initialEstimates[5] = this.initialEstimates[1];
1145 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1146 sumW28 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1147 sumW28 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1148 }
1149 this.initialEstimates[4] = sumW28/(2.0D*(this.numberOfFrequencies - indexMinImagZ));
1150 }
1151 else{
1152 this.initialEstimates[1] = 3.0D/(this.initialEstimates[0]*geometricFreqMean);
1153 this.initialEstimates[3] = this.initialEstimates[1];
1154 this.initialEstimates[5] = this.initialEstimates[1];
1155 for(int i=indexMinImagZ; i<this.numberOfFrequencies; i++){
1156 sumW28 += Math.abs(this.realZ[i]*Math.sqrt(this.omegas[i]));
1157 sumW28 += Math.abs(this.imagZ[i]*Math.sqrt(this.omegas[i]));
1158 }
1159 this.initialEstimates[4] = sumW28/(2.0D*this.numberOfFrequencies);
1160 }
1161 break;
1162 default: throw new IllegalArgumentException("Automatically calculated initial estimates are only presntly available for models 1 to 28");
1163 }
1164
1165 // initial steps
1166 this.initialSteps = new double[this.numberOfParameters];
1167 for(int i=0; i<this.numberOfParameters; i++)this.initialSteps[i] = Math.abs(this.initialEstimates[i])*0.1D;
1168
1169 // check for zero step
1170 for(int i=0; i<this.numberOfParameters; i++){
1171 if(this.initialSteps[i]==0.0D){
1172 if(this.parameterSymbols[i].trim().substring(0,1).equals("R"))this.initialSteps[i] = maxRealZ*0.01D;
1173 if(this.parameterSymbols[i].trim().substring(0,1).equals("C"))this.initialSteps[i] = 0.01D/(imagBig*this.frequencies[bigIndex]);
1174 if(this.parameterSymbols[i].trim().substring(0,1).equals("L"))this.initialSteps[i] = imagBig*0.01D/this.frequencies[bigIndex];
1175 if(this.parameterSymbols[i].trim().substring(0,1).equals("W"))this.initialSteps[i] = 0.01D/(imagBig*Math.sqrt(this.frequencies[bigIndex]));
1176 if(this.parameterSymbols[i].trim().substring(0,2).equals("Fs"))this.initialSteps[i] = 0.01D/(imagBig*Math.sqrt(this.frequencies[bigIndex]));
1177 if(this.parameterSymbols[i].trim().substring(0,2).equals("Fd"))this.initialSteps[i] = 0.05D;
1178 if(this.parameterSymbols[i].trim().substring(0,2).equals("Qs"))this.initialSteps[i] = 0.01D/(imagBig*Math.sqrt(this.frequencies[bigIndex]));
1179 if(this.parameterSymbols[i].trim().substring(0,2).equals("Qa"))this.initialSteps[i] = 0.005D;
1180 }
1181 }
1182
1183 this.estimatesSet = true;
1184 }
1185 else{
1186 this.estimatesNeeded = true;
1187 }
1188 }
1189
1190 // get the initial estimates
1191 public double[] getInitialEstimates(){
1192 if(!this.estimatesSet)throw new IllegalArgumentException("No initial estimates have been entered or calculated");
1193 return this.initialEstimates;
1194 }
1195
1196 // get the model parameter symbols
1197 public String[] getCircuitComponents(){
1198 return this.parameterSymbols;
1199 }
1200
1201 // REGRESSION
1202
1203 // user addition of constraints
1204 public void addNewConstraint(int parameter, int direction, double boundary){
1205 this.constraints.add(new Integer(parameter));
1206 this.constraints.add(new Integer(direction));
1207 this.constraints.add(new Double(boundary));
1208 this.numberOfAddedConstraints++;
1209 this.constraintsAdded = true;
1210 }
1211
1212 public void addNewConstraint(String parameterSymbol, int direction, double boundary){
1213 if(this.numberOfParameters==0)throw new IllegalArgumentException("No model number or model parameters entered");
1214 int parameterNumber = -1;
1215 for(int i=0; i<this.numberOfParameters; i++){
1216 if( this.parameterSymbols[i].trim().equals( parameterSymbol.trim() ) )parameterNumber = i;
1217 }
1218 if(parameterNumber == -1)throw new IllegalArgumentException("Parameter symbol, " + parameterSymbol + ", not found");
1219
1220 this.constraints.add(new Integer(parameterNumber));
1221 this.constraints.add(new Integer(direction));
1222 this.constraints.add(new Double(boundary));
1223 this.numberOfAddedConstraints++;
1224 this.constraintsAdded = true;
1225 }
1226
1227 // remove default constraints on parameters
1228 public void removeDefaultConstraints(){
1229 this.supressDefaultConstraints = true;
1230 }
1231
1232 // restore default constraints on parameters
1233 public void restoreDefaultConstraints(){
1234 this.supressDefaultConstraints = false;
1235 }
1236
1237 // remove added constraints on parameters
1238 public void removeAddedConstraints(){
1239 this.supressAddedConstraints = true;
1240 this.constraintsAdded = false;
1241 }
1242
1243 // remove all constraints on parameters
1244 public void removeAllConstraints(){
1245 this.supressDefaultConstraints = true;
1246 this.supressAddedConstraints = true;
1247 this.constraintsAdded = false;
1248 }
1249
1250 // reset maximum number of iterations
1251 public void resetMaximumNumberOfIterations(int max){
1252 this.maximumIterations = max;
1253 }
1254
1255 // reset the regression tolerance
1256 public void resetTolerance(double tol){
1257 this.tolerance = tol;
1258 }
1259
1260 // get the regression results as ArrayList
1261 public ArrayList<Object> getRegressionResultsAsArrayList(){
1262 if(!this.regressionDone)this.regression();
1263 return this.results;
1264 }
1265
1266 // get the regression results as Vector
1267 public Vector<Object> getRegressionResultsAsVector(){
1268 if(!this.regressionDone)this.regression();
1269 int n = this.results.size();
1270 Vector<Object> res = new Vector<Object>(n);
1271 for(int i=0; i<n; i++)res.add(this.results.get(i));
1272 return res;
1273 }
1274
1275 // get the regression results as Vector
1276 public Vector<Object> getRegressionResults(){
1277 return this.getRegressionResults();
1278 }
1279
1280 // Set Regression data arrays
1281 private void setRegressionArrays(){
1282
1283 this.xRegression = new double[this.numberOfFrequencies];
1284 this.yRegression = new double[2][this.numberOfFrequencies];
1285 if(this.weightsSet)this.wRegression = new double[2][this.numberOfFrequencies];
1286
1287 for(int i=0; i<this.numberOfFrequencies; i++){
1288 xRegression[i] = this.omegas[i];
1289 yRegression[0][i] = this.realZ[i];
1290 yRegression[1][i] = this.imagZ[i];
1291 }
1292
1293 if(this.weightsSet){
1294 for(int i=0; i<this.numberOfFrequencies; i++){
1295 wRegression[0][i] = this.realZweights[i];
1296 wRegression[1][i] = this.imagZweights[i];
1297 }
1298 }
1299 }
1300
1301 // fit the data to the chosen model
1302 public ArrayList<Object> regression(){
1303
1304 // check data
1305 this.degreesOfFreedom = this.numberOfFrequencies - this.numberOfParameters;
1306 if(this.degreesOfFreedom<=0)throw new IllegalArgumentException("Degrees of freedom, " + this.degreesOfFreedom + ", are less than 1");
1307 if(!this.impedancesSet)throw new IllegalArgumentException("No impedances or voltages have been entered");
1308
1309 // check initial estimates have been provided
1310 if(!this.estimatesSet && !this.userModelSet)this.setInitialEstimates();
1311
1312 // Set regression arrays
1313 this.setRegressionArrays();
1314
1315 // store initial estimates and associated data
1316 this.results = new ArrayList<Object>();
1317 this.results.add(new Integer(this.numberOfFrequencies));
1318 this.results.add(new Integer(this.numberOfParameters));
1319 this.results.add(new Integer(this.degreesOfFreedom));
1320 this.results.add(this.parameterSymbols);
1321 this.results.add(Conv.copy(this.initialEstimates));
1322 this.results.add(Conv.copy(this.initialSteps));
1323
1324 // Enter regression data
1325 if(this.weightsSet){
1326 this.enterData(xRegression, yRegression, wRegression);
1327 }
1328 else{
1329 this.enterData(xRegression, yRegression);
1330 }
1331
1332 // Create instance of regression function
1333 if(this.userModelSet){
1334 ImpedSpecRegressionFunction2 function = new ImpedSpecRegressionFunction2();
1335 function.numberOfFrequencies = this.numberOfFrequencies;
1336 function.isModel = this.userModel;
1337 this.regressionFunction = function;
1338 }else{
1339 ImpedSpecRegressionFunction1 function = new ImpedSpecRegressionFunction1();
1340 function.numberOfFrequencies = this.numberOfFrequencies;
1341 function.modelNumber = this.modelNumber;
1342 this.regressionFunction = function;
1343 }
1344
1345 // Enter user added constraints
1346 int[] param = null;
1347 int[] direct = null;
1348 double[] bound = null;
1349 if(this.constraintsAdded){
1350 param = new int[this.numberOfAddedConstraints];
1351 direct = new int[this.numberOfAddedConstraints];
1352 bound = new double[this.numberOfAddedConstraints];
1353 int index = 0;
1354 for(int i=0; i<this.numberOfAddedConstraints; i++){
1355 int parameter = ((Integer)constraints.get(index)).intValue();
1356 param[i] = parameter;
1357 index++;
1358 int direction = ((Integer)constraints.get(index)).intValue();
1359 direct[i] = direction;
1360 index++;
1361 double boundary = ((Double)constraints.get(index)).doubleValue();
1362 bound[i] = boundary;
1363 index++;
1364 this.addConstraint(parameter, direction, boundary);
1365 }
1366 }
1367
1368 // enter in-built constraints (if not set to be supressed)
1369 if(!this.supressDefaultConstraints){
1370
1371 for(int i=0; i<this.numberOfParameters; i++){
1372 double lower = 0.0;
1373 double upper = 1.0;
1374 if(this.constraintsAdded){
1375 for(int j=0; j<this.numberOfAddedConstraints; j++){
1376 if(param[j]==i){
1377 if(direct[j]==1){
1378 upper = bound[j];
1379 }
1380 else{
1381 lower = bound[j];
1382 }
1383 }
1384 }
1385 }
1386 this.addConstraint(i, -1, lower);
1387 if(this.parameterSymbols[i].trim().substring(0,1).equals("Qa"))this.addConstraint(i, 1, upper);
1388 }
1389 }
1390
1391 // perform regression
1392 this.simplex2(this.regressionFunction, Conv.copy(this.initialEstimates), Conv.copy(this.initialSteps), this.tolerance, this.maximumIterations);
1393
1394 // repeat regression with best estimates as new initial estimates
1395 this.numberOfIterations1 = this.getNiter();
1396 double[] estimates = this.getCoeff();
1397 double[] steps = new double[this.numberOfParameters];
1398 for(int i=0; i<this.numberOfParameters; i++)steps[i] = Math.abs(estimates[i])*0.1D;
1399
1400 this.simplex2(this.regressionFunction, estimates, steps, this.tolerance, this.maximumIterations);
1401
1402 // store the regression results
1403 this.bestEstimates = this.getCoeff();
1404 this.results.add(this.bestEstimates);
1405 this.standardDeviations = this.getCoeffSd();
1406 this.results.add(this.standardDeviations);
1407 this.coefficientsOfVariation = this.getCoeffVar();
1408 this.results.add(this.coefficientsOfVariation);
1409 this.correlationCoefficients = this.getCorrCoeffMatrix();
1410 this.results.add(this.correlationCoefficients);
1411 double[][] gradients = new double[this.numberOfParameters][2];
1412 if(this.getGrad()==null){
1413 for(int i=0; i<this.numberOfParameters; i++){
1414 this.preMinimumGradients[i] = Double.NaN;
1415 this.postMinimumGradients[i] = Double.NaN;
1416 }
1417 }
1418 else{
1419 gradients = this.getGrad();
1420 for(int i=0; i<this.numberOfParameters; i++){
1421 this.preMinimumGradients[i] = gradients[i][0];
1422 this.postMinimumGradients[i] = gradients[i][1];
1423 }
1424 }
1425
1426 this.results.add(this.preMinimumGradients);
1427 this.results.add(this.postMinimumGradients);
1428 this.sumOfSquares = this.getSumOfSquares();
1429 this.results.add(new Double(this.sumOfSquares));
1430 this.reducedSumOfSquares = this.sumOfSquares/this.degreesOfFreedom;
1431 this.results.add(new Double(this.reducedSumOfSquares));
1432 if(this.weightsSet){
1433 this.chiSquare = this.getChiSquare();
1434 this.results.add(new Double(this.chiSquare));
1435 this.reducedChiSquare = this.getReducedChiSquare();
1436 this.results.add(new Double(this.reducedChiSquare));
1437 }
1438 else{
1439 this.results.add(null);
1440 this.results.add(null);
1441 }
1442 this.numberOfIterations2 = this.getNiter();
1443 this.results.add(new Integer(this.numberOfIterations1));
1444 this.results.add(new Integer(this.numberOfIterations2));
1445 this.results.add(new Integer(this.maximumIterations));
1446 this.results.add(this.dataEnteredType[this.dataEnteredTypePointer]);
1447
1448 this.results.add(this.frequencies);
1449 this.results.add(this.log10frequencies);
1450 this.results.add(this.omegas);
1451 this.results.add(this.log10omegas);
1452 this.results.add(this.impedanceMagnitudes);
1453 this.results.add(this.impedancePhasesRad);
1454 this.results.add(this.impedancePhasesDeg);
1455 this.results.add(this.impedances);
1456 this.results.add(this.realZ);
1457 this.results.add(this.imagZ);
1458
1459 double[] calculatedY = this.getYcalc();
1460 for(int i=0; i<this.numberOfFrequencies; i++){
1461 this.calculatedRealZ[i] = calculatedY[i];
1462 this.calculatedImagZ[i] = calculatedY[i + this.numberOfFrequencies];
1463 }
1464 this.results.add(this.calculatedRealZ);
1465 this.results.add(this.calculatedImagZ);
1466
1467
1468 double[] residuals = this.getResiduals();
1469 for(int i=0; i<this.numberOfFrequencies; i++){
1470 this.realZresiduals[i] = residuals[i];
1471 this.imagZresiduals[i] = residuals[i + this.numberOfFrequencies];
1472 }
1473 this.results.add(this.realZresiduals);
1474 this.results.add(this.imagZresiduals);
1475
1476 if(this.weightsSet){
1477 switch(this.dataEnteredTypePointer){
1478 case 0: this.results.add(this.realVweights);
1479 this.results.add(this.imagVweights);
1480 break;
1481 case 1: this.results.add(this.voltageWeights);
1482 this.results.add(null);
1483 break;
1484 case 2: this.results.add(this.voltageMagnitudeWeights);
1485 this.results.add(this.voltagePhaseWeightsRad);
1486 break;
1487 case 3: this.results.add(this.voltageMagnitudeWeights);
1488 this.results.add(this.voltagePhaseWeightsDeg);
1489 break;
1490 case 4: this.results.add(this.realZweights);
1491 this.results.add(this.imagZweights);
1492 break;
1493 case 5: this.results.add(this.impedanceWeights);
1494 this.results.add(null);
1495 break;
1496 case 6: this.results.add(this.impedanceMagnitudeWeights);
1497 this.results.add(this.impedancePhaseWeightsRad);
1498 break;
1499 case 7: this.results.add(this.impedanceMagnitudeWeights);
1500 this.results.add(this.impedancePhaseWeightsDeg);
1501 break;
1502 default: this.results.add(null);
1503 this.results.add(null);
1504 }
1505 this.results.add(this.realZweights);
1506 this.results.add(this.imagZweights);
1507 }
1508 else{
1509 for(int i=0; i<4; i++)this.results.add(null);
1510 }
1511
1512 for(int i=0; i<this.numberOfFrequencies; i++){
1513 this.calculatedImpedances[i] = new Complex(this.calculatedRealZ[i], this.calculatedImagZ[i]);
1514 this.calculatedImpedanceMagnitudes[i] = this.calculatedImpedances[i].abs();
1515 this.calculatedImpedancePhasesRad[i] = this.calculatedImpedances[i].arg();
1516 this.calculatedImpedancePhasesDeg[i] = Math.toDegrees(this.calculatedImpedancePhasesRad[i]);
1517 }
1518 this.results.add(this.calculatedImpedances);
1519 this.results.add(this.calculatedImpedanceMagnitudes);
1520 this.results.add(this.calculatedImpedancePhasesRad);
1521 this.results.add(this.calculatedImpedancePhasesDeg);
1522
1523 if(this.appliedVoltageSet && this.referenceSet){
1524 for(int i=0; i<this.numberOfFrequencies; i++){
1525 this.calculatedVoltages[i] = this.appliedVoltage.times(this.calculatedImpedances[i]).over(this.calculatedImpedances[i].plus(this.referenceImpedance));
1526 this.calculatedRealV[i] = this.calculatedVoltages[i].getReal();
1527 this.calculatedImagV[i] = this.calculatedVoltages[i].getImag();
1528 this.calculatedVoltageMagnitudes[i] = this.calculatedVoltages[i].abs();
1529 this.calculatedVoltagePhasesRad[i] = this.calculatedVoltages[i].arg();
1530 this.calculatedVoltagePhasesDeg[i] = Math.toDegrees(this.calculatedVoltagePhasesRad[i]);
1531 }
1532 this.results.add(this.calculatedVoltages);
1533 this.results.add(this.calculatedRealV);
1534 this.results.add(this.calculatedImagV);
1535 this.results.add(this.calculatedVoltageMagnitudes);
1536 this.results.add(this.calculatedVoltagePhasesRad);
1537 this.results.add(this.calculatedVoltagePhasesDeg);
1538 }
1539 else{
1540 for(int i=0; i<6; i++)this.results.add(null);
1541 }
1542
1543 this.regressionDone = true;
1544
1545 return this.results;
1546 }
1547
1548 // get the best estimates
1549 public double[] getBestEstimates(){
1550 if(!this.regressionDone)this.regression();
1551 return this.bestEstimates;
1552 }
1553
1554 // get the best estimates standard deviations
1555 public double[] getStandardDeviations(){
1556 if(!this.regressionDone)this.regression();
1557 return this.standardDeviations;
1558 }
1559
1560 // get the number of iterations taken in the first regression
1561 public int getFirstNumberOfIterations(){
1562 return this.numberOfIterations1;
1563 }
1564
1565 // get the number of iterations taken in the second regression
1566 public int getSecondNumberOfIterations(){
1567 return this.numberOfIterations2;
1568 }
1569
1570 // get the number of iterations taken
1571 public double getTolerance(){
1572 return this.tolerance;
1573 }
1574
1575 // PLOT
1576
1577 // Set linear option
1578 public void setLinearPlot(){
1579 this.logOrLinear = false;
1580
1581 }
1582
1583 // Set log10 option
1584 public void setLog10Plot(){
1585 this.logOrLinear = true;
1586 }
1587
1588 // Calculate line frequencies
1589 private void calculateLineFrequencies(){
1590 double lowestFrequency = Fmath.minimum(this.frequencies);
1591 double highestFrequency = Fmath.maximum(this.frequencies);
1592 if(this.logOrLinear){
1593 double logLow = Fmath.log10(lowestFrequency);
1594 double logHigh = Fmath.log10(highestFrequency);
1595 double increment = (logHigh - logLow)/(this.numberOfLineFrequencies - 1);
1596 this.lineFrequencies = new double[this.numberOfLineFrequencies];
1597 this.log10lineFrequencies = new double[this.numberOfLineFrequencies];
1598 this.log10lineFrequencies[0] = logLow;
1599 this.log10lineFrequencies[this.numberOfLineFrequencies-1] = logHigh;
1600 for(int i=1; i<this.numberOfLineFrequencies-1; i++)this.log10lineFrequencies[i] = this.log10lineFrequencies[i-1] + increment;
1601 for(int i=0; i<this.numberOfLineFrequencies; i++)this.lineFrequencies[i] = Math.pow(10.0D, this.log10lineFrequencies[i]);
1602
1603 }
1604 else{
1605 double increment = (highestFrequency - lowestFrequency)/(this.numberOfLineFrequencies - 1);
1606 this.lineFrequencies = new double[this.numberOfLineFrequencies];
1607 this.lineFrequencies[0] = lowestFrequency;
1608 this.log10lineFrequencies = new double[this.numberOfLineFrequencies];
1609 this.lineFrequencies[this.numberOfLineFrequencies-1] = highestFrequency;
1610 for(int i=1; i<this.numberOfLineFrequencies-1; i++)this.lineFrequencies[i] = this.lineFrequencies[i-1] + increment;
1611 for(int i=0; i<this.numberOfLineFrequencies; i++)this.log10lineFrequencies[i] = Fmath.log10(this.lineFrequencies[i]);
1612 }
1613 }
1614
1615 // Returns date and time
1616 private String[] dateAndTime(){
1617 Date d = new Date();
1618 String[] ret = new String[2];
1619 ret[0] = DateFormat.getDateInstance().format(d);
1620 ret[1] = DateFormat.getTimeInstance().format(d);
1621 return ret;
1622 }
1623
1624
1625 // Display Cole-Cole Plot
1626 public ArrayList<Object> plotColeCole(){
1627 String[] dAndT= this.dateAndTime();
1628 String graphTitle1 = "ImpedSpecRegression program: Cole - Cole plot [" + dAndT[0] + " " + dAndT[1] + "]";
1629 String graphTitle2 = this.regressionTitle;
1630
1631 if(!this.regressionDone)this.regression();
1632
1633 this.calculateLineFrequencies();
1634
1635 double[][] data = PlotGraph.data(2, this.numberOfLineFrequencies);
1636
1637 for(int i=0; i<this.numberOfFrequencies; i++){
1638 data[0][i] = this.realZ[this.numberOfFrequencies - i - 1];
1639 data[1][i] = -this.imagZ[this.numberOfFrequencies - i - 1];
1640 }
1641
1642 if(this.userModelSet){
1643 for(int i=0; i<this.numberOfLineFrequencies; i++){
1644 data[2][i] = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[this.numberOfLineFrequencies - i - 1]*2.0D*Math.PI).getReal();
1645 data[3][i] = -userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[this.numberOfLineFrequencies - i - 1]*2.0D*Math.PI).getImag();
1646 }
1647 }
1648 else{
1649 for(int i=0; i<this.numberOfLineFrequencies; i++){
1650 data[2][i] = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[this.numberOfLineFrequencies - i - 1]*2.0D*Math.PI, this.modelNumber).getReal();
1651 data[3][i] = -Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[this.numberOfLineFrequencies - i - 1]*2.0D*Math.PI, this.modelNumber).getImag();
1652 }
1653 }
1654
1655 PlotGraph pg = new PlotGraph(data);
1656 int[] lineOpt = {0, 3};
1657 pg.setLine(lineOpt);
1658 int[] pointOpt = {1, 0};
1659 pg.setPoint(pointOpt);
1660 pg.setGraphTitle(graphTitle1);
1661 pg.setGraphTitle2(graphTitle2);
1662 pg.setXaxisLegend("Real[Impedance / ohms]");
1663 pg.setYaxisLegend("-Imag[Impedance / ohms]");
1664 pg.plot();
1665
1666 return this.results;
1667 }
1668
1669 // Plot impedance magnitude versus frequency
1670 public ArrayList<Object> plotImpedanceMagnitudes(){
1671
1672 String[] dAndT= this.dateAndTime();
1673 String graphTitle1 = "ImpedSpecRegression program: Impedance magnitude versus frequency plot [" + dAndT[0] + " " + dAndT[1] + "]";
1674 String graphTitle2 = this.regressionTitle;
1675
1676 if(!this.regressionDone)this.regression();
1677
1678 this.calculateLineFrequencies();
1679
1680 // Magnitude versus frequency
1681 double[][] data = PlotGraph.data(2, this.numberOfLineFrequencies);
1682
1683 if(this.logOrLinear){
1684 for(int i=0; i<this.numberOfFrequencies; i++){
1685 data[0][i] = this.log10frequencies[i];
1686 data[1][i] = this.impedanceMagnitudes[i];
1687 }
1688 }
1689 else{
1690 for(int i=0; i<this.numberOfFrequencies; i++){
1691 data[0][i] = this.frequencies[i];
1692 data[1][i] = this.impedanceMagnitudes[i];
1693 }
1694 }
1695
1696 if(this.logOrLinear){
1697 if(this.userModelSet){
1698 for(int i=0; i<this.numberOfLineFrequencies; i++){
1699 data[2][i] = this.log10lineFrequencies[i];
1700 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1701 data[3][i] = imped.abs();
1702 }
1703 }
1704 else{
1705 for(int i=0; i<this.numberOfLineFrequencies; i++){
1706 data[2][i] = this.log10lineFrequencies[i];
1707 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1708 data[3][i] = imped.abs();
1709 }
1710 }
1711 }
1712 else{
1713 if(this.userModelSet){
1714 for(int i=0; i<this.numberOfLineFrequencies; i++){
1715 data[2][i] = this.lineFrequencies[i];
1716 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1717 data[3][i] = imped.abs();
1718 }
1719 }
1720 else{
1721 for(int i=0; i<this.numberOfLineFrequencies; i++){
1722 data[2][i] = this.lineFrequencies[i];
1723 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1724 data[3][i] = imped.abs();
1725 }
1726 }
1727 }
1728
1729 PlotGraph pg = new PlotGraph(data);
1730 int[] lineOpt = {0, 3};
1731 pg.setLine(lineOpt);
1732 int[] pointOpt = {1, 0};
1733 pg.setPoint(pointOpt);
1734 pg.setGraphTitle(graphTitle1);
1735 pg.setGraphTitle2(graphTitle2);
1736 if(this.logOrLinear){
1737 pg.setXaxisLegend("Log10[Frequency / Hz]");
1738 }
1739 else{
1740 pg.setXaxisLegend("Frequency / Hz");
1741 }
1742 pg.setYaxisLegend("Impedance Magnitude");
1743 pg.plot();
1744
1745 return this.results;
1746 }
1747
1748 // Plot impedance phase versus frequency
1749 public ArrayList<Object> plotImpedancePhases(){
1750
1751 String[] dAndT= this.dateAndTime();
1752 String graphTitle1 = "ImpedSpecRegression program: Impedance phase versus frequency plot [" + dAndT[0] + " " + dAndT[1] + "]";
1753 String graphTitle2 = this.regressionTitle;
1754
1755 if(!this.regressionDone)this.regression();
1756
1757 this.calculateLineFrequencies();
1758
1759 // Magnitude versus frequency
1760 double[][] data = PlotGraph.data(2, this.numberOfLineFrequencies);
1761
1762 if(this.logOrLinear){
1763 for(int i=0; i<this.numberOfFrequencies; i++){
1764 data[0][i] = this.log10frequencies[i];
1765 data[1][i] = this.impedancePhasesDeg[i];
1766 }
1767 }
1768 else{
1769 for(int i=0; i<this.numberOfFrequencies; i++){
1770 data[0][i] = this.frequencies[i];
1771 data[1][i] = this.impedancePhasesDeg[i];
1772 }
1773 }
1774
1775 if(this.logOrLinear){
1776 if(this.userModelSet){
1777 for(int i=0; i<this.numberOfLineFrequencies; i++){
1778 data[2][i] = this.log10lineFrequencies[i];
1779 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1780 data[3][i] = Math.toDegrees(imped.arg());
1781 }
1782 }
1783 else{
1784 for(int i=0; i<this.numberOfLineFrequencies; i++){
1785 data[2][i] = this.log10lineFrequencies[i];
1786 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1787 data[3][i] = Math.toDegrees(imped.arg());
1788 }
1789 }
1790 }
1791 else{
1792 if(this.userModelSet){
1793 for(int i=0; i<this.numberOfLineFrequencies; i++){
1794 data[2][i] = this.lineFrequencies[i];
1795 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1796 data[3][i] = Math.toDegrees(imped.arg());
1797 }
1798 }
1799 else{
1800 for(int i=0; i<this.numberOfLineFrequencies; i++){
1801 data[2][i] = this.lineFrequencies[i];
1802 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1803 data[3][i] = Math.toDegrees(imped.arg());
1804 }
1805 }
1806 }
1807
1808 PlotGraph pg = new PlotGraph(data);
1809 int[] lineOpt = {0, 3};
1810 pg.setLine(lineOpt);
1811 int[] pointOpt = {1, 0};
1812 pg.setPoint(pointOpt);
1813 pg.setGraphTitle(graphTitle1);
1814 pg.setGraphTitle2(graphTitle2);
1815 if(this.logOrLinear){
1816 pg.setXaxisLegend("Log10[Frequency / Hz]");
1817 }
1818 else{
1819 pg.setXaxisLegend("Frequency / Hz");
1820 }
1821 pg.setYaxisLegend("Impedance Phase / degrees");
1822 pg.plot();
1823
1824 return this.results;
1825 }
1826
1827
1828 // Plot voltage magnitude versus frequency
1829 public ArrayList<Object> plotVoltageMagnitudes(){
1830
1831 if(!this.regressionDone)this.regression();
1832
1833 if(this.referenceSet && this.appliedVoltageSet){
1834 String[] dAndT= this.dateAndTime();
1835 String graphTitle1 = "ImpedSpecRegression program: Voltage magnitude versus frequency plot [" + dAndT[0] + " " + dAndT[1] + "]";
1836 String graphTitle2 = this.regressionTitle;
1837
1838 this.calculateLineFrequencies();
1839
1840 double[][] data = PlotGraph.data(2, this.numberOfLineFrequencies);
1841
1842 if(this.logOrLinear){
1843 for(int i=0; i<this.numberOfFrequencies; i++){
1844 data[0][i] = this.log10frequencies[i];
1845 data[1][i] = this.voltageMagnitudes[i];
1846 }
1847 }
1848 else{
1849 for(int i=0; i<this.numberOfFrequencies; i++){
1850 data[0][i] = this.frequencies[i];
1851 data[1][i] = this.voltageMagnitudes[i];
1852 }
1853 }
1854
1855 if(this.logOrLinear){
1856 if(this.userModelSet){
1857 for(int i=0; i<this.numberOfLineFrequencies; i++){
1858 data[2][i] = this.log10lineFrequencies[i];
1859 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1860 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1861 data[3][i] = volt.abs();
1862 }
1863 }
1864 else{
1865 for(int i=0; i<this.numberOfLineFrequencies; i++){
1866 data[2][i] = this.log10lineFrequencies[i];
1867 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1868 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1869 data[3][i] = volt.abs();
1870 }
1871 }
1872 }
1873 else{
1874 if(this.userModelSet){
1875 for(int i=0; i<this.numberOfLineFrequencies; i++){
1876 data[2][i] = this.lineFrequencies[i];
1877 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1878 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1879 data[3][i] = volt.abs();
1880 }
1881 }
1882 else{
1883 for(int i=0; i<this.numberOfLineFrequencies; i++){
1884 data[2][i] = this.lineFrequencies[i];
1885 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1886 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1887 data[3][i] = volt.abs();
1888 }
1889 }
1890 }
1891
1892 PlotGraph pg = new PlotGraph(data);
1893 int[] lineOpt = {0, 3};
1894 pg.setLine(lineOpt);
1895 int[] pointOpt = {1, 0};
1896 pg.setPoint(pointOpt);
1897 pg.setGraphTitle(graphTitle1);
1898 pg.setGraphTitle2(graphTitle2);
1899 if(this.logOrLinear){
1900 pg.setXaxisLegend("Log10[Frequency / Hz]");
1901 }
1902 else{
1903 pg.setXaxisLegend("Frequency / Hz");
1904 }
1905 pg.setYaxisLegend("Voltage Magnitude");
1906 pg.plot();
1907 }
1908 else{
1909 System.out.println("The voltage magnitudes cannot be plotted as no reference impedance or applied voltage has been entered");
1910 }
1911
1912 return this.results;
1913 }
1914
1915 // Plot voltage phase versus frequency
1916 public ArrayList<Object> plotVoltagePhases(){
1917
1918 if(!this.regressionDone)this.regression();
1919
1920 if(this.referenceSet && this.appliedVoltageSet){
1921 String[] dAndT= this.dateAndTime();
1922 String graphTitle1 = "ImpedSpecRegression program: Voltage phase versus frequency plot [" + dAndT[0] + " " + dAndT[1] + "]";
1923 String graphTitle2 = this.regressionTitle;
1924
1925 this.calculateLineFrequencies();
1926
1927 double[][] data = PlotGraph.data(2, this.numberOfLineFrequencies);
1928
1929 if(this.logOrLinear){
1930 for(int i=0; i<this.numberOfFrequencies; i++){
1931 data[0][i] = this.log10frequencies[i];
1932 data[1][i] = this.voltagePhasesDeg[i];
1933 }
1934 }
1935 else{
1936 for(int i=0; i<this.numberOfFrequencies; i++){
1937 data[0][i] = this.frequencies[i];
1938 data[1][i] = this.voltagePhasesDeg[i];
1939 }
1940 }
1941
1942 if(this.logOrLinear){
1943 if(this.userModelSet){
1944 for(int i=0; i<this.numberOfLineFrequencies; i++){
1945 data[2][i] = this.log10lineFrequencies[i];
1946 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1947 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1948 data[3][i] = Math.toDegrees(volt.arg());
1949 }
1950 }
1951 else{
1952 for(int i=0; i<this.numberOfLineFrequencies; i++){
1953 data[2][i] = this.log10lineFrequencies[i];
1954 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1955 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1956 data[3][i] = Math.toDegrees(volt.arg());
1957 }
1958 }
1959 }
1960 else{
1961 if(this.userModelSet){
1962 for(int i=0; i<this.numberOfLineFrequencies; i++){
1963 data[2][i] = this.lineFrequencies[i];
1964 Complex imped = userModel.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI);
1965 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1966 data[3][i] = Math.toDegrees(volt.arg());
1967 }
1968 }
1969 else{
1970 for(int i=0; i<this.numberOfLineFrequencies; i++){
1971 data[2][i] = this.lineFrequencies[i];
1972 Complex imped = Impedance.modelImpedance(this.bestEstimates, this.lineFrequencies[i]*2.0D*Math.PI, this.modelNumber);
1973 Complex volt = imped.times(this.appliedVoltage).over(this.referenceImpedance.plus(imped));
1974 data[3][i] = Math.toDegrees(volt.arg());
1975 }
1976 }
1977 }
1978
1979 PlotGraph pg = new PlotGraph(data);
1980 int[] lineOpt = {0, 3};
1981 pg.setLine(lineOpt);
1982 int[] pointOpt = {1, 0};
1983 pg.setPoint(pointOpt);
1984 pg.setGraphTitle(graphTitle1);
1985 pg.setGraphTitle2(graphTitle2);
1986 if(this.logOrLinear){
1987 pg.setXaxisLegend("Log10[Frequency / Hz]");
1988 }
1989 else{
1990 pg.setXaxisLegend("Frequency / Hz");
1991 }
1992 pg.setYaxisLegend("Voltage Phases / degrees");
1993 pg.plot();
1994 }
1995 else{
1996 System.out.println("The voltage magnitudes cannot be plotted as no reference impedance or applied voltage has been entered");
1997 }
1998
1999 return this.results;
2000 }
2001
2002 // PRINT
2003
2004 // Print regression results to text file
2005 public ArrayList<Object> printToTextFile(){
2006 String fileName = "ImpedSpecRegressionOutput.txt";
2007 this.fileType = true;
2008 return this.printToTextFile(fileName);
2009 }
2010
2011 // Print regression results to text file
2012 public ArrayList<Object> printToTextFile(String fileName){
2013
2014 if(!this.regressionDone)regression();
2015
2016 int field = 11; // output field length
2017 int trunc = 4; // truncation length
2018
2019 // Check extension
2020 fileName = fileName.trim();
2021 int dotPosition = fileName.indexOf('.');
2022 if(dotPosition==-1)fileName += ".txt";
2023
2024 // instantiate a FileOutput
2025 FileOutput fout = null;
2026 if(this.fileType){
2027 fout = new FileOutput(fileName, 'n');
2028 }
2029 else{
2030 fout = new FileOutput(fileName);
2031 }
2032
2033 // print header
2034 fout.println("ImpedSpecRegression Program Output File: " + this.regressionTitle);
2035 fout.dateAndTimeln(fileName);
2036 fout.println();
2037 if(this.modelSet){
2038 fout.println("Circuit - model number " + this.modelNumber);
2039 }
2040 else{
2041 fout.println("Circuit supplied by the user");
2042 }
2043 fout.println();
2044
2045
2046 // print circuit parameters
2047 fout.println("Circuit Parameters");
2048 fout.println("Best Estimates");
2049
2050 fout.print("Parameter", field);
2051 fout.print("Best", field);
2052 fout.print("Standard", field);
2053 fout.print("Coeff. of", field);
2054 fout.print("Pre-", field);
2055 fout.println("Post-");
2056
2057 fout.print(" ", field);
2058 fout.print("estimate", field);
2059 fout.print("deviation", field);
2060 fout.print("variation", field);
2061 fout.print("gradient", field);
2062 fout.println("gradient");
2063
2064 for(int i=0; i<this.numberOfParameters; i++){
2065 fout.print(this.parameterSymbols[i], field);
2066 fout.print(Fmath.truncate(this.bestEstimates[i], trunc), field);
2067 fout.print(Fmath.truncate(this.standardDeviations[i], trunc), field);
2068 fout.print(Fmath.truncate(this.coefficientsOfVariation[i], trunc), field);
2069 fout.print(Fmath.truncate(this.preMinimumGradients[i], trunc), field);
2070 fout.println(Fmath.truncate(this.postMinimumGradients[i], trunc));
2071 }
2072 fout.println();
2073
2074 fout.println("Initial Estimates");
2075
2076 fout.print("Parameter", field);
2077 fout.print("Initial", field);
2078 fout.println("initial");
2079
2080 fout.print(" ", field);
2081 fout.print("estimate", field);
2082 fout.println("step size");
2083
2084 for(int i=0; i<this.numberOfParameters; i++){
2085 fout.print(this.parameterSymbols[i], field);
2086 fout.print(Fmath.truncate(this.initialEstimates[i], trunc), field);
2087 fout.println(Fmath.truncate(this.initialSteps[i], trunc));
2088 }
2089 fout.println();
2090
2091 // Print summary of regression statistics
2092 fout.println("Sum of squares of the Real[Z] and Imag[Z] residuals: " + Fmath.truncate(this.sumOfSquares, trunc));
2093 fout.println("Reduced sum of squares of the Real[Z] and Imag[Z] residuals: " + Fmath.truncate(this.sumOfSquares/this.degreesOfFreedom, trunc));
2094 fout.println("Degrees of freedom: " + this.degreesOfFreedom);
2095 if(this.weightsSet){
2096 fout.println("Chi square: " + Fmath.truncate(this.chiSquare, trunc));
2097 fout.println("Reduced chi square: " + Fmath.truncate(this.reducedChiSquare, trunc));
2098 }
2099 fout.println("Number of iterations taken in the first regression: " + this.numberOfIterations1);
2100 fout.println("Number of iterations taken in the second regression: " + this.numberOfIterations2);
2101 fout.println("Maximum number of iterations allowed in each regression: " + this.maximumIterations);
2102 fout.println();
2103
2104 // print aplied voltage and reference impedance if entered
2105 if(this.appliedVoltageSet)fout.println("Applied voltage: " + this.appliedVoltage.getReal());
2106 if(this.referenceSet)fout.println("Reference impedance: " + this.referenceImpedance);
2107 fout.println();
2108
2109 // Print impedance data for each frequency
2110 field=14;
2111 fout.println("Fitted and entered data [frequencies, calculated impedances, data as entered]");
2112 fout.print("Entered data type: ");
2113 fout.println(dataEnteredType[dataEnteredTypePointer]);
2114 fout.println();
2115
2116 fout.print("Frequency", field);
2117 fout.print("Experimental", field);
2118 fout.print("Calculated", field);
2119 fout.print("Experimental", field);
2120 fout.print("Calculated", field);
2121
2122 switch(this.dataEnteredTypePointer){
2123 case 0: fout.print("Real", field);
2124 fout.print("Imag", field);
2125 break;
2126 case 1: fout.print("Complex", field);
2127 break;
2128 case 2: fout.print("Magnitude", field);
2129 fout.print("Phase (rad)", field);
2130 break;
2131 case 3: fout.print("Magnitude", field);
2132 fout.print("Phase (deg)", field);
2133 break;
2134 case 4: fout.print("Real", field);
2135 fout.print("Imag", field);
2136 break;
2137 case 5: fout.print("Complex", field);
2138 break;
2139 case 6: fout.print("Magnitude", field);
2140 fout.print("Phase (rad)", field);
2141 break;
2142 case 7: fout.print("Magnitude", field);
2143 fout.print("Phase (deg)", field);
2144 break;
2145 }
2146 fout.println();
2147
2148 fout.print("Frequency", field);
2149 fout.print("Real[Z]", field);
2150 fout.print("Real[Z]", field);
2151 fout.print("Imag[Z]", field);
2152 fout.print("Imag[Z]", field);
2153 switch(this.dataEnteredTypePointer){
2154 case 0: fout.print("[voltage]", field);
2155 fout.print("[voltage]", field);
2156 break;
2157 case 1: fout.print("voltage", field);
2158 break;
2159 case 2: fout.print("[voltage]", field);
2160 fout.print("[voltage]", field);
2161 break;
2162 case 3: fout.print("[voltage]", field);
2163 fout.print("[voltage]", field);
2164 break;
2165 case 4: fout.print("[impedance]", field);
2166 fout.print("[impedance]", field);
2167 break;
2168 case 5: fout.print("impedance", field);
2169 break;
2170 case 6: fout.print("[impedance]", field);
2171 fout.print("[impedance]", field);
2172 break;
2173 case 7: fout.print("[impedance]", field);
2174 fout.print("[impedance]", field);
2175 break;
2176 }
2177 fout.println();
2178
2179 for(int i=0; i<this.numberOfFrequencies; i++){
2180 fout.print(Fmath.truncate(this.frequencies[i], trunc), field);
2181 fout.print(Fmath.truncate(this.realZ[i], trunc), field);
2182 fout.print(Fmath.truncate(this.calculatedRealZ[i], trunc), field);
2183 fout.print(Fmath.truncate(this.imagZ[i], trunc), field);
2184 fout.print(Fmath.truncate(this.calculatedImagZ[i], trunc),field);
2185
2186 switch(this.dataEnteredTypePointer){
2187 case 0: fout.print(Fmath.truncate(this.realV[i], trunc), field);
2188 fout.print(Fmath.truncate(this.imagV[i], trunc), field);
2189 break;
2190 case 1: fout.print(Complex.truncate(this.voltages[i], trunc), field);
2191 break;
2192 case 2: fout.print(Fmath.truncate(this.voltageMagnitudes[i], trunc), field);
2193 fout.print(Fmath.truncate(this.voltagePhasesRad[i], trunc), field);
2194 break;
2195 case 3: fout.print(Fmath.truncate(this.voltageMagnitudes[i], trunc), field);
2196 fout.print(Fmath.truncate(this.voltagePhasesDeg[i], trunc), field);
2197 break;
2198 case 4: fout.print(Fmath.truncate(this.realZ[i], trunc), field);
2199 fout.print(Fmath.truncate(this.imagZ[i], trunc), field);
2200 break;
2201 case 5: fout.print(Complex.truncate(this.impedances[i], trunc), field);
2202 break;
2203 case 6: fout.print(Fmath.truncate(this.impedanceMagnitudes[i], trunc), field);
2204 fout.print(Fmath.truncate(this.impedancePhasesRad[i], trunc), field);
2205 break;
2206 case 7: fout.print(Fmath.truncate(this.impedanceMagnitudes[i], trunc), field);
2207 fout.print(Fmath.truncate(this.impedancePhasesDeg[i], trunc), field);
2208 break;
2209 }
2210 fout.println();
2211 }
2212 fout.close();
2213
2214 return this.results;
2215 }
2216
2217
2218 // Print regression results to a .xls (MS Excel) file
2219 public ArrayList<Object> printToExcelFile(){
2220 String fileName = "ImpedSpecRegressionOutput.txt";
2221 this.fileType = true;
2222 return this.printToExcelFile(fileName);
2223 }
2224
2225 // Print regression results to a .xls (MS Excel) file
2226 public ArrayList<Object> printToExcelFile(String fileName){
2227
2228 if(!this.regressionDone)regression();
2229
2230 int field = 11; // output field length
2231 int trunc = 4; // truncation length
2232
2233 // Check extension
2234 fileName = fileName.trim();
2235 int dotPosition = fileName.indexOf('.');
2236 if(dotPosition==-1){
2237 fileName += ".xls";
2238 }
2239 else{
2240 fileName = fileName.substring(0, dotPosition) + ".xls";
2241 }
2242
2243 // instantiate a FileOutput
2244 FileOutput fout = null;
2245 if(this.fileType){
2246 fout = new FileOutput(fileName, 'n');
2247 }
2248 else{
2249 fout = new FileOutput(fileName);
2250 }
2251
2252 // print header
2253 fout.println("ImpedSpecRegression Program Output File: " + this.regressionTitle);
2254 fout.dateAndTimeln(fileName);
2255 fout.println();
2256 if(this.modelSet){
2257 fout.println("Circuit - model number " + this.modelNumber);
2258 }
2259 else{
2260 fout.println("Circuit supplied by the user");
2261 }
2262 fout.println();
2263
2264
2265 // print circuit parameters
2266 fout.println("Circuit Parameters");
2267 fout.println("Best Estimates");
2268
2269 fout.printtab("Parameter", field);
2270 fout.printtab("Best", field);
2271 fout.printtab("Standard", field);
2272 fout.printtab("Coeff. of", field);
2273 fout.printtab("Pre-", field);
2274 fout.println("Post-");
2275
2276 fout.printtab(" ", field);
2277 fout.printtab("estimate", field);
2278 fout.printtab("deviation", field);
2279 fout.printtab("variation", field);
2280 fout.printtab("gradient", field);
2281 fout.println("gradient");
2282
2283 for(int i=0; i<this.numberOfParameters; i++){
2284 fout.printtab(this.parameterSymbols[i], field);
2285 fout.printtab(Fmath.truncate(this.bestEstimates[i], trunc), field);
2286 fout.printtab(Fmath.truncate(this.standardDeviations[i], trunc), field);
2287 fout.printtab(Fmath.truncate(this.coefficientsOfVariation[i], trunc), field);
2288 fout.printtab(Fmath.truncate(this.preMinimumGradients[i], trunc), field);
2289 fout.println(Fmath.truncate(this.postMinimumGradients[i], trunc));
2290 }
2291 fout.println();
2292
2293 fout.println("Initial Estimates");
2294
2295 fout.printtab("Parameter", field);
2296 fout.printtab("Initial", field);
2297 fout.println("initial");
2298
2299 fout.printtab(" ", field);
2300 fout.printtab("estimate", field);
2301 fout.println("step size");
2302
2303 for(int i=0; i<this.numberOfParameters; i++){
2304 fout.printtab(this.parameterSymbols[i], field);
2305 fout.printtab(Fmath.truncate(this.initialEstimates[i], trunc), field);
2306 fout.println(Fmath.truncate(this.initialSteps[i], trunc));
2307 }
2308 fout.println();
2309
2310 // Print summary of regression statistics
2311 fout.println("Sum of squares of the Real[Z] and Imag[z] residuals: " + Fmath.truncate(this.sumOfSquares, trunc));
2312 fout.println("Reduced sum of squares of the Real[Z] and Imag[z] residuals: " + Fmath.truncate(this.sumOfSquares/this.degreesOfFreedom, trunc));
2313 fout.println("Degrees of freedom: " + this.degreesOfFreedom);
2314 if(this.weightsSet){
2315 fout.println("Chi square: " + Fmath.truncate(this.chiSquare, trunc));
2316 fout.println("Reduced chi square: " + Fmath.truncate(this.reducedChiSquare, trunc));
2317 }
2318 fout.println("Number of iterations taken in the first regression: " + this.numberOfIterations1);
2319 fout.println("Number of iterations taken in the second regression: " + this.numberOfIterations2);
2320 fout.println("Maximum number of iterations allowed in each regression: " + this.maximumIterations);
2321 fout.println();
2322
2323 // Print impedance data for each frequency
2324 field=14;
2325 fout.println("Fitted and entered data [frequencies, calculated impedances, data as entered]");
2326 fout.print("Entered data type: ");
2327 fout.println(dataEnteredType[dataEnteredTypePointer]);
2328 fout.println();
2329
2330 fout.printtab("Frequency", field);
2331 fout.printtab("Experimental", field);
2332 fout.printtab("Calculated", field);
2333 fout.printtab("Experimental", field);
2334 fout.printtab("Calculated", field);
2335
2336 switch(this.dataEnteredTypePointer){
2337 case 0: fout.printtab("Real", field);
2338 fout.printtab("Imag", field);
2339 break;
2340 case 1: fout.printtab("Complex", field);
2341 break;
2342 case 2: fout.printtab("Magnitude", field);
2343 fout.printtab("Phase (rad)", field);
2344 break;
2345 case 3: fout.printtab("Magnitude", field);
2346 fout.printtab("Phase (deg)", field);
2347 break;
2348 case 4: fout.printtab("Real", field);
2349 fout.printtab("Imag", field);
2350 break;
2351 case 5: fout.printtab("Complex", field);
2352 break;
2353 case 6: fout.printtab("Magnitude", field);
2354 fout.printtab("Phase (rad)", field);
2355 break;
2356 case 7: fout.printtab("Magnitude", field);
2357 fout.printtab("Phase (deg)", field);
2358 break;
2359 }
2360 fout.println();
2361
2362 fout.printtab("Frequency", field);
2363 fout.printtab("Real[Z]", field);
2364 fout.printtab("Real[Z]", field);
2365 fout.printtab("Imag[Z]", field);
2366 fout.printtab("Imag[Z]", field);
2367 switch(this.dataEnteredTypePointer){
2368 case 0: fout.printtab("[voltage]", field);
2369 fout.printtab("[voltage]", field);
2370 break;
2371 case 1: fout.printtab("voltage", field);
2372 break;
2373 case 2: fout.printtab("[voltage]", field);
2374 fout.printtab("[voltage]", field);
2375 break;
2376 case 3: fout.printtab("[voltage]", field);
2377 fout.printtab("[voltage]", field);
2378 break;
2379 case 4: fout.printtab("[impedance]", field);
2380 fout.printtab("[impedance]", field);
2381 break;
2382 case 5: fout.printtab("impedance", field);
2383 break;
2384 case 6: fout.printtab("[impedance]", field);
2385 fout.printtab("[impedance]", field);
2386 break;
2387 case 7: fout.printtab("[impedance]", field);
2388 fout.printtab("[impedance]", field);
2389 break;
2390 }
2391 fout.println();
2392
2393 for(int i=0; i<this.numberOfFrequencies; i++){
2394 fout.printtab(Fmath.truncate(this.frequencies[i], trunc), field);
2395 fout.printtab(Fmath.truncate(this.realZ[i], trunc), field);
2396 fout.printtab(Fmath.truncate(this.calculatedRealZ[i], trunc), field);
2397 fout.printtab(Fmath.truncate(this.imagZ[i], trunc), field);
2398 fout.printtab(Fmath.truncate(this.calculatedImagZ[i], trunc),field);
2399
2400 switch(this.dataEnteredTypePointer){
2401 case 0: fout.printtab(Fmath.truncate(this.realV[i], trunc), field);
2402 fout.printtab(Fmath.truncate(this.imagV[i], trunc), field);
2403 break;
2404 case 1: fout.printtab(Complex.truncate(this.voltages[i], trunc), field);
2405 break;
2406 case 2: fout.printtab(Fmath.truncate(this.voltageMagnitudes[i], trunc), field);
2407 fout.printtab(Fmath.truncate(this.voltagePhasesRad[i], trunc), field);
2408 break;
2409 case 3: fout.printtab(Fmath.truncate(this.voltageMagnitudes[i], trunc), field);
2410 fout.printtab(Fmath.truncate(this.voltagePhasesDeg[i], trunc), field);
2411 break;
2412 case 4: fout.printtab(Fmath.truncate(this.realZ[i], trunc), field);
2413 fout.printtab(Fmath.truncate(this.imagZ[i], trunc), field);
2414 break;
2415 case 5: fout.printtab(Complex.truncate(this.impedances[i], trunc), field);
2416 break;
2417 case 6: fout.printtab(Fmath.truncate(this.impedanceMagnitudes[i], trunc), field);
2418 fout.printtab(Fmath.truncate(this.impedancePhasesRad[i], trunc), field);
2419 break;
2420 case 7: fout.printtab(Fmath.truncate(this.impedanceMagnitudes[i], trunc), field);
2421 fout.printtab(Fmath.truncate(this.impedancePhasesDeg[i], trunc), field);
2422 break;
2423
2424 }
2425 fout.println();
2426 }
2427
2428 // close file
2429 fout.close();
2430
2431 return this.results;
2432 }
2433}
2434
2435
2436
2437
Note: See TracBrowser for help on using the repository browser.