home *** CD-ROM | disk | FTP | other *** search
- program freqres(input,output);
- (* Program evaluates magnitude in decibels and angle in degrees of a *)
- (* rational function K*N(s)/D(s) for s = jw over a desired range of w. *)
-
- type vector = array[0..10] of real;
- var coefn,coefd: vector;
- gain,freqlo,freqhi,freq,rmag,jmag,
- rmagn,jmagn,rmagd,jmagd,cmag,angle,spacing: real;
- ndegree,ddegree,npts: integer;
-
- procedure readin(var a1: vector; n1: integer);
- (* Reads in polynomial coefficients from the keyboard. *)
-
- var i: integer;
-
- begin
- for i := 0 to n1 do
- begin
- write('Input the ',i,' coefficent: ');
- readln(a1[i]);
- end;
- writeln('The polynomial coefficients are:');
- writeln;
- for i := 0 to n1 do
- begin
- write(a1[i]:6:3,' ');
- end;
- writeln;
- end;
-
- procedure decade(npts1: integer; var delta1: real);
- (* Sets frequency increment so as to get uniform spacing of points on *)
- (* a log(frequency) scale for npts1 = 2^i points per decade. *)
-
- var i,j,n1: integer;
-
- begin
- i := 0;
- n1 := npts1;
- while n1 >= 2 do
- begin
- n1 := n1 div 2;
- i := i + 1;
- end;
- delta1 := 10.0;
- for j := 1 to i do
- begin
- delta1 := sqrt(delta1);
- end;
- end;
-
- procedure evalpoly(coef: vector; w1,w2: real; var b1,b2: real; n1: integer);
- (* Evaluates a polynomial N(s) in the form *)
- (* A(0) + A(1)s + A(2)s^2 +...+A(n1)s^n1 for s = w1 + jw2. In this *)
- (* program w1 = 0. *)
-
- var a1,a2: vector;
- i: integer;
-
- begin
- a1[0] := 1.0;
- a2[0] := 0.0;
- b1 := a1[0]*coef[0];
- b2 := a2[0]*coef[0];
- for i := 1 to n1 do
- begin
- a1[i] := w1*a1[i-1] - w2*a2[i-1]; (* real part of w^i *)
- a2[i] := w1*a2[i-1] + w2*a1[i-1]; (* imag part of w^i *)
- b1 := b1 + a1[i]*coef[i]; (* real part of trunc polynomial *)
- b2 := b2 + a2[i]*coef[i]; (* imag part of trunc polynomial *)
- end;
- end;
-
- procedure evaltf(a1,a2,b1,b2: real; var d1,d2: real);
- (* Evaluates a complex quotient d1 + jd2 = (a1 + ja2)/(b1 + jb2). *)
-
- var d: real;
-
- begin
- d := b1*b1 + b2*b2;
- d1 := (a1*b1 + a2*b2)/d;
- d2 := (a2*b1 - a1*b2)/d;
- end;
-
- procedure rectpol(a1,a2: real; var cmag1,angle1: real);
- (* Converts rectangular form a1 + ja2 to polar form. *)
-
- var eta: real;
-
- begin
- cmag1 := sqrt(a1*a1 + a2*a2);
- if (a1 = 0.0) and (a2 = 0.0) then
- angle1 := 0.0;
- if (a1 = 0.0) and (a2 > 0.0) then
- angle1 := 90.0;
- if (a1 = 0.0) and (a2 < 0.0) then
- angle1 := -90.0;
- if abs(a1) > 0.0 then
- eta := arctan(a2/a1)*57.296;
- if a1 > 0 then
- angle1 := eta;
- if (a1 < 0.0) and (a2 >= 0.0) then
- angle1 := eta + 180.0;
- if (a1 < 0.0) and (a2 < 0.0) then
- angle1 := eta - 180.0;
- end;
-
- begin (* main *)
- write('Input gain constant: ');
- readln(gain);
- writeln;
- write('Input numerator and denominator degree: ');
- readln(ndegree,ddegree);
- writeln;
- write('Input lowest and highest frequencies: ');
- readln(freqlo,freqhi);
- writeln;
- writeln('Input number of points per decade (powers of 2): ');
- readln(npts);
- writeln;
- decade(npts,spacing);
- writeln('Input numerator coefficients in response to prompt:');
- writeln;
- readin(coefn,ndegree);
- writeln('Input denominator coefficients in response to prompt:');
- writeln;
- readin(coefd,ddegree);
- writeln(' rad/s ',' decibels ',' degrees ');
- writeln;
- freq := freqlo;
- while freq < freqhi do
- begin
- evalpoly(coefn,0,freq,rmagn,jmagn,ndegree);
- evalpoly(coefd,0,freq,rmagd,jmagd,ddegree);
- evaltf(rmagn,jmagn,rmagd,jmagd,rmag,jmag);
- rectpol(rmag,jmag,cmag,angle);
- writeln(freq:6:1,' ',20*ln(gain*cmag)/ln(10):8:3,' ',angle:5:2);
- freq := freq*spacing;
- end;
- end.