function [acout,bc,cc,dc] = d2cm(a,b,c,d,Ts,method,w)
%D2CM	Conversion of discrete LTI systems to continuous-time.
%	[Ac,Bc,Cc,Dc] = D2CM(A,B,C,D,Ts,'method') converts the discrete-
%	time state-space system to continuous-time using 'method':
%	  'zoh'	        Convert to continuous time assuming a zero order
%	                hold on the inputs.
%	  'tustin'      Convert to continuous time using the bilinear 
%	                (Tustin) approximation to the derivative.
%	  'prewarp'     Convert to continuous time using the bilinear 
%	                (Tustin) approximation with frequency prewarping.
%	                Specify the critical frequency with an additional
%	                argument, i.e. D2CM(A,B,C,D,Ts,'prewarp',Wc)
%	  'matched'     Convert the SISO system to continuous time using
%	                the matched pole-zero method.
%
%	[NUMc,DENc] = D2CM(NUM,DEN,Ts,'method') converts the discrete-time
%	polynomial transfer function G(z) = NUM(z)/DEN(z) to continuous
%	time, G(s) = NUMc(s)/DENc(s), using 'method'.
%
%	Note:  'foh' is no longer available.
%
%	See also: D2C, and C2DM.

%	Clay M. Thompson  7-19-90
%	Copyright (c) 1986-93 by the MathWorks, Inc.

error(nargchk(3,7,nargin));

tol = 1.e-4; % Tolerance for 'foh' integrator and zero checking

tf = 0;
% --- Determine which syntax is being used ---
if (nargin==3),		% Transfer function without method, assume 'zoh'
  [num,den] = tfchk(a,b);
  Ts = c;
  method = 'zoh';
  [a,b,c,d] = tf2ss(num,den);
  tf = 1;

elseif (nargin==4),	% Transfer function with method.
  [num,den] = tfchk(a,b);
  Ts = c;
  method = d;
  [a,b,c,d] = tf2ss(num,den);
  tf = 1;

elseif (nargin==5),
  if isstr(d),		% Transfer function with method and prewarp const.
    [num,den] = tfchk(a,b);
    w = Ts;
    Ts = c;
    method = d;
    [a,b,c,d] = tf2ss(num,den); 
    tf = 1;
  else			% State space system without method, assume 'zoh'
    error(abcdchk(a,b,c,d));
    method = 'zoh';
  end

else			% State space system with method.
  error(abcdchk(a,b,c,d));

end
[nx,na] = size(a);
[nb,nu] = size(b);

% --- Determine conversion method ---
if method(1)=='z',	% Zero order hold approximation.
  [ac,bc] = d2c(a,b,Ts);
  cc = c; dc = d;

elseif method(1)=='f',	% First order hold approximation.
  error('Conversion to continuous time with ''foh'' is not available.')

elseif method(1)=='t',	% Tustin approximation.
  I = eye(nx);
  r = 2/Ts;
  P = inv(I + a);
  ac = r*(a-I)*P;
  bc = 2*P*b;
  cc = r*c*P;
  dc = d - c*P*b;

elseif method(1)=='p',	% Tustin approximation with frequency prewarping.
  if ~((nargin==5)|(nargin==7)),
    error('The critical frequency must be specified when using ''prewarp''.');
  end
  T = 2*tan(w*Ts/2)/w;		% Prewarp
  I = eye(nx);
  r = 2/T;
  P = inv(I + a);
  ac = r*(a-I)*P;
  bc = 2*P*b;
  cc = r*c*P;
  dc = d - c*P*b;
  
elseif method(1)=='m',	% Matched pole-zero approximation.
  [ny,nu] = size(d);
  if (ny>1)|(nu>1),
    error('System must be SISO for matched pole-zero method.');
  end
  if tf,
    z = roots(num); p = roots(den);
  else
    [z,p] = ss2zp(a,b,c,d,1);
  end
  z=esort(z); p = esort(p);
  pc = log(p)./Ts;
  zc = zeros(length(z),1);
  zinf = (abs(z+1)<sqrt(eps));	% Fuzzy compare (z==-1)
  if ~isempty(zc),
    zc(~zinf) = log(z(~zinf))./Ts;
    zc(zinf) = inf*ones(length(z(zinf)),1);
  end
  [ac,bc,cc,dc] = zp2ss(zc,pc,1);

  % Match D.C. gain or gain at s=1 for singular systems.
  if any(abs(p-1)<sqrt(eps)), % Match gain at s = 1.
    w = exp(sqrt(-1)*Ts);
    if tf,
      kd = abs(polyval(num,w))/abs(polyval(den,w));
    else
      kd = abs(c/(eye(nx)*w-a)*b + d);
    end
    kc = cc/(eye(nx)-ac)*bc + dc;
  else
    if tf,
      kd = sum(num')'/sum(den);
    else
      kd = c/(eye(nx)-a)*b + d;
    end
    kc = -cc/ac*bc + dc;
  end
  km = sqrt(abs(kd/kc));
  sm = sign(kd/kc);
  bc = bc.*km;
  cc = cc.*km.*sm;
  dc = dc.*km.*km.*sm;

else
  error('Conversion method is unknown.');

end

if nargout==0,		% Compare Bode or Singular value plots
  [ny,nc] = size(c);
  if (ny==1)&(nu==1),	% Plot Bode plots
    [magd,phased,wd] = dbode(a,b,c,d,Ts,1);
    [magc,phasec,wc] = bode(ac,bc,cc,dc,1);
    semilogx(wd,20*log10(magd),'-',wc,20*log10(magc),'--')
    xlabel('Frequency (rad/sec)'), ylabel('Gain dB')
    title('D2CM comparison plot')
  else
    [svd,wd] = dsigma(a,b,c,d,Ts);
    [svc,wc] = sigma(ac,bc,cc,dc);
    semilogx(wd,20*log10(svd),'-',wc,20*log10(svc),'--')
    xlabel('Frequency (rad/sec)'), ylabel('Singular Values dB')
    title('D2CM comparison plot')
  end
  return
end

if tf,		% Convert to TF form for output
  [ac,bc] = ss2tf(ac,bc,cc,dc,1);
end

acout = ac;
