// bodetf.r
//____________________________________________________________________
//  This does a Bode plot of a transfer function H(s) =N(s)/D(s),
//  where the coefficients of N(s) and D(s) starting with the 
//  highest power of s are in the vector NUM and DEN respectively.  
//  The argument W is an optional vector specifying what decades 
//  of frequency to plot and how many points (similar to the 
//  arguments of function logspace).  The first element is the 
//  starting decade, the second element is the ending decade 
//  and the last element is the number of points to plot.
//
//  Example:  To obtain the Bode plot of (s+2)/(s^2 + 10s + 25) the 
//  command is:
//
//		> bodetf([1,2],[1,10,25])
//
//	or
//
//		> bodetf([1,2],[1,10,25],[-1,3,200])
//
//	to plot the same thing from f=10^(-1) to 10^2 using 200 points.
//
//	This function was written by Rob Frohne, at Walla Walla College. 
//			His e-mail address is frohro@wwc.edu.
//
//____________________________________________________________________

bodetf = function ( NUM, DEN, W )
{
  global(pi);
  local(f,mag,phase,H,s,i,top,bottom,nargs,dln,dld,dl,du,dud,dun,ymin,ymax);

  if ((size(NUM)[2] ==1) && (size(DEN)[2] ==1)) 
  {
    mag = 20.*log10(NUM./DEN);
    fprintf("stdout",...
    "There is no frequency variation.  The gain in dB is %f. \n",mag);
  else
    i=sqrt(-1);
    if (nargs == 3)
    {
      f = logspace(W[1],W[2],W[3]);
      top = zeros(1,W[3]);
      bottom = zeros(1,W[3]);
    else 
      rfile roots
      if (size(DEN)[2] >=2) {
	zero_loc = roots(DEN);
	dld = min(abs(zero_loc));
	dud = max(abs(zero_loc));
      }
      if (size(NUM)[2] >= 2) {
	pole_loc = roots(NUM);
	dln = min(abs(pole_loc));
	dun = max(abs(pole_loc));
      }			
      if(size(DEN)[2] ==1) {
	dl = min(dln);
	du = max(dun);
      else
	if(size(NUM)[2]==1) {
	  dl = min(dld); 
	  du = max(dud);
	else
	  dl = min([dln,dld]);
	  du = max([dun,dud]);
	}
      }
      f=logspace(round(log10(dl))-2,round(log10(du))+2,200);
      top=zeros(1,200);
      bottom=zeros(1,200);
    }

    s = i.*2.*pi.*f;

    for (n in 1:size(NUM)[2])
    {
      top = NUM[n].*s.^(size(NUM)[2]-n) .+ top;
    }

    for (n in 1:size(DEN)[2])
    {
      bottom = DEN[n].*s.^(size(DEN)[2]-n) .+ bottom;
    }

    H=top./bottom;
    mag=[f',20.*log10(abs(H))'];
    phase=[f',180./pi.*atan2(imag(H),real(H))'];

    plstart(1,2);
    pltitle("Bode Plot");
    plstyle("line");
    plegend();
    plaxis("log","");

    ymin = 10.*floor(min(mag[;2])./10);
    ymax =  10.*ceil(max(mag[;2])./10);
    plimits(,,ymin,ymax,,);
    xlabel("Frequency (Hz)");
    ylabel("Gain (dB)");
    plot(mag,1);

    subplot(2);
    plegend();
    plaxis("log","");
    xlabel("Frequency (Hz)");
    ylabel("Phase (degrees)");
    plot(phase,1);
  }
};
