%
%  This routine determines the controller to place the closed
%  loop poles at the desired locations by solving the 
%  Diophantine equations
%
%  Inputs: Gp = plant transfer function
%           p = an array containing the desired closed loop pole locations
%           m = order of desired controller
%  Outputs: Gc = desired controller transfer function or [] for errors
%
%   Notes:  n = degree of denominator of proper transfer function Gp
%           the number of poles must equal n+m
%           if m = n, a type 1 controller is designed (A0=0)
%           if m = n-1, a type 0 controller is designed (A0 not
%           deliberately set to 0)
%
function Gc = solve_diophantine(Gp,p,m)
%  
%  get the numerator (N) and denominator (D) of the plant
%
  [N,D] = tfdata(Gp,'v');
  n = length(D)-1;
%
%  we need n+m poles
%
  if (n+m ~= length(p))
      fprintf('ERROR! We need n (%d) + m (%d) >= #closed loop poles (%d) \n', n, m , length(p));
      Gc = [];
      return;
  end;
%
  if ( (m > n) || (m < n-1))
      fprintf('ERROR!  m = %d, n = %d : We need m = n-1 or m = n \n',m,n);
      Gc = [];
      return;
  end;
%
%  Construct the closed loop polynomial
%
  F = poly(p); 
%
%  For convenience, first make sure N and D are the same length
%
  nN = length(N);
  nn = n-nN;
  if (nn > 0) N = [zeros(1,nn) N]; end;
%
%  Now construct the S matrix
%
  Nt = fliplr(N)';
  Dt = fliplr(D)';
  start = 1;
  S = [];
  for i = 1:m+1
      index = 2*i-1;
      S(start:start+n,index) = Dt;
      S(start:start+n,index+1) = Nt;
      start = start+1;
  end;
% 
%  what we do next depends on whether or not we want a type 1
%  system or not.  If m = n, we want a type 1 system
%
  if (n == m)
%
     fprintf(' Making a type 1 system ... \n');
%
%    eliminate the first (A0) column from S
%
     S = S(:,2:end);
%
%    solve for the coefficients
%
     x = S\fliplr(F)';
%
%    get the A and B components
%
     A = [0];
     B = [x(1)];
     for i = 2:2:length(x)-1
       A = [x(i) A];
       B = [x(i+1) B];
     end;
%
  else  % do the type 0 system
%
%    solve for the coefficients
%
     x = S\fliplr(F)';
%
%    get out the A and B components
%
     A = [];
     B = [];
     for i = 1:2:length(x)
       A = [x(i) A];
       B = [x(i+1) B];
     end;
 end;
%
%  construct the controller transfer function
%
  Gc = tf(B,A);
%
%  find the closed loop transfer function
%
  Go = feedback(Gc*Gp,1);
  Go = minreal(Go);
%
%  Find the poles of the closed loop transfer function
%
  disp('The poles of the closed loop transfer function are : ');
  pole(Go)'
  return;
  
