function OpPreFil = bod_prefi_opt(Pla,C_ref,PFi_ref,C_sys,PFi_sys,OrdBal,Tol)
%function OptPreFi = bod_prefi_opt(Pla,C_ref,PFi_ref,C_sys,PFi_sys(,OrdBal,Tol))
% Digital Magnitude Optimum: optional pre-filter optimization (second step)
%                    in case that overshoot should be decreased more
% PLEASE NOTE: this function is based on LTI representation of all input
%              transfer functions; same sampling times are assumed
% Pla       LTI plant
% C_ref     LTI controller: reference system desired, e.g. bod - undel inp
% PFi_ref   LTI pre-filter: reference system desired, (proper method)
% C_sys     LTI controller: system to be optimized, e.g. bod - del inp
% PFi_sys   LTI pre-filter: system to be optimized, e.g. bod - del inp
% OrdBal     --> optional: desired prefilter order,      default: 2
% Tol        --> optional: tolerance of function balred, default: sqrt(eps)
% OpPreFil  LTI pre-filter optimized in order to replace PFi_sys
% ===> Since balred.m is called, see "help stabsepOptions" for problems.

% preparation: check for identical sampling times of all transer functions
T_cr=C_ref.TS; T_pr=PFi_ref.TS; T_cs=C_sys.TS; T_ps=PFi_sys.TS;
if     nargin>7  error('Too much input arguments');
elseif nargin<5  error('Not enough input arguments');
else   if nargin<7 Tol=sqrt(eps); end % default of minreal
       if nargin<6 OrdBal=2;  end     % default here, no order input
       if ~issiso(Pla)|~issiso(C_ref)|~issiso(PFi_ref)...
                      |~issiso(C_sys)|~issiso(PFi_sys)
       error('One or more input arguments 1 till 5 are not LTI type');end
       if T_cr~=T_pr||T_cr~=T_cs||T_cr~=T_ps
       error('One or more sampling times do not match each other');end
end
% if there is any dead time, so it is already included via z-transformation

ClL_u =series(PFi_ref,feedback(series(C_ref,Pla),1));
ClL_um=minreal(ClL_u,Tol);                % TOL as second argument possible
ClL_d =series(PFi_sys,feedback(series(C_sys,Pla),1));
ClL_dm=minreal(ClL_d,Tol);                % TOL as second argument possible

PFi_x=ClL_um/ClL_dm;                     % tf devision excludes dead time !
PFi_xm=minreal(PFi_x,Tol);               % TOL as second argument possible
FiEquOrd=series(PFi_xm,PFi_sys);         % both filter here
FiEquOrdm=minreal(FiEquOrd,Tol);         % TOL as second argument possible
OpPreFil=balred(FiEquOrdm,OrdBal); % action impossible if ord_num > ord_den
