function OptPreFi = bo_prefi_op(Pla,C_bo_u,C_bo_d,PFi_bo_d,OrdBal,Tol)
%function OptPreFi = bo_prefi_op(Pla,C_bo_u,C_bo_d,PFi_bo_d(,OrdBal,Tol))
% Magnitude Optimum: optional prefilter optimization as a second step
%                    in case that overshoot should be decreased more
% PLEASE NOTE: this function is based on LTI representation of all 
%              transfer functions - in contrast to bo_u_gen / bo_d_gen
% Pla        LTI plant
% C_bo_u     LTI controller - based on results of function bo_u_gen(02)
% C_bo_d     LTI controller - based on results of function bo_d_gen(02)
% PFi_bo_d   LTI pre-filter - based on results of function bo_d_gen(02)
% OrdBal     --> optional: desired prefilter order, default: 4
% Tol        --> optional: tolerance of function balred, default: sqrt(eps)
% OptPreFi   LTI pre-filter optimized in order to replace PFi_bo_d

if     nargin>6  error('Too much input arguments');
elseif nargin<4  error('Not enough input arguments'); 
else   if nargin<6 Tol=sqrt(eps); end % default of minreal
       if nargin<5 OrdBal=4;  end     % default here, no order input
       if ~issiso(Pla)|~issiso(C_bo_u)|~issiso(C_bo_d)|~issiso(PFi_bo_d)
       error('One or more input arguments 1 till 4 are not LTI type');end
end
ToSwi=get(Pla,'ioDelay');                 % system features dead time ?
if ToSwi~=0%MATLAB cannot handle delay annulment in tf division - see below
    Tt_num=[-(1/120)*ToSwi^3  0.1*ToSwi^2  -0.5*ToSwi  1]; %Pade 3. order
    Tt_den=[+(1/120)*ToSwi^3  0.1*ToSwi^2   0.5*ToSwi  1];
    set(Pla,'ioDelay',0);              % reset dead time in LTI plant model
    Pla=series(Pla,tf(Tt_num,Tt_den)); % use Pade approximation instead
end

ClL_u =feedback(series(C_bo_u,Pla),1);
ClL_um=minreal(ClL_u,Tol);                % TOL as second argument possible
ClL_d=series(PFi_bo_d,feedback(series(C_bo_d,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_bo_d);        % both filter here
FiEquOrdm=minreal(FiEquOrd,Tol);         % TOL as second argument possible
OptPreFi=balred(FiEquOrdm,OrdBal); % action impossible if ord_num > ord_den

