function [out1,out2,out3]=trans(inp1,inp2,inp3,inp4,inp5)
%TRANS    All-purpose z-transform of transfer functions starting from
%         Laplace into z-domain: G(s)=za(s)/ne(s) - dead times separately!
%         >>>upgrading of c2d/c2dm<<< by consideration of the coupling of
%         controller and plant (T/H) as well as of the measuring methods (A/M/R)
%         LTI syntax optionally; menu driven input optionally;
%         output vectors of same order; real zeros in numerator;
%  ===>  Input/Output version by standard MATLAB syntax:
%            [znum,zden(,sdef)] = trans(za,ne,T(,m,code))
%  ===>  Input/Output version by LTI model MATLAB syntax:
%            [SY_Z(,sdef)]=trans(SY_P,T(,m,kode))
%  ATTENTION: applying LTI model features:
%         'InputDelay': interaction with real time delay "m" of TRANS
%                       (calculation of variants using same LTI model possible)
%         'Ts':         priority control regarding sampling time "T" of TRANS
%                       (case T<=0 only causes use of 'Ts' of the LTI model)
%  INPUT/OUTPUT ARGUMENTS:
%            za,znum:   numerator   in Laplace- resp. z domain
%            ne,zden:   denominator in    "      "    "   "
%            SY_P,SY_Z: LTI model of a SISO plant in Laplace- resp. z-domain
%            T:         sampling time in milliseconds
%  (,m,code) m:         optionally any >>>real<<< time delay
%                       >>>Default m=0<<<
%            code:      >>>menu switch off:<<< setting of coupling and measuring
%                       T/A     code=0;   H/M     code=2;   T/R     code=4;
%                       H/A     code=1;   T/M     code=3;   H/R     code=5;
%            T/H:   coupling:  (T) sampler;       (H) zero order sample&hold
%            A/M/R: measuring: (A) instantaneous; (M) mean value;
%                                                 (R) arithmetic mean value
%  (,sdef)   sdef: special case - optionally coding of entered plant
%                  for simulation using function "simu.m" of the BOD toolbox

%  KEY WORDS:      z-transform, modified z-transform, measuring, coupling,
%                  dead time, phase shift, menu driven, LTI model,
%                  sampler, zero order sample & hold, optionally,
%                  instantaneous value, mean value, arithmetic mean value

%  Copyright (c) 1997-20123. All Rights Reserved.
%                     Dr. Gert-Helge Geitner, TU Dresden,
%                     https://wwwpub.zih.tu-dresden.de/~geitner/ae_1_0e.htm
%  Reference regarding the application of the z-transform: Geitner, G.-H.:
%  "Entwurf digitaler Regler für elektrische Antriebe",
%  publisher: VDE-Verlag GmbH Berlin und Offenbach 1996, ISBN 3-8007-1847-2

AT01='Calculation of this order ratio of numerator / denominator not provided!';
FT01='Input argument error';
FT02='Output argument error';
FT03='Illegal >>>real<<< time delay!';
FT04='Invalid coding of coupling / measuring!';
FT05='No sampling time defined!';

if isa(inp1,'lti') LTI=1; else LTI=0; end
s1='inp1'; FeMe=0;
for i=1:nargin-1 s1=setstr(abs(s1)+[0 0 0 1]);
    if isa(eval(s1),'lti') FeMe=1; end; end
if LTI                                           %new syntax
   if FeMe~=0|nargin<2|nargin>4 error(FT01); end
   if nargout~=1 error(FT02); end
   [za,ne]=tfdata(inp1,'v'); T=inp2;
   if T<=0 T=get(inp1,'Ts');                     %priority control
           if T<=0 error(FT05); end; end
   if nargin==2 m=0; else m=inp3; end
   m=m+get(inp1,'InputDelay');                   %interaction
else
   if FeMe~=0|nargin<3|nargin>5 error(FT01); end %old syntax
   if nargout<2|nargout>3 error(FT02); end
   za=inp1; ne=inp2; T=inp3;
   if T<=0 error(FT05); end;
   if nargin==3 m=0; else m=inp4; end; end
if m<0 error(FT03); end

HISP=0;                        %auxiliary storage because of measuring variant R
if (~LTI&nargin<5)|(LTI&nargin<4)
   K=input('Coupling: ZeroOrderSample&Hold(any)/Sampler(1) =');
     if isempty(K)|K~=1 K=0; end   
   M=input...
   ('Measuring: InstantaneousValue(any)/MeanValue(1)/ArithmeticMeanValue(2)=');
if M==2 M=0; HISP=1; end       %handle as instantaneous value, but keep in mind
     if isempty(M)|M~=1 M=0; end
   z=K&~M;  n=~K&M; kode=M+n+(~(M|n|z));
else
   if LTI kode=inp4; else kode=inp5; end
   if kode==4|kode==5 kode=kode-4; HISP=1; end%keep in mind instantaneous handle
   if ((kode<0)|(kode>3)|(rem(kode,1)~=0)) error(FT04); end
   if      kode==0 z=1; n=0; M=0;
   elseif  kode==1 z=0; n=0; M=0;
   elseif  kode==2 z=0; n=1; M=1;
   else    kode=1; z=0; n=0; M=1; end; end %M für simu über sdef(3,4)

[i,j1]=size(za); [i,j2]=size(ne); zas=za; nes=ne; zSF=0;
nonull=find(za~=0); j1=j1-nonull(1)+1; %tfdata erzeugt gleiche Ordnung!!
if ((m~=0)&z&((j2-j1)<=1))
   if (j2-j1)==1&mod(m,T)==0 zSF=m/T; m=0; %Sonderfall: ganzzahlige Totzeit
   else disp(AT01); return; end; end

if z       za=conv(za,[1 0]);
elseif n   ne=conv(ne,[1 0]);  end

[a,b,c,d]=tf2ss(za,ne);
[a,b,c,dd]=c2dt(a,b,c,T,m);

if m==0   [znum,zden]=ss2tf(a,b,c,d,1);
else      [znum,zden]=ss2tf(a,b,c,dd,1);  end

%Hier "m" auswerten um echte führende Nullen im Zähler einzustellen
if znum(1)<eps                  %sprungfähige Strecken ausschließen
  i=fix(m/T)+1;
  for j=1:i znum(j)=0; end; end %Rundung Richtung Null

if z
   znum=deconv(znum,[1 -1]); s=size(znum);
       if (zden(s(2)+1)==0)  zden=deconv(zden,[1 0]); %Null abschneiden
       else  znum(s(2)+1)=0; end
   if zSF znum(1+zSF:end+zSF)=znum(1:end); znum(1:zSF)=0;
      while znum(end)==0 znum=deconv(znum,[1 0]); end %Null abschneiden
      szae=size(znum); snen=size(zden); m=zSF; %m für sdef setzen 
      if szae(2)>snen(2) zden(szae(2))=0; end; end
   znum=znum*T;
elseif n
   zden=deconv(zden,[1 -1]); s=size(zden); zden(s(2)+1)=0;
   znum=znum/T; end

%%% necessary for "simu.m" only, but without measurering variant R!
%%% because no HISP handover:
sdef(1,1)=j1; for i=1:j1   sdef(1,1+i)=zas(i); end
sdef(2,1)=j2; for i=1:j2   sdef(2,1+i)=nes(i); end
sdef(3,1)=T;  sdef(3,2)=m; sdef(3,3)=kode;     sdef(3,4)=M;
%%%

if HISP znum=conv(znum,[1 1])*0.5;        %arithmetic mean value measurering
        s=size(zden); zden(s(2)+1)=0; end %because based on instantaneous values
if LTI
   out1=tf(znum,zden,T,'Variable','z^-1'); out2=sdef; out3=0;
else
   out1=znum; out2=zden; out3=sdef; end
