1 | /*
|
---|
2 | * Class PlotPoleZero
|
---|
3 | *
|
---|
4 | * Plots, in a window, the poles and zeros of a transfer function,
|
---|
5 | * of the form of a polynomial over a polynomial, in either the s- or
|
---|
6 | * z-plane given the coefficients of the polynomials either as two arrays
|
---|
7 | * or as two types ComplexPolynom()
|
---|
8 | *
|
---|
9 | * WRITTEN BY: Dr Michael Thomas Flanagan
|
---|
10 | *
|
---|
11 | * DATE: July 2002
|
---|
12 | * REVISED: 22 June 2003, 14 August 2004, 16 May 2005, 7 July 2008, 10-12 August 2008
|
---|
13 | *
|
---|
14 | * DOCUMENTATION:
|
---|
15 | * See Michael Thomas Flanagan's Java library on-line web page:
|
---|
16 | * http://www.ee.ucl.ac.uk/~mflanaga/java/PlotPoleZero.html
|
---|
17 | * http://www.ee.ucl.ac.uk/~mflanaga/java/
|
---|
18 | *
|
---|
19 | * Copyright (c) June 2002 - 2008
|
---|
20 | *
|
---|
21 | * PERMISSION TO COPY:
|
---|
22 | * Permission to use, copy and modify this software and its documentation for
|
---|
23 | * NON-COMMERCIAL purposes is granted, without fee, provided that an acknowledgement
|
---|
24 | * to the author, Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies.
|
---|
25 | *
|
---|
26 | * Dr Michael Thomas Flanagan makes no representations about the suitability
|
---|
27 | * or fitness of the software for any or for a particular purpose.
|
---|
28 | * Michael Thomas Flanagan shall not be liable for any damages suffered
|
---|
29 | * as a result of using, modifying or distributing this software or its derivatives.
|
---|
30 | *
|
---|
31 | ***************************************************************************************/
|
---|
32 |
|
---|
33 |
|
---|
34 | package agents.anac.y2015.agentBuyogV2.flanagan.plot;
|
---|
35 |
|
---|
36 | import java.awt.*;
|
---|
37 |
|
---|
38 | import agents.anac.y2015.agentBuyogV2.flanagan.complex.Complex;
|
---|
39 | import agents.anac.y2015.agentBuyogV2.flanagan.complex.ComplexPoly;
|
---|
40 | import agents.anac.y2015.agentBuyogV2.flanagan.io.*;
|
---|
41 | import agents.anac.y2015.agentBuyogV2.flanagan.math.Fmath;
|
---|
42 |
|
---|
43 | public class PlotPoleZero{
|
---|
44 | private ComplexPoly numerPoly = null; // ComplexPoly instance of the numerator polynomial
|
---|
45 | private ComplexPoly denomPoly = null; // ComplexPoly instance of the denominator polynomial
|
---|
46 | private Complex[] numerRoots = null; // Roots of the numerator polynomial
|
---|
47 | private Complex[] denomRoots = null; // Roots of the denominator polynomial
|
---|
48 | private double[][] data = null; // Data for PlotGraph
|
---|
49 | private int nDeg = 0; // degree of numerator polynomial
|
---|
50 | private int dDeg = 0; // degree of denominator polynomial
|
---|
51 | private int mDeg = 0; // maximum of the two polynomial degrees
|
---|
52 | private int sORz = 0; // if 0 s or z plot, =1 s plane plot, =2 z plane plot
|
---|
53 | private boolean zerosSet = false; // = true if zeros entered directly
|
---|
54 | private boolean polesSet = false; // = true if poles entered directly
|
---|
55 | private boolean zCircle = false; // if true - a unit radius circle is plotted
|
---|
56 | private boolean noImag = true; // if true - no imaginary non-zero values
|
---|
57 | private boolean noReal = true; // if true - no real non-zero values
|
---|
58 | private boolean noZeros = true; // = true if no zeros, false if there are
|
---|
59 | private boolean noPoles = true; // = true if no poles, false if there are
|
---|
60 | private boolean setUnitAxes = false; // if true - axis set to span at least -1 to +1
|
---|
61 | // and unit circle is drawn
|
---|
62 | private boolean setEqualAxes = false; // if true - axis set to span equal ranges
|
---|
63 | private double scaleFactor = 1.0; // scales all dimensions of the plot
|
---|
64 |
|
---|
65 |
|
---|
66 | // Constructors
|
---|
67 | // no poles or zeros set
|
---|
68 | public PlotPoleZero(){
|
---|
69 | }
|
---|
70 |
|
---|
71 | // numer Array of coefficients of the numerator polynomial
|
---|
72 | // denom Array of coefficients of the denominator polynomial
|
---|
73 | // ComplexPoly coefficients
|
---|
74 | public PlotPoleZero(ComplexPoly numer, ComplexPoly denom){
|
---|
75 |
|
---|
76 | if(numer!=null){
|
---|
77 | this.nDeg = numer.getDeg();
|
---|
78 | if(this.nDeg>0){
|
---|
79 | this.numerPoly = ComplexPoly.copy(numer);
|
---|
80 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
81 | this.mDeg = nDeg;
|
---|
82 | this.noZeros = false;
|
---|
83 | }
|
---|
84 | }
|
---|
85 |
|
---|
86 | if(denom!=null){
|
---|
87 | this.dDeg = denom.getDeg();
|
---|
88 | if(this.dDeg>0){
|
---|
89 | this.denomPoly = ComplexPoly.copy(denom);
|
---|
90 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
91 | if(!this.noZeros){
|
---|
92 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
93 | }
|
---|
94 | else{
|
---|
95 | this.mDeg = dDeg;
|
---|
96 | }
|
---|
97 | this.noPoles = false;
|
---|
98 | }
|
---|
99 | }
|
---|
100 | if(this.noZeros && this.noPoles)throw new IllegalArgumentException("No poles or zeros entered");
|
---|
101 | }
|
---|
102 |
|
---|
103 | // Two arrays of Complex coefficients
|
---|
104 | public PlotPoleZero(Complex[] numer, Complex[] denom){
|
---|
105 |
|
---|
106 | if(numer!=null){
|
---|
107 | this.nDeg = numer.length-1;
|
---|
108 | if(this.nDeg>0){
|
---|
109 | this.numerPoly = new ComplexPoly(numer);;
|
---|
110 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
111 | this.mDeg = nDeg;
|
---|
112 | this.noZeros = false;
|
---|
113 | }
|
---|
114 | }
|
---|
115 |
|
---|
116 | if(denom!=null){
|
---|
117 | this.dDeg = denom.length-1;
|
---|
118 | if(this.dDeg>0){
|
---|
119 | this.denomPoly = new ComplexPoly(denom);;
|
---|
120 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
121 | if(!this.noZeros){
|
---|
122 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
123 | }
|
---|
124 | else{
|
---|
125 | this.mDeg = dDeg;
|
---|
126 | }
|
---|
127 | this.noPoles = false;
|
---|
128 | }
|
---|
129 | if(this.noZeros && this.noPoles)throw new IllegalArgumentException("No poles or zeros entered");
|
---|
130 | }
|
---|
131 | }
|
---|
132 |
|
---|
133 |
|
---|
134 | // Two arrays of double coefficients
|
---|
135 | public PlotPoleZero(double[] numer, double[] denom){
|
---|
136 |
|
---|
137 | if(numer!=null){
|
---|
138 | this.nDeg = numer.length-1;
|
---|
139 | if(this.nDeg>0){
|
---|
140 | this.numerPoly = new ComplexPoly(numer);;
|
---|
141 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
142 | this.mDeg = nDeg;
|
---|
143 | this.noZeros = false;
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | if(denom!=null){
|
---|
148 | this.dDeg = denom.length-1;
|
---|
149 | if(this.dDeg>0){
|
---|
150 | this.denomPoly = new ComplexPoly(denom);;
|
---|
151 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
152 | if(!this.noZeros){
|
---|
153 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
154 | }
|
---|
155 | else{
|
---|
156 | this.mDeg = dDeg;
|
---|
157 | }
|
---|
158 | this.noPoles = false;
|
---|
159 | }
|
---|
160 | if(this.noZeros && this.noPoles)throw new IllegalArgumentException("No poles or zeros entered");
|
---|
161 | }
|
---|
162 | }
|
---|
163 |
|
---|
164 |
|
---|
165 | // Enter zeros as ComplexPoly
|
---|
166 | public void setNumerator(ComplexPoly numer){
|
---|
167 | if(numer!=null){
|
---|
168 | this.nDeg = numer.getDeg();
|
---|
169 | if(this.nDeg>0){
|
---|
170 | this.numerPoly = ComplexPoly.copy(numer);
|
---|
171 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
172 | if(!this.noPoles){
|
---|
173 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
174 | }
|
---|
175 | else{
|
---|
176 | this.mDeg = nDeg;
|
---|
177 | }
|
---|
178 | this.noZeros = false;
|
---|
179 | }
|
---|
180 | }
|
---|
181 | else{
|
---|
182 | this.noZeros = true;
|
---|
183 | }
|
---|
184 | }
|
---|
185 |
|
---|
186 |
|
---|
187 | // Enter zeros: array of Complex coefficients
|
---|
188 | public void setNumerator(Complex[] numer){
|
---|
189 | if(numer!=null){
|
---|
190 | this.nDeg = numer.length-1;
|
---|
191 | if(this.nDeg>0){
|
---|
192 | this.numerPoly = new ComplexPoly(numer);;
|
---|
193 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
194 | if(!this.noPoles){
|
---|
195 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
196 | }
|
---|
197 | else{
|
---|
198 | this.mDeg = nDeg;
|
---|
199 | }
|
---|
200 | this.noZeros = false;
|
---|
201 | }
|
---|
202 | }
|
---|
203 | else{
|
---|
204 | this.noZeros = true;
|
---|
205 | }
|
---|
206 | }
|
---|
207 |
|
---|
208 | // Enter zeros: array of double coefficients
|
---|
209 | public void setNumerator(double[] numer){
|
---|
210 | if(numer!=null){
|
---|
211 | this.nDeg = numer.length-1;
|
---|
212 | if(this.nDeg>0){
|
---|
213 | this.numerPoly = new ComplexPoly(numer);;
|
---|
214 | this.numerRoots = Complex.oneDarray(nDeg);
|
---|
215 | if(!this.noPoles){
|
---|
216 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
217 | }
|
---|
218 | else{
|
---|
219 | this.mDeg = nDeg;
|
---|
220 | }
|
---|
221 | this.noZeros = false;
|
---|
222 | }
|
---|
223 | }
|
---|
224 | else{
|
---|
225 | this.noZeros = true;
|
---|
226 | }
|
---|
227 | }
|
---|
228 |
|
---|
229 | // Enter zeros as Complex roots
|
---|
230 | public void setZeros(Complex[] zeros){
|
---|
231 | if(zeros!=null){
|
---|
232 | this.nDeg = zeros.length;
|
---|
233 | if(this.nDeg>0){
|
---|
234 | this.numerRoots = zeros;
|
---|
235 | this.numerPoly = ComplexPoly.rootsToPoly(zeros);
|
---|
236 | if(!this.noPoles){
|
---|
237 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
238 | }
|
---|
239 | else{
|
---|
240 | this.mDeg = nDeg;
|
---|
241 | }
|
---|
242 | this.noZeros = false;
|
---|
243 | }
|
---|
244 | this.zerosSet = true;
|
---|
245 | }
|
---|
246 | else{
|
---|
247 | this.noZeros = true;
|
---|
248 | }
|
---|
249 | }
|
---|
250 |
|
---|
251 | // Enter zeros as double roots
|
---|
252 | public void setZeros(double[] zeros){
|
---|
253 | int n = zeros.length;
|
---|
254 | Complex[] czeros = Complex.oneDarray(n);
|
---|
255 | for(int i=0; i<n; i++)czeros[i] = new Complex(zeros[i], 0.0);
|
---|
256 | this.setZeros(czeros);
|
---|
257 | }
|
---|
258 |
|
---|
259 |
|
---|
260 |
|
---|
261 | // Enter poles as ComplexPoly
|
---|
262 | public void setDenominator(ComplexPoly denom){
|
---|
263 | if(denom!=null){
|
---|
264 | this.dDeg = denom.getDeg();
|
---|
265 | if(this.dDeg>0){
|
---|
266 | this.denomPoly = ComplexPoly.copy(denom);
|
---|
267 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
268 | if(!this.noZeros){
|
---|
269 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
270 | }
|
---|
271 | else{
|
---|
272 | this.mDeg = dDeg;
|
---|
273 | }
|
---|
274 | this.noPoles = false;
|
---|
275 | }
|
---|
276 | }
|
---|
277 | else{
|
---|
278 | this.noPoles = true;
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|
282 |
|
---|
283 |
|
---|
284 | // Enter poles: array of Complex coefficients
|
---|
285 | public void setDenominator(Complex[] denom){
|
---|
286 | if(denom!=null){
|
---|
287 | this.dDeg = denom.length-1;
|
---|
288 | if(this.dDeg>0){
|
---|
289 | this.denomPoly = new ComplexPoly(denom);;
|
---|
290 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
291 | if(!this.noZeros){
|
---|
292 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
293 | }
|
---|
294 | else{
|
---|
295 | this.mDeg = dDeg;
|
---|
296 | }
|
---|
297 | this.noPoles = false;
|
---|
298 | }
|
---|
299 | }
|
---|
300 | else{
|
---|
301 | this.noPoles = true;
|
---|
302 | }
|
---|
303 | }
|
---|
304 |
|
---|
305 |
|
---|
306 |
|
---|
307 | // Enter poles: array of double coefficients
|
---|
308 | public void setDenominator(double[] denom){
|
---|
309 | if(denom!=null){
|
---|
310 | this.dDeg = denom.length-1;
|
---|
311 | if(this.dDeg>0){
|
---|
312 | this.denomPoly = new ComplexPoly(denom);;
|
---|
313 | this.denomRoots = Complex.oneDarray(dDeg);
|
---|
314 | if(!this.noZeros){
|
---|
315 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
316 | }
|
---|
317 | else{
|
---|
318 | this.mDeg = dDeg;
|
---|
319 | }
|
---|
320 | this.noPoles = false;
|
---|
321 | }
|
---|
322 | }
|
---|
323 | else{
|
---|
324 | this.noPoles = true;
|
---|
325 | }
|
---|
326 | }
|
---|
327 |
|
---|
328 | // Enter poles as Complex roots
|
---|
329 | public void setPoles(Complex[] poles){
|
---|
330 | if(poles!=null){
|
---|
331 | this.dDeg = poles.length;
|
---|
332 | if(this.dDeg>0){
|
---|
333 | this.denomRoots = poles;
|
---|
334 | this.denomPoly = ComplexPoly.rootsToPoly(poles);
|
---|
335 | if(!this.noZeros){
|
---|
336 | this.mDeg = Math.max(nDeg, dDeg);
|
---|
337 | }
|
---|
338 | else{
|
---|
339 | this.mDeg = dDeg;
|
---|
340 | }
|
---|
341 | this.noPoles = false;
|
---|
342 | }
|
---|
343 | this.polesSet = true;
|
---|
344 | }
|
---|
345 | else{
|
---|
346 | this.noPoles = true;
|
---|
347 | }
|
---|
348 | }
|
---|
349 |
|
---|
350 | // Enter poles as double roots
|
---|
351 | public void setPoles(double[] poles){
|
---|
352 | int n = poles.length;
|
---|
353 | Complex[] cpoles = Complex.oneDarray(n);
|
---|
354 | for(int i=0; i<n; i++)cpoles[i] = new Complex(poles[i], 0.0);
|
---|
355 | this.setPoles(cpoles);
|
---|
356 | }
|
---|
357 |
|
---|
358 |
|
---|
359 | // Sets overall scale factor
|
---|
360 | public void setScaleFactor(double scale){
|
---|
361 | this.scaleFactor = scale;
|
---|
362 | }
|
---|
363 |
|
---|
364 | // Sets plot to s-plane plot
|
---|
365 | public void setS(){
|
---|
366 | this.sORz=1;
|
---|
367 | }
|
---|
368 |
|
---|
369 | // Sets plot to z-plane plot
|
---|
370 | public void setZ(){
|
---|
371 | this.sORz=2;
|
---|
372 | this.zCircle=true;
|
---|
373 | }
|
---|
374 |
|
---|
375 | // set axes to span unit circle
|
---|
376 | public void setUnitAxes(){
|
---|
377 | this.setUnitAxes = true;
|
---|
378 | this.setEqualAxes = false;
|
---|
379 | }
|
---|
380 |
|
---|
381 | // Sets axes to span equal ranges
|
---|
382 | public void setEqualAxes(){
|
---|
383 | this.setEqualAxes = true;
|
---|
384 | this.setUnitAxes = false;
|
---|
385 | }
|
---|
386 |
|
---|
387 | // Sets plot a unit radius circle.
|
---|
388 | public void setCircle(){
|
---|
389 | this.zCircle=true;
|
---|
390 | if(this.sORz!=2)sORz=2;
|
---|
391 | }
|
---|
392 |
|
---|
393 | // Unsets plot a unit radius circle.
|
---|
394 | public void unsetCircle(){
|
---|
395 | this.zCircle=false;
|
---|
396 | }
|
---|
397 |
|
---|
398 | // Calculate roots and plot and write to text file
|
---|
399 | // Plot title given
|
---|
400 | public Complex[][] pzPlot(String title){
|
---|
401 | if(this.noPoles && this.noZeros)throw new IllegalArgumentException("No poles or zeros have been entered");
|
---|
402 |
|
---|
403 | double absReal = 0.0D;
|
---|
404 | double absImag = 0.0D;
|
---|
405 | double zeroLimit = 1e-5;
|
---|
406 | double minall = 0.0;
|
---|
407 | double maxall = 0.0;
|
---|
408 | int ncirc = 600;
|
---|
409 | double stp = 2.0/(double)(ncirc-1);
|
---|
410 | int maxPoints = 0;
|
---|
411 | double[] zerosReal = null;
|
---|
412 | double[] zerosImag = null;
|
---|
413 | double[] polesReal = null;
|
---|
414 | double[] polesImag = null;
|
---|
415 | double[] xAxisIfRealZero = null;
|
---|
416 | double[] yAxisIfRealZero = null;
|
---|
417 | double[] xAxisIfImagZero = null;
|
---|
418 | double[] yAxisIfImagZero = null;
|
---|
419 | double[] xAxisCircle1 = new double[ncirc];
|
---|
420 | double[] yAxisCircle1 = new double[ncirc];
|
---|
421 | double[] xAxisCircle2 = new double[ncirc];
|
---|
422 | double[] yAxisCircle2 = new double[ncirc];
|
---|
423 |
|
---|
424 | Complex[][] zerosAndPoles = {null, null};
|
---|
425 |
|
---|
426 | int mm=0;
|
---|
427 | if(this.nDeg>0){
|
---|
428 | mm++;
|
---|
429 | zerosReal = new double[this.nDeg];
|
---|
430 | zerosImag = new double[this.nDeg];
|
---|
431 | if(!this.zerosSet)this.numerRoots = this.numerPoly.roots();
|
---|
432 | zerosAndPoles[0] = this.numerRoots;
|
---|
433 | for(int i=0; i<this.nDeg; i++){
|
---|
434 | zerosReal[i] = this.numerRoots[i].getReal();
|
---|
435 | zerosImag[i] = this.numerRoots[i].getImag();
|
---|
436 | if(!numerRoots[i].isZero()){
|
---|
437 | absReal = Math.abs(zerosReal[i]);
|
---|
438 | absImag = Math.abs(zerosImag[i]);
|
---|
439 | if(absReal>absImag){
|
---|
440 | if(absImag<zeroLimit*absReal)zerosImag[i]=0.0D;
|
---|
441 | }
|
---|
442 | else{
|
---|
443 | if(absReal<zeroLimit*absImag)zerosReal[i]=0.0D;
|
---|
444 | }
|
---|
445 | }
|
---|
446 | if(zerosReal[i]!=0.0D)this.noReal=false;
|
---|
447 | if(zerosImag[i]!=0.0D)this.noImag=false;
|
---|
448 | }
|
---|
449 | maxPoints = nDeg;
|
---|
450 | }
|
---|
451 |
|
---|
452 | if(this.dDeg>0){
|
---|
453 | mm++;
|
---|
454 | polesReal = new double[this.dDeg];
|
---|
455 | polesImag = new double[this.dDeg];
|
---|
456 | if(!this.polesSet)this.denomRoots = this.denomPoly.roots();
|
---|
457 | zerosAndPoles[1] = this.denomRoots;
|
---|
458 | for(int i=0; i<this.dDeg; i++){
|
---|
459 | polesReal[i] = this.denomRoots[i].getReal();
|
---|
460 | polesImag[i] = this.denomRoots[i].getImag();
|
---|
461 | if(!denomRoots[i].isZero()){
|
---|
462 | absReal = Math.abs(polesReal[i]);
|
---|
463 | absImag = Math.abs(polesImag[i]);
|
---|
464 | if(absReal>absImag){
|
---|
465 | if(absImag<zeroLimit*absReal)polesImag[i]=0.0D;
|
---|
466 | }
|
---|
467 | else{
|
---|
468 | if(absReal<zeroLimit*absImag)polesReal[i]=0.0D;
|
---|
469 | }
|
---|
470 | }
|
---|
471 | if(polesReal[i]!=0.0D)this.noReal=false;
|
---|
472 | if(polesImag[i]!=0.0D)this.noImag=false;
|
---|
473 | }
|
---|
474 | if(dDeg>maxPoints)maxPoints=dDeg;
|
---|
475 | }
|
---|
476 |
|
---|
477 | if(this.noReal){
|
---|
478 | mm++;
|
---|
479 | xAxisIfRealZero = new double[2];
|
---|
480 | xAxisIfRealZero[0]=1.D;
|
---|
481 | xAxisIfRealZero[1]=-1.0D;
|
---|
482 | yAxisIfRealZero = new double[2];
|
---|
483 | yAxisIfRealZero[0]=0.0D;
|
---|
484 | yAxisIfRealZero[1]=0.0D;
|
---|
485 | if(2>maxPoints)maxPoints=2;
|
---|
486 | }
|
---|
487 |
|
---|
488 | if(this.noImag){
|
---|
489 | mm++;
|
---|
490 | xAxisIfImagZero = new double[2];
|
---|
491 | xAxisIfImagZero[0]=0.0D;
|
---|
492 | xAxisIfImagZero[1]=0.0D;
|
---|
493 | yAxisIfImagZero = new double[2];
|
---|
494 | yAxisIfImagZero[0]=1.0D;
|
---|
495 | yAxisIfImagZero[1]=-1.0D;
|
---|
496 | if(2>maxPoints)maxPoints=2;
|
---|
497 | }
|
---|
498 |
|
---|
499 | if(this.zCircle){
|
---|
500 | mm+=2;
|
---|
501 | xAxisCircle1[0]=-1.0;
|
---|
502 | yAxisCircle1[0]=0.0;
|
---|
503 | xAxisCircle2[0]=-1.0;
|
---|
504 | yAxisCircle2[0]=0.0;
|
---|
505 | for(int i=1; i<ncirc; i++){
|
---|
506 | xAxisCircle1[i]=xAxisCircle1[i-1]+stp;
|
---|
507 | yAxisCircle1[i]=Math.sqrt(1.0-xAxisCircle1[i]*xAxisCircle1[i]);
|
---|
508 | xAxisCircle2[i]=xAxisCircle2[i-1]+stp;
|
---|
509 | yAxisCircle2[i]=-yAxisCircle1[i];
|
---|
510 | }
|
---|
511 | if(ncirc>maxPoints)maxPoints=ncirc;
|
---|
512 | }
|
---|
513 |
|
---|
514 | if(this.setEqualAxes){
|
---|
515 | mm++;
|
---|
516 | double maxpr = Fmath.maximum(polesReal);
|
---|
517 | double maxzr = Fmath.maximum(zerosReal);
|
---|
518 | double maxr = Math.max(maxpr, maxzr);
|
---|
519 | double maxpi = Fmath.maximum(polesImag);
|
---|
520 | double maxzi = Fmath.maximum(zerosImag);
|
---|
521 | double maxi = Math.max(maxpi, maxzi);
|
---|
522 | maxall = Math.max(maxr, maxi);
|
---|
523 |
|
---|
524 | double minpr = Fmath.minimum(polesReal);
|
---|
525 | double minzr = Fmath.minimum(zerosReal);
|
---|
526 | double minr = Math.min(minpr, minzr);
|
---|
527 | double minpi = Fmath.minimum(polesImag);
|
---|
528 | double minzi = Fmath.minimum(zerosImag);
|
---|
529 | double mini = Math.min(minpi, minzi);
|
---|
530 | minall = Math.min(minr, mini);
|
---|
531 | }
|
---|
532 |
|
---|
533 | int ii = 0;
|
---|
534 |
|
---|
535 | // Create array for data to be plotted
|
---|
536 | double[][] data = PlotGraph.data(mm, maxPoints);
|
---|
537 | boolean[] trim = new boolean[mm];
|
---|
538 | boolean[] minmax = new boolean[mm];
|
---|
539 | int[] line = new int[mm];
|
---|
540 | int[] point = new int[mm];
|
---|
541 |
|
---|
542 | // Fill above array with data to be plotted
|
---|
543 | ii=0;
|
---|
544 | if(this.nDeg>0){
|
---|
545 | line[ii]=0;
|
---|
546 | point[ii]=1;
|
---|
547 | trim[ii]=false;
|
---|
548 | minmax[ii]=true;
|
---|
549 | for(int i=0; i<nDeg; i++){
|
---|
550 | data[2*ii][i]=zerosReal[i];
|
---|
551 | data[2*ii+1][i]=zerosImag[i];
|
---|
552 | }
|
---|
553 | ii++;
|
---|
554 | }
|
---|
555 | if(this.dDeg>0){
|
---|
556 | line[ii]=0;
|
---|
557 | point[ii]=7;
|
---|
558 | trim[ii]=false;
|
---|
559 | minmax[ii]=true;
|
---|
560 | for(int i=0; i<dDeg; i++){
|
---|
561 | data[2*ii][i]=polesReal[i];
|
---|
562 | data[2*ii+1][i]=polesImag[i];
|
---|
563 | }
|
---|
564 | ii++;
|
---|
565 | }
|
---|
566 | if(this.zCircle){
|
---|
567 | line[ii]=3;
|
---|
568 | point[ii]=0;
|
---|
569 | trim[ii]=true;
|
---|
570 | minmax[ii]=false;
|
---|
571 | if(this.setUnitAxes)minmax[ii]=true;
|
---|
572 | for(int i=0; i<ncirc; i++){
|
---|
573 | data[2*ii][i]=xAxisCircle1[i];
|
---|
574 | data[2*ii+1][i]=yAxisCircle1[i];
|
---|
575 | }
|
---|
576 |
|
---|
577 | ii++;
|
---|
578 | line[ii]=3;
|
---|
579 | point[ii]=0;
|
---|
580 | trim[ii]=true;
|
---|
581 | minmax[ii]=false;
|
---|
582 | if(this.setUnitAxes)minmax[ii]=true;
|
---|
583 | for(int i=0; i<ncirc; i++){
|
---|
584 | data[2*ii][i]=xAxisCircle2[i];
|
---|
585 | data[2*ii+1][i]=yAxisCircle2[i];
|
---|
586 | }
|
---|
587 | ii++;
|
---|
588 | }
|
---|
589 | if(this.noReal){
|
---|
590 | line[ii]=0;
|
---|
591 | point[ii]=0;
|
---|
592 | trim[ii]=false;
|
---|
593 | minmax[ii]=true;
|
---|
594 | for(int i=0; i<2; i++){
|
---|
595 | data[2*ii][i]=xAxisIfRealZero[i];
|
---|
596 | data[2*ii+1][i]=yAxisIfRealZero[i];
|
---|
597 | }
|
---|
598 | ii++;
|
---|
599 | }
|
---|
600 | if(this.noImag){
|
---|
601 | line[ii]=0;
|
---|
602 | point[ii]=0;
|
---|
603 | trim[ii]=false;
|
---|
604 | minmax[ii]=true;
|
---|
605 |
|
---|
606 | for(int i=0; i<2; i++){
|
---|
607 | data[2*ii][i]=xAxisIfImagZero[i];
|
---|
608 | data[2*ii+1][i]=yAxisIfImagZero[i];
|
---|
609 | }
|
---|
610 | ii++;
|
---|
611 | }
|
---|
612 | if(this.setEqualAxes){
|
---|
613 | line[ii]=0;
|
---|
614 | point[ii]=0;
|
---|
615 | trim[ii]=false;
|
---|
616 | minmax[ii]=true;
|
---|
617 |
|
---|
618 | data[2*ii][0]=minall;
|
---|
619 | data[2*ii+1][0]=minall;
|
---|
620 | data[2*ii][1]=maxall;
|
---|
621 | data[2*ii+1][1]=maxall;
|
---|
622 | ii++;
|
---|
623 | }
|
---|
624 |
|
---|
625 | // Create an instance of PlotGraph with above data
|
---|
626 | PlotGraph pg = new PlotGraph(data);
|
---|
627 | pg.setLine(line);
|
---|
628 | pg.setPoint(point);
|
---|
629 | pg.setTrimOpt(trim);
|
---|
630 | pg.setMinMaxOpt(minmax);
|
---|
631 | pg.setXlowFac(0.0D);
|
---|
632 | pg.setYlowFac(0.0D);
|
---|
633 | pg.setGraphWidth((int)(this.scaleFactor*760.0));
|
---|
634 | pg.setGraphHeight((int)(this.scaleFactor*700.0));
|
---|
635 | pg.setXaxisLen((int)(this.scaleFactor*560.0));
|
---|
636 | pg.setYaxisLen((int)(this.scaleFactor*560.0));
|
---|
637 | pg.setYhigh((int)(this.scaleFactor*80.0));
|
---|
638 | pg.setNoOffset(true);
|
---|
639 |
|
---|
640 | switch(sORz){
|
---|
641 | case 0:
|
---|
642 | pg.setGraphTitle("Pole Zero Plot: "+title);
|
---|
643 | pg.setXaxisLegend("Real part of s or z");
|
---|
644 | pg.setYaxisLegend("Imaginary part of s or z");
|
---|
645 | break;
|
---|
646 | case 1:
|
---|
647 | pg.setGraphTitle("Pole Zero Plot (s-plane): "+title);
|
---|
648 | pg.setXaxisLegend("Real part of s");
|
---|
649 | pg.setYaxisLegend("Imaginary part of s");
|
---|
650 | break;
|
---|
651 | case 2:
|
---|
652 | pg.setGraphTitle("Pole Zero Plot (z-plane): "+title);
|
---|
653 | pg.setXaxisLegend("Real part of z");
|
---|
654 | pg.setYaxisLegend("Imaginary part of z");
|
---|
655 | break;
|
---|
656 | }
|
---|
657 |
|
---|
658 | // Plot poles and zeros
|
---|
659 | pg.plot();
|
---|
660 |
|
---|
661 | // Open and write an output file
|
---|
662 |
|
---|
663 | Complex[] numval = null;
|
---|
664 | Complex[] denval = null;
|
---|
665 |
|
---|
666 | FileOutput fout = new FileOutput("PoleZeroOutput.txt");
|
---|
667 |
|
---|
668 | fout.println("Output File for Program PlotPoleZero");
|
---|
669 | if(this.sORz==1)fout.println("An s-plane plot");
|
---|
670 | if(this.sORz==2)fout.println("A z-plane plot");
|
---|
671 | fout.dateAndTimeln(title);
|
---|
672 | fout.println();
|
---|
673 |
|
---|
674 | if(!this.noZeros){
|
---|
675 | numval = numerPoly.polyNomCopy();
|
---|
676 | fout.println("Numerator polynomial coefficients");
|
---|
677 | for(int i=0;i<=nDeg;i++){
|
---|
678 | fout.print(numval[i].toString());
|
---|
679 | if(i<nDeg){
|
---|
680 | fout.printcomma();
|
---|
681 | fout.printsp();
|
---|
682 | }
|
---|
683 | }
|
---|
684 | fout.println();
|
---|
685 | fout.println();
|
---|
686 | }
|
---|
687 |
|
---|
688 | if(!this.noPoles){
|
---|
689 | denval = denomPoly.polyNomCopy();
|
---|
690 | fout.println("Denominator polynomial coefficients");
|
---|
691 | for(int i=0;i<=dDeg;i++){
|
---|
692 | fout.print(denval[i].toString());
|
---|
693 | if(i<dDeg){
|
---|
694 | fout.printcomma();
|
---|
695 | fout.printsp();
|
---|
696 | }
|
---|
697 | }
|
---|
698 | fout.println();
|
---|
699 | fout.println();
|
---|
700 | }
|
---|
701 |
|
---|
702 | fout.println("Numerator roots (zeros)");
|
---|
703 | if(nDeg<1){
|
---|
704 | fout.println("No zeros");
|
---|
705 | }
|
---|
706 | else{
|
---|
707 | for(int i=0;i<nDeg;i++){
|
---|
708 | fout.print(Complex.truncate(numerRoots[i],6));
|
---|
709 | if(i<nDeg-1){
|
---|
710 | fout.printcomma();
|
---|
711 | fout.printsp();
|
---|
712 | }
|
---|
713 | }
|
---|
714 | fout.println();
|
---|
715 | fout.println();
|
---|
716 | }
|
---|
717 |
|
---|
718 | fout.println("Denominator roots (poles)");
|
---|
719 | if(dDeg<1){
|
---|
720 | fout.println("No poles");
|
---|
721 | }
|
---|
722 | else{
|
---|
723 | for(int i=0;i<dDeg;i++){
|
---|
724 | fout.print(Complex.truncate(denomRoots[i],6));
|
---|
725 | if(i<dDeg-1){
|
---|
726 | fout.printcomma();
|
---|
727 | fout.printsp();
|
---|
728 | }
|
---|
729 | }
|
---|
730 | fout.println();
|
---|
731 | fout.println();
|
---|
732 | }
|
---|
733 |
|
---|
734 | if(this.sORz==2){
|
---|
735 | fout.println("Denominator pole radial distances on the z-plane");
|
---|
736 | if(dDeg<1){
|
---|
737 | fout.println("No poles");
|
---|
738 | }
|
---|
739 | else{
|
---|
740 | for(int i=0;i<dDeg;i++){
|
---|
741 | fout.print(Fmath.truncate(denomRoots[i].abs(),6));
|
---|
742 | if(i<dDeg-1){
|
---|
743 | fout.printcomma();
|
---|
744 | fout.printsp();
|
---|
745 | }
|
---|
746 | }
|
---|
747 | }
|
---|
748 | fout.println();
|
---|
749 | fout.println();
|
---|
750 | }
|
---|
751 |
|
---|
752 | boolean testroots=true;
|
---|
753 | if(this.sORz==1){
|
---|
754 | for(int i=0;i<dDeg;i++){
|
---|
755 | if(denomRoots[i].getReal()>0)testroots=false;
|
---|
756 | }
|
---|
757 | if(testroots){
|
---|
758 | fout.println("All pole real parts are less than or equal to zero - stable system");
|
---|
759 | }
|
---|
760 | else{
|
---|
761 | fout.println("At least one pole real part is greater than zero - unstable system");
|
---|
762 | }
|
---|
763 | }
|
---|
764 |
|
---|
765 | if(this.sORz==2){
|
---|
766 | for(int i=0;i<dDeg;i++){
|
---|
767 | if(Fmath.truncate(denomRoots[i].abs(),6)>1.0)testroots=false;
|
---|
768 | }
|
---|
769 | if(testroots){
|
---|
770 | fout.println("All pole distances from the z-plane zero are less than or equal to one - stable system");
|
---|
771 | }
|
---|
772 | else{
|
---|
773 | fout.println("At least one pole distance from the z-plane zero is greater than one - unstable system");
|
---|
774 | }
|
---|
775 | }
|
---|
776 |
|
---|
777 | fout.println();
|
---|
778 | fout.println("End of file");
|
---|
779 | fout.close();
|
---|
780 |
|
---|
781 | return zerosAndPoles;
|
---|
782 |
|
---|
783 | }
|
---|
784 |
|
---|
785 | // Calculate roots and plot and write to text file
|
---|
786 | // No plot title given
|
---|
787 | public Complex[][] pzPlot(){
|
---|
788 | String title = "no file title provided";
|
---|
789 | return pzPlot(title);
|
---|
790 | }
|
---|
791 |
|
---|
792 | }
|
---|