%test_VAcPlant(t, ID) is an example, which shows how to use the VAModel in MATLAB
%In this example, Luyben's multi-loop control structure is implemented and tested
%Eight process disturbances are available and transients are generated at the end of simulation
%On a PIII-1GHz PC, the VA plant model runs approaximately 80 times faster than the real time
%To use this example:
%       t sets the simulation time (in munite)
%       ID is an integer selected between 0 and 8
%           0: no disturbance
%           1: setpoint of the reactor outlet temperature decreases 8 degC (from 159 to 151)
%           2: setpoint of the reactor outlet temperature increases 6 degC (from 159 to 165)
%           3: setpoint of the H2O composition in the column bottom increases 9% (from 9% to 18%)
%           4: the vaporizer liqiud inlet flowrate increases 0.44 kmol/min (from 2.2 to 2.64)
%           5: HAc fresh feed stream lost for 5 minutes
%           6: O2 fresh feed stream lost for 5 minutes
%           7: C2H6 composition changes from 0.001 to 0.003 in the C2H4 fresh feed stream
%           8: column feed lost for 5 minutes
%       Note: in this example, all the disturbances occur at 10 minute after the simulation starts
%-----------------------------------------------------------------------------
%Copyright: Rong Chen and Kedar David, June 2002
%-----------------------------------------------------------------------------
function test_VAcPlant(minute,selected_ID)

%-----------------------------------------------------------------------------
close all
format short g
%-----------------------------------------------------------------------------

%-----------------------------------------------------------------------------
%The recommended simulation sampling time is 1/3 second, which corresponds to a frequency of 180 samples in one minute
model_sampling_frequency=180;
%The recommended historical data sampling time is 1 minute, which corresponds to a frequency of 1 sample in one minute
storage_sampling_frequency=1;
%The recommended display sampling time is 1 minute, which corresponds to a frequency of 1 sample in one minute
display_sampling_frequency=1;
%-----------------------------------------------------------------------------

%-----------------------------------------------------------------------------
% Inintialze process states and MV's
% 246 state variables
states=zeros(246,1);
% 26 manipulated variables
MVs=zeros(26,1);
% set the current process time to 0 (in minute)
time=0;
% set initialization flag 1
is_initial=1;
% set disturbance_ID 0
disturbance_ID=0;
% get the base operation
[dstatedt,states,MVs,y_ss]=VAModel(states,MVs,time,is_initial,disturbance_ID);
%-----------------------------------------------------------------------------

%-----------------------------------------------------------------------------
% Implement Luyben and Tyreus's control structure for the VA plant
% Note that: in this example,
%   1. for each transmitter, a 3 second time lag is used
%   2. for two analyzer transmitters (on the gas recycle and column bottom), a 10 minute deadtime is used
%   3. for other transmitters, no deadtime is used
%   4. for three controllers using analyzers on the gas recycle and column bottom, a 10 minute sampling time is used
%   5. for other controllers, a 1 second sampling time is used
%   6. for each transmitter, a 1 second sampling time is used
%-----------------------------------------------------------------------------
transmitter_lag=0.05; %in minute
transmitter_deadtime=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 10 0 10 0 0 0 0 0 0]; %in minute
transmitter_sampling_frequency=[60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60];
controller_sampling_frequency=[60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 0.1 0.1 60 0.1 60 60 60 60 60 60];
%-----------------------------------------------------------------------------
%transmitter and controller initialization
%SP: setpoint (not scaled)
%K: controller gain which is dimentionless
%Ti: reset time (in minute)
%act: 1 if positive process gain, -1 if negative process gain
%mode: 1 for automatic, 2 for manual
%Ponly: 1 for proportional only control, 0 for PI control
%hc: controller sampling time (in minute), should be 1/"controller_sampling_frequency"
%ht: transmitter sampling time (in minute), should be 1/"transmitter_sampling_frequency"
%uLO: low limit of MV
%uHI: high limit of MV
%ded: should be "transmitter_deadtime" defined above
%tau: should be "transmitter_lag" defined above
%yLO: low limit of measurement
%yHI: high limit of measurement
%Nded: measurement deadtime storage, which should be 1+transmitter_deadtime*transmitter_sampling_frequency
%Ntau: measurement time constant storage, which should be 1 all the time
%-----------------------------------------------------------------------------
%MV1: F_O2 - O2 composition
SP_O2=0.075;
K_O2=5;
Ti_O2=10;
act_O2=1;
mode_O2=1;
Ponly_O2=0;
ht_O2=1/transmitter_sampling_frequency(1);
hc_O2=1/controller_sampling_frequency(1);
uLO_O2=0;
uHI_O2=2.268;
ded_O2=transmitter_deadtime(1);
tau_O2=transmitter_lag;
yLO_O2=0;
yHI_O2=0.2;
Nded_O2=1+transmitter_deadtime(1)*transmitter_sampling_frequency(1);
Ntau_O2=1;
xxx_O2(1)= (y_ss(37) -yLO_O2) / (yHI_O2 -yLO_O2);
for i=2:Nded_O2
    xxx_O2(i)=xxx_O2(1);
end
for i=1:Ntau_O2
    yyy_O2(i)= xxx_O2(Nded_O2);
end
xi_O2= (MVs(1) - uLO_O2) /(uHI_O2 -uLO_O2)-K_O2*act_O2*((SP_O2-yLO_O2)/(yHI_O2-yLO_O2)-yyy_O2(Ntau_O2));
%-----------------------------------------------------------------------------
%controller initialization
%MV2: F_C2H4 - Recycle Pressure
SP_C2H4=128;
K_C2H4=0.3;
Ti_C2H4=20;
act_C2H4=1;
mode_C2H4=1;
Ponly_C2H4=0;
ht_C2H4=1/transmitter_sampling_frequency(2);
hc_C2H4=1/controller_sampling_frequency(2);
uLO_C2H4=0;
uHI_C2H4=7.56;
ded_C2H4=transmitter_deadtime(2);
tau_C2H4=transmitter_lag;
yLO_C2H4=0;
yHI_C2H4=200;
Nded_C2H4=1+transmitter_deadtime(2)*transmitter_sampling_frequency(2);
Ntau_C2H4=1;
xxx_C2H4(1)= (y_ss(12) -yLO_C2H4) / (yHI_C2H4 -yLO_C2H4);
for i=2:Nded_C2H4
    xxx_C2H4(i)= xxx_C2H4(1);
end
for i=1:Ntau_C2H4
    yyy_C2H4(i)= xxx_C2H4(Nded_C2H4);
end
xi_C2H4= (MVs(2) - uLO_C2H4) /(uHI_C2H4 -uLO_C2H4)-K_C2H4*act_C2H4*((SP_C2H4-yLO_C2H4)/(yHI_C2H4-yLO_C2H4)-yyy_C2H4(Ntau_C2H4));
%-----------------------------------------------------------------------------
%controller initialization
%MV3: HAc feed stream - HAc tank level
SP_HAc=0.5;
K_HAc=2;
Ti_HAc=100;
act_HAc=1;
mode_HAc=1;
Ponly_HAc=1;
ht_HAc=1/transmitter_sampling_frequency(3);
hc_HAc=1/controller_sampling_frequency(3);
uLO_HAc=0;
uHI_HAc=4.536;
ded_HAc=transmitter_deadtime(3);
tau_HAc=transmitter_lag;
yLO_HAc=0;
yHI_HAc=1;
Nded_HAc=1+transmitter_deadtime(3)*transmitter_sampling_frequency(3);
Ntau_HAc=1;
xxx_HAc(1)= (y_ss(23) -yLO_HAc) / (yHI_HAc -yLO_HAc);
for i=2:Nded_HAc
    xxx_HAc(i)= xxx_HAc(1);
end
for i=1:Ntau_HAc
    yyy_HAc(i)= xxx_HAc(Nded_HAc);
end
xi_HAc= (MVs(3) - uLO_HAc) /(uHI_HAc -uLO_HAc)-K_HAc*act_HAc*((SP_HAc-yLO_HAc)/(yHI_HAc-yLO_HAc)-yyy_HAc(Ntau_HAc));
%-----------------------------------------------------------------------------
%controller initialization
%MV4: Qv - Level
SP_LevelVap=0.7;
K_LevelVap=0.1;
Ti_LevelVap=30;
act_LevelVap=-1;
mode_LevelVap=1;
Ponly_LevelVap=0;
ht_LevelVap=1/transmitter_sampling_frequency(4);
hc_LevelVap=1/controller_sampling_frequency(4);
uLO_LevelVap=0;
uHI_LevelVap=1433400;
ded_LevelVap=transmitter_deadtime(4);
tau_LevelVap=transmitter_lag;
yLO_LevelVap=0;
yHI_LevelVap=1;
Nded_LevelVap=1+transmitter_deadtime(4)*transmitter_sampling_frequency(4);
Ntau_LevelVap=1;
xxx_LevelVap(1)= (y_ss(2) -yLO_LevelVap) / (yHI_LevelVap -yLO_LevelVap);
for i=2:Nded_LevelVap
    xxx_LevelVap(i)= xxx_LevelVap(1);
end
for i=1:Ntau_LevelVap
    yyy_LevelVap(i)= xxx_LevelVap(Nded_LevelVap);
end
xi_LevelVap= (MVs(4) - uLO_LevelVap) /(uHI_LevelVap -uLO_LevelVap)-K_LevelVap*act_LevelVap*((SP_LevelVap-yLO_LevelVap)/(yHI_LevelVap-yLO_LevelVap)-yyy_LevelVap(Ntau_LevelVap));
%-----------------------------------------------------------------------------
%controller initialization
%MV5: F_Vaporizer - Vaporizer Pressure
SP_PresVap=128;
K_PresVap=5;
Ti_PresVap=10;
act_PresVap=-1;
mode_PresVap=1;
Ponly_PresVap=0;
ht_PresVap=1/transmitter_sampling_frequency(5);
hc_PresVap=1/controller_sampling_frequency(5);
uLO_PresVap=0;
uHI_PresVap=50;
ded_PresVap=transmitter_deadtime(5);
tau_PresVap=transmitter_lag;
yLO_PresVap=0;
yHI_PresVap=200;
Nded_PresVap=1+transmitter_deadtime(5)*transmitter_sampling_frequency(5);
Ntau_PresVap=1;
xxx_PresVap(1)= (y_ss(1) -yLO_PresVap) / (yHI_PresVap -yLO_PresVap);
for i=2:Nded_PresVap
    xxx_PresVap(i)= xxx_PresVap(1);
end
for i=1:Ntau_PresVap
    yyy_PresVap(i)= xxx_PresVap(Nded_PresVap);
end
xi_PresVap= (MVs(5) - uLO_PresVap) /(uHI_PresVap -uLO_PresVap)-K_PresVap*act_PresVap*((SP_PresVap-yLO_PresVap)/(yHI_PresVap-yLO_PresVap)-yyy_PresVap(Ntau_PresVap));
%-----------------------------------------------------------------------------
%controller initialization
%MV6: Q_heater - Vaporizer Outlet Temperature
SP_ReactorInletTemp=150;
K_ReactorInletTemp=1;
Ti_ReactorInletTemp=5;
act_ReactorInletTemp=1;
mode_ReactorInletTemp=1;
Ponly_ReactorInletTemp=0;
ht_ReactorInletTemp=1/transmitter_sampling_frequency(6);
hc_ReactorInletTemp=1/controller_sampling_frequency(6);
uLO_ReactorInletTemp=0;
uHI_ReactorInletTemp=15000;
ded_ReactorInletTemp=transmitter_deadtime(6);
tau_ReactorInletTemp=transmitter_lag;
yLO_ReactorInletTemp=120;
yHI_ReactorInletTemp=170;
Nded_ReactorInletTemp=1+transmitter_deadtime(6)*transmitter_sampling_frequency(6);
Ntau_ReactorInletTemp=1;
xxx_ReactorInletTemp(1)= (y_ss(4) -yLO_ReactorInletTemp) / (yHI_ReactorInletTemp -yLO_ReactorInletTemp);
for i=2:Nded_ReactorInletTemp
    xxx_ReactorInletTemp(i)= xxx_ReactorInletTemp(1);
end
for i=1:Ntau_ReactorInletTemp
    yyy_ReactorInletTemp(i)= xxx_ReactorInletTemp(Nded_ReactorInletTemp);
end
xi_ReactorInletTemp= (MVs(6) - uLO_ReactorInletTemp) /(uHI_ReactorInletTemp -uLO_ReactorInletTemp)-K_ReactorInletTemp*act_ReactorInletTemp*((SP_ReactorInletTemp-yLO_ReactorInletTemp)/(yHI_ReactorInletTemp-yLO_ReactorInletTemp)-yyy_ReactorInletTemp(Ntau_ReactorInletTemp));
%-----------------------------------------------------------------------------
%controller initialization
%MV7: T_Shell - T_RCTOUT
SP_TRCT=159.17;
K_TRCT=3;
Ti_TRCT=10;
act_TRCT=1;
mode_TRCT=1;
Ponly_TRCT=0;
ht_TRCT=1/transmitter_sampling_frequency(7);
hc_TRCT=1/controller_sampling_frequency(7);
uLO_TRCT=110;
uHI_TRCT=150;
ded_TRCT=transmitter_deadtime(7);
tau_TRCT=transmitter_lag;
yLO_TRCT=0;
yHI_TRCT=200;
Nded_TRCT=1+transmitter_deadtime(7)*transmitter_sampling_frequency(7);
Ntau_TRCT=1;
xxx_TRCT(1)= (y_ss(5)-yLO_TRCT) / (yHI_TRCT -yLO_TRCT);
for i=2:Nded_TRCT
    xxx_TRCT(i)= xxx_TRCT(1);
end
for i=1:Ntau_TRCT
    yyy_TRCT(i)= xxx_TRCT(Nded_TRCT);
end
xi_TRCT= (MVs(7) - uLO_TRCT) /(uHI_TRCT -uLO_TRCT)-K_TRCT*act_TRCT*((SP_TRCT-yLO_TRCT)/(yHI_TRCT-yLO_TRCT)-yyy_TRCT(Ntau_TRCT));
%-----------------------------------------------------------------------------
%controller initialization
%MV8: Separator Liquid Exit - Separator Level
SP_LevelSep=0.5;
K_LevelSep=5;
Ti_LevelSep=100;
act_LevelSep=-1;
mode_LevelSep=1;
Ponly_LevelSep=1;
ht_LevelSep=1/transmitter_sampling_frequency(8);
hc_LevelSep=1/controller_sampling_frequency(8);
uLO_LevelSep=0;
uHI_LevelSep=4.536;
ded_LevelSep=transmitter_deadtime(8);
tau_LevelSep=transmitter_lag;
yLO_LevelSep=0;
yHI_LevelSep=1;
Nded_LevelSep=1+transmitter_deadtime(8)*transmitter_sampling_frequency(8);
Ntau_LevelSep=1;
xxx_LevelSep(1)= (y_ss(9)-yLO_LevelSep) / (yHI_LevelSep -yLO_LevelSep);
for i=2:Nded_LevelSep
    xxx_LevelSep(i)= xxx_LevelSep(1);
end
for i=1:Ntau_LevelSep
    yyy_LevelSep(i)= xxx_LevelSep(Nded_LevelSep);
end
xi_LevelSep= (MVs(8) - uLO_LevelSep) /(uHI_LevelSep -uLO_LevelSep)-K_LevelSep*act_LevelSep*((SP_LevelSep-yLO_LevelSep)/(yHI_LevelSep-yLO_LevelSep)-yyy_LevelSep(Ntau_LevelSep));
%-----------------------------------------------------------------------------
%controller initialization
%MV9: T_Shell_Separator - Separator Liquid Temperature
SP_TempSep=40;
K_TempSep=5;
Ti_TempSep=20;
act_TempSep=-1;
mode_TempSep=1;
Ponly_TempSep=0;
ht_TempSep=1/transmitter_sampling_frequency(9);
hc_TempSep=1/controller_sampling_frequency(9);
uLO_TempSep=0;
uHI_TempSep=80;
ded_TempSep=transmitter_deadtime(9);
tau_TempSep=transmitter_lag;
yLO_TempSep=0;
yHI_TempSep=80;
Nded_TempSep=1+transmitter_deadtime(9)*transmitter_sampling_frequency(9);
Ntau_TempSep=1;
xxx_TempSep(1)= (y_ss(10)-yLO_TempSep) / (yHI_TempSep -yLO_TempSep);
for i=2:Nded_TempSep
    xxx_TempSep(i)= xxx_TempSep(1);
end
for i=1:Ntau_TempSep
    yyy_TempSep(i)= xxx_TempSep(Nded_TempSep);
end
xi_TempSep= (MVs(9) - uLO_TempSep) /(uHI_TempSep -uLO_TempSep)-K_TempSep*act_TempSep*((SP_TempSep-yLO_TempSep)/(yHI_TempSep-yLO_TempSep)-yyy_TempSep(Ntau_TempSep));
%-----------------------------------------------------------------------------
%controller initialization
%MV10: Separator Vapor Exit is fixed at 16.1026 kmol/min
%-----------------------------------------------------------------------------
%controller initialization
%MV11: Q_Compressor_Cooler - Compressor Outlet Temperature (80degC)
SP_CompOutletTemp=80;
K_CompOutletTemp=1;
Ti_CompOutletTemp=5;
act_CompOutletTemp=-1;
mode_CompOutletTemp=1;
Ponly_CompOutletTemp=0;
ht_CompOutletTemp=1/transmitter_sampling_frequency(11);
hc_CompOutletTemp=1/controller_sampling_frequency(11);
uLO_CompOutletTemp=0;
uHI_CompOutletTemp=50000;
ded_CompOutletTemp=transmitter_deadtime(11);
tau_CompOutletTemp=transmitter_lag;
yLO_CompOutletTemp=70;
yHI_CompOutletTemp=90;
Nded_CompOutletTemp=1+transmitter_deadtime(11)*transmitter_sampling_frequency(11);
Ntau_CompOutletTemp=1;
xxx_CompOutletTemp(1)= (y_ss(11) -yLO_CompOutletTemp) / (yHI_CompOutletTemp -yLO_CompOutletTemp);
for i=2:Nded_CompOutletTemp
    xxx_CompOutletTemp(i)= xxx_CompOutletTemp(1);
end
for i=1:Ntau_CompOutletTemp
    yyy_CompOutletTemp(i)= xxx_CompOutletTemp(Nded_CompOutletTemp);
end
xi_CompOutletTemp= (MVs(11) - uLO_CompOutletTemp) /(uHI_CompOutletTemp -uLO_CompOutletTemp)-K_CompOutletTemp*act_CompOutletTemp*((SP_CompOutletTemp-yLO_CompOutletTemp)/(yHI_CompOutletTemp-yLO_CompOutletTemp)-yyy_CompOutletTemp(Ntau_CompOutletTemp));
%-----------------------------------------------------------------------------
%controller initialization
%MV12: Absorber Liquid Exit - Absorber Level
SP_LevelAbs=0.5;
K_LevelAbs=5;
Ti_LevelAbs=100;
act_LevelAbs=-1;
mode_LevelAbs=1;
Ponly_LevelAbs=1;
ht_LevelAbs=1/transmitter_sampling_frequency(12);
hc_LevelAbs=1/controller_sampling_frequency(12);
uLO_LevelAbs=0;
uHI_LevelAbs=4.536;
ded_LevelAbs=transmitter_deadtime(12);
tau_LevelAbs=transmitter_lag;
yLO_LevelAbs=0;
yHI_LevelAbs=1;
Nded_LevelAbs=1+transmitter_deadtime(12)*transmitter_sampling_frequency(12);
Ntau_LevelAbs=1;
xxx_LevelAbs(1)= (y_ss(13)-yLO_LevelAbs) / (yHI_LevelAbs -yLO_LevelAbs);
for i=2:Nded_LevelAbs
    xxx_LevelAbs(i)= xxx_LevelAbs(1);
end
for i=1:Ntau_LevelAbs
    yyy_LevelAbs(i)= xxx_LevelAbs(Nded_LevelAbs);
end
xi_LevelAbs= (MVs(12) - uLO_LevelAbs) /(uHI_LevelAbs -uLO_LevelAbs)-K_LevelAbs*act_LevelAbs*((SP_LevelAbs-yLO_LevelAbs)/(yHI_LevelAbs-yLO_LevelAbs)-yyy_LevelAbs(Ntau_LevelAbs));
%-----------------------------------------------------------------------------
%controller initialization
%MV13: Circulation Flowrate is fixed to 15.1198 kmol/min
%-----------------------------------------------------------------------------
%controller initialization
%MV14: Q_Cooler_Circulation - Circulation Temperature
SP_CircOutletTemp=25;
K_CircOutletTemp=1;
Ti_CircOutletTemp=5;
act_CircOutletTemp=-1;
mode_CircOutletTemp=1;
Ponly_CircOutletTemp=0;
ht_CircOutletTemp=1/transmitter_sampling_frequency(14);
hc_CircOutletTemp=1/controller_sampling_frequency(14);
uLO_CircOutletTemp=0;
uHI_CircOutletTemp=30000;
ded_CircOutletTemp=transmitter_deadtime(14);
tau_CircOutletTemp=transmitter_lag;
yLO_CircOutletTemp=10;
yHI_CircOutletTemp=40;
Nded_CircOutletTemp=1+transmitter_deadtime(14)*transmitter_sampling_frequency(14);
Ntau_CircOutletTemp=1;
xxx_CircOutletTemp(1)= (y_ss(14) -yLO_CircOutletTemp) / (yHI_CircOutletTemp -yLO_CircOutletTemp);
for i=2:Nded_CircOutletTemp
    xxx_CircOutletTemp(i)= xxx_CircOutletTemp(1);
end
for i=1:Ntau_CircOutletTemp
    yyy_CircOutletTemp(i)= xxx_CircOutletTemp(Nded_CircOutletTemp);
end
xi_CircOutletTemp= (MVs(14) - uLO_CircOutletTemp) /(uHI_CircOutletTemp -uLO_CircOutletTemp)-K_CircOutletTemp*act_CircOutletTemp*((SP_CircOutletTemp-yLO_CircOutletTemp)/(yHI_CircOutletTemp-yLO_CircOutletTemp)-yyy_CircOutletTemp(Ntau_CircOutletTemp));
%-----------------------------------------------------------------------------
%controller initialization
%MV15: Scrub Flowrate is fixed to 0.756 kmol/min
%-----------------------------------------------------------------------------
%controller initialization
%MV16: Q_Cooler_Scrub - Scrub Temperature
SP_ScrubOutletTemp=25;
K_ScrubOutletTemp=1;
Ti_ScrubOutletTemp=5;
act_ScrubOutletTemp=-1;
mode_ScrubOutletTemp=1;
Ponly_ScrubOutletTemp=0;
ht_ScrubOutletTemp=1/transmitter_sampling_frequency(16);
hc_ScrubOutletTemp=1/controller_sampling_frequency(16);
uLO_ScrubOutletTemp=0;
uHI_ScrubOutletTemp=5000;
ded_ScrubOutletTemp=transmitter_deadtime(16);
tau_ScrubOutletTemp=transmitter_lag;
yLO_ScrubOutletTemp=10;
yHI_ScrubOutletTemp=40;
Nded_ScrubOutletTemp=1+transmitter_deadtime(16)*transmitter_sampling_frequency(16);
Ntau_ScrubOutletTemp=1;
xxx_ScrubOutletTemp(1)= (y_ss(15) -yLO_ScrubOutletTemp) / (yHI_ScrubOutletTemp -yLO_ScrubOutletTemp);
for i=2:Nded_ScrubOutletTemp
    xxx_ScrubOutletTemp(i)= xxx_ScrubOutletTemp(1);
end
for i=1:Ntau_ScrubOutletTemp
    yyy_ScrubOutletTemp(i)= xxx_ScrubOutletTemp(Nded_ScrubOutletTemp);
end
xi_ScrubOutletTemp= (MVs(16) - uLO_ScrubOutletTemp) /(uHI_ScrubOutletTemp -uLO_ScrubOutletTemp)-K_ScrubOutletTemp*act_ScrubOutletTemp*((SP_ScrubOutletTemp-yLO_ScrubOutletTemp)/(yHI_ScrubOutletTemp-yLO_ScrubOutletTemp)-yyy_ScrubOutletTemp(Ntau_ScrubOutletTemp));
%-----------------------------------------------------------------------------
%controller initialization
%MV17: CO2 - CO2 composition
SP_CO2=0.0076393;
K_CO2=1;
Ti_CO2=100;
act_CO2=-1;
mode_CO2=1;
Ponly_CO2=1;
ht_CO2=1/transmitter_sampling_frequency(17);
hc_CO2=1/controller_sampling_frequency(17);
uLO_CO2=0;
uHI_CO2=22.68;
ded_CO2=transmitter_deadtime(17);
tau_CO2=transmitter_lag;
yLO_CO2=0;
yHI_CO2=0.5;
Nded_CO2=1+transmitter_deadtime(17)*transmitter_sampling_frequency(17);
Ntau_CO2=1;
xxx_CO2(1)= (y_ss(31) -yLO_CO2) / (yHI_CO2 -yLO_CO2);
for i=2:Nded_CO2
    xxx_CO2(i)= xxx_CO2(1);
end
for i=1:Ntau_CO2
    yyy_CO2(i)= xxx_CO2(Nded_CO2);
end
xi_CO2= (MVs(17) - uLO_CO2) /(uHI_CO2 -uLO_CO2)-K_CO2*act_CO2*((SP_CO2-yLO_CO2)/(yHI_CO2-yLO_CO2)-yyy_CO2(Ntau_CO2));
%-----------------------------------------------------------------------------
%controller initialization
%MV18: Purge - C2H6 composition
SP_C2H6=0.25;
K_C2H6=1;
Ti_C2H6=100;
act_C2H6=-1;
mode_C2H6=1;
Ponly_C2H6=1;
ht_C2H6=1/transmitter_sampling_frequency(18);
hc_C2H6=1/controller_sampling_frequency(18);
uLO_C2H6=0;
uHI_C2H6=0.02268;
ded_C2H6=transmitter_deadtime(18);
tau_C2H6=transmitter_lag;
yLO_C2H6=0;
yHI_C2H6=1;
Nded_C2H6=1+transmitter_deadtime(18)*transmitter_sampling_frequency(18);
Ntau_C2H6=1;
xxx_C2H6(1)= (y_ss(33) -yLO_C2H6) / (yHI_C2H6 -yLO_C2H6);
for i=2:Nded_C2H6
    xxx_C2H6(i)= xxx_C2H6(1);
end
for i=1:Ntau_C2H6
    yyy_C2H6(i)= xxx_C2H6(Nded_C2H6);
end
xi_C2H6= (MVs(18) - uLO_C2H6) /(uHI_C2H6 -uLO_C2H6)-K_C2H6*act_C2H6*((SP_C2H6-yLO_C2H6)/(yHI_C2H6-yLO_C2H6)-yyy_C2H6(Ntau_C2H6));
%-----------------------------------------------------------------------------
%controller initialization
%MV19: bypass - FEHE Cold Exit Temp
SP_FEHE=134;
K_FEHE=5;
Ti_FEHE=10;
act_FEHE=1;
mode_FEHE=1;
Ponly_FEHE=0;
ht_FEHE=1/transmitter_sampling_frequency(19);
hc_FEHE=1/controller_sampling_frequency(19);
uLO_FEHE=0;
uHI_FEHE=1;
ded_FEHE=transmitter_deadtime(19);
tau_FEHE=transmitter_lag;
yLO_FEHE=0;
yHI_FEHE=200;
Nded_FEHE=1+transmitter_deadtime(19)*transmitter_sampling_frequency(19);
Ntau_FEHE=1;
xxx_FEHE(1)= (y_ss(8) -yLO_FEHE) / (yHI_FEHE -yLO_FEHE);
for i=2:Nded_FEHE
    xxx_FEHE(i)= xxx_FEHE(1);
end
for i=1:Ntau_FEHE
    yyy_FEHE(i)= xxx_FEHE(Nded_FEHE);
end
xi_FEHE= (MVs(19) - uLO_FEHE) /(uHI_FEHE -uLO_FEHE)-K_FEHE*act_FEHE*((SP_FEHE-yLO_FEHE)/(yHI_FEHE-yLO_FEHE)-yyy_FEHE(Ntau_FEHE));
%-----------------------------------------------------------------------------
%controller initialization
%MV20: LR - %H2O in bottom
SP_H2OCol=0.09344;
K_H2OCol=0.5;
Ti_H2OCol=60;
act_H2OCol=-1;
mode_H2OCol=1;
Ponly_H2OCol=0;
ht_H2OCol=1/transmitter_sampling_frequency(20);
hc_H2OCol=1/controller_sampling_frequency(20);
uLO_H2OCol=0;
uHI_H2OCol=7.56;
ded_H2OCol=transmitter_deadtime(20);
tau_H2OCol=transmitter_lag;
yLO_H2OCol=0;
yHI_H2OCol=0.2;
Nded_H2OCol=1+transmitter_deadtime(20)*transmitter_sampling_frequency(20);
Ntau_H2OCol=1;
xxx_H2OCol(1)= (y_ss(28) -yLO_H2OCol) / (yHI_H2OCol -yLO_H2OCol);
for i=2:Nded_H2OCol
    xxx_H2OCol(i)= xxx_H2OCol(1);
end
for i=1:Ntau_H2OCol
    yyy_H2OCol(i)= xxx_H2OCol(Nded_H2OCol);
end
xi_H2OCol= (MVs(20) - uLO_H2OCol) /(uHI_H2OCol -uLO_H2OCol)-K_H2OCol*act_H2OCol*((SP_H2OCol-yLO_H2OCol)/(yHI_H2OCol-yLO_H2OCol)-yyy_H2OCol(Ntau_H2OCol));
%-----------------------------------------------------------------------------
%controller initialization
%MV21: Qr - Temp
SP_TempCol=110;
K_TempCol=20;
Ti_TempCol=30;
act_TempCol=1;
mode_TempCol=1;
Ponly_TempCol=0;
ht_TempCol=1/transmitter_sampling_frequency(21);
hc_TempCol=1/controller_sampling_frequency(21);
uLO_TempCol=0;
uHI_TempCol=100000;
ded_TempCol=transmitter_deadtime(21);
tau_TempCol=transmitter_lag;
yLO_TempCol=0;
yHI_TempCol=120;
Nded_TempCol=1+transmitter_deadtime(21)*transmitter_sampling_frequency(21);
Ntau_TempCol=1;
xxx_TempCol(1)= (y_ss(22) -yLO_TempCol) / (yHI_TempCol -yLO_TempCol);
for i=2:Nded_TempCol
    xxx_TempCol(i)= xxx_TempCol(1);
end
for i=1:Ntau_TempCol
    yyy_TempCol(i)= xxx_TempCol(Nded_TempCol);
end
xi_TempCol= (MVs(21) - uLO_TempCol) /(uHI_TempCol -uLO_TempCol)-K_TempCol*act_TempCol*((SP_TempCol-yLO_TempCol)/(yHI_TempCol-yLO_TempCol)-yyy_TempCol(Ntau_TempCol));
%-----------------------------------------------------------------------------
%controller initialization
%MV22: Q_Condenser - Decanter Temperature (45.845 degC) is perfetly controlled in the code
SP_DecanterTemp=45.845;
K_DecanterTemp=1;
Ti_DecanterTemp=5;
act_DecanterTemp=-1;
mode_DecanterTemp=1;
Ponly_DecanterTemp=0;
ht_DecanterTemp=1/transmitter_sampling_frequency(22);
hc_DecanterTemp=1/controller_sampling_frequency(22);
uLO_DecanterTemp=0;
uHI_DecanterTemp=150000;
ded_DecanterTemp=transmitter_deadtime(22);
tau_DecanterTemp=transmitter_lag;
yLO_DecanterTemp=40;
yHI_DecanterTemp=50;
Nded_DecanterTemp=1+transmitter_deadtime(22)*transmitter_sampling_frequency(25);
Ntau_DecanterTemp=1;
xxx_DecanterTemp(1)= (y_ss(20) -yLO_DecanterTemp) / (yHI_DecanterTemp -yLO_DecanterTemp);
for i=2:Nded_DecanterTemp
    xxx_DecanterTemp(i)= xxx_DecanterTemp(1);
end
for i=1:Ntau_DecanterTemp
    yyy_DecanterTemp(i)= xxx_DecanterTemp(Nded_DecanterTemp);
end
xi_DecanterTemp= (MVs(22) - uLO_DecanterTemp) /(uHI_DecanterTemp -uLO_DecanterTemp)-K_DecanterTemp*act_DecanterTemp*((SP_DecanterTemp-yLO_DecanterTemp)/(yHI_DecanterTemp-yLO_DecanterTemp)-yyy_DecanterTemp(Ntau_DecanterTemp));
%-----------------------------------------------------------------------------
%controller initialization
%MV22: Organic Level is controlled by Organic Product Flow at 0.5
SP_Organic=0.5;
K_Organic=1;
Ti_Organic=100;
act_Organic=-1;
mode_Organic=1;
Ponly_Organic=1;
ht_Organic=1/transmitter_sampling_frequency(23);
hc_Organic=1/controller_sampling_frequency(23);
uLO_Organic=0;
uHI_Organic=2.4;
ded_Organic=transmitter_deadtime(23);
tau_Organic=transmitter_lag;
yLO_Organic=0;
yHI_Organic=1;
Nded_Organic=1+transmitter_deadtime(23)*transmitter_sampling_frequency(23);
Ntau_Organic=1;
xxx_Organic(1)= (y_ss(18)-yLO_Organic) / (yHI_Organic -yLO_Organic);
for i=2:Nded_Organic
    xxx_Organic(i)= xxx_Organic(1);
end
for i=1:Ntau_Organic
    yyy_Organic(i)= xxx_Organic(Nded_Organic);
end
xi_Organic= (MVs(23) - uLO_Organic) /(uHI_Organic -uLO_Organic)-K_Organic*act_Organic*((SP_Organic-yLO_Organic)/(yHI_Organic-yLO_Organic)-yyy_Organic(Ntau_Organic));
%-----------------------------------------------------------------------------
%controller initialization
%MV23: Aqueous Level is controlled by Aqueous Product Flow at 0.5
SP_Aqueous=0.5;
K_Aqueous=1;
Ti_Aqueous=100;
act_Aqueous=-1;
mode_Aqueous=1;
Ponly_Aqueous=1;
ht_Aqueous=1/transmitter_sampling_frequency(24);
hc_Aqueous=1/controller_sampling_frequency(24);
uLO_Aqueous=0;
uHI_Aqueous=2.4;
ded_Aqueous=transmitter_deadtime(24);
tau_Aqueous=transmitter_lag;
yLO_Aqueous=0;
yHI_Aqueous=1;
Nded_Aqueous=1+transmitter_deadtime(24)*transmitter_sampling_frequency(24);
Ntau_Aqueous=1;
xxx_Aqueous(1)= (y_ss(19)-yLO_Aqueous) / (yHI_Aqueous -yLO_Aqueous);
for i=2:Nded_Aqueous
    xxx_Aqueous(i)= xxx_Aqueous(1);
end
for i=1:Ntau_Aqueous
    yyy_Aqueous(i)= xxx_Aqueous(Nded_Aqueous);
end
xi_Aqueous= (MVs(24) - uLO_Aqueous) /(uHI_Aqueous -uLO_Aqueous)-K_Aqueous*act_Aqueous*((SP_Aqueous-yLO_Aqueous)/(yHI_Aqueous-yLO_Aqueous)-yyy_Aqueous(Ntau_Aqueous));
%-----------------------------------------------------------------------------
%MV24: Column Bottom Exit is used to control the Column Bottom Level
SP_ColButtom=0.5;
K_ColButtom=1;
Ti_ColButtom=100;
act_ColButtom=-1;
mode_ColButtom=1;
Ponly_ColButtom=1;
ht_ColButtom=1/transmitter_sampling_frequency(25);
hc_ColButtom=1/controller_sampling_frequency(25);
uLO_ColButtom=0;
uHI_ColButtom=4.536;
ded_ColButtom=transmitter_deadtime(25);
tau_ColButtom=transmitter_lag;
yLO_ColButtom=0;
yHI_ColButtom=1;
Nded_ColButtom=1+transmitter_deadtime(25)*transmitter_sampling_frequency(25);
Ntau_ColButtom=1;
xxx_ColButtom(1)= (y_ss(21)-yLO_ColButtom) / (yHI_ColButtom -yLO_ColButtom);
for i=2:Nded_ColButtom
    xxx_ColButtom(i)= xxx_ColButtom(1);
end
for i=1:Ntau_ColButtom
    yyy_ColButtom(i)= xxx_ColButtom(Nded_ColButtom);
end
xi_ColButtom= (MVs(25) - uLO_ColButtom) /(uHI_ColButtom -uLO_ColButtom)-K_ColButtom*act_ColButtom*((SP_ColButtom-yLO_ColButtom)/(yHI_ColButtom-yLO_ColButtom)-yyy_ColButtom(Ntau_ColButtom));
%-----------------------------------------------------------------------------
%controller initialization
%MV26: Vaporizer Liquid Inlet is fixed at 2.1924 kmol/min
%-----------------------------------------------------------------------------

%-----------------------------------------------------------------------------
%initialize historical data vectors
x_history=[];
y_history=[];
u_history=[];
dx_history=[];
%initialize simulation parameters
tic
timer=0;
is_initial=0;
disturbance_ID=0;
%start simulation
for k=0:(model_sampling_frequency*minute)
    time=k/model_sampling_frequency; %in minute
    %initialize disturbances
    if (k/model_sampling_frequency)>=10
        switch selected_ID
        case 0
            ;
        case 1
            SP_TRCT=151;
        case 2
            SP_TRCT=165;
        case 3
            SP_H2OCol=0.18;
        case 4
            MVs(26)=2.64;
        case 5
            if (k/model_sampling_frequency)<15
                MVs(3)=0;
            end
        case 6
            if (k/model_sampling_frequency)<15
                MVs(1)=0;
            end
        case 7
             disturbance_ID=1;
        case 8
            if (k/model_sampling_frequency)<15
                disturbance_ID=2;
            else
                disturbance_ID=0;
            end
        end
    end
    %calculate state derivatives and measurements
    [dstatedt,states,MVs,y_ss]=VAModel(states,MVs,time,is_initial,disturbance_ID);
    %in this example, we assume the setpoint of the vaporizer pressure control is given by the current gas recycle pressure
    SP_PresVap=y_ss(12);
    %command window display refreshing rate
    if rem(k,display_sampling_frequency*model_sampling_frequency)==0
        [error, indx]=max(abs(dstatedt./states));
%        info=['minute: ' num2str(time) '    max_dxdt_error: ' num2str(error) '    location: ' num2str(indx)];
 %       disp(info);
    end
    %save information
    if rem(k,storage_sampling_frequency*model_sampling_frequency)==0
        x_history=[x_history;states'];
        y_history=[y_history;[y_ss(37);y_ss(12);y_ss(23);y_ss(2);y_ss(1);y_ss(4);y_ss(5);y_ss(9);y_ss(10);MVs(10);y_ss(11);y_ss(13);MVs(13);y_ss(14);MVs(15);y_ss(15);y_ss(31);y_ss(33);y_ss(8);y_ss(28);y_ss(22);y_ss(20);y_ss(18);y_ss(19);y_ss(21);MVs(26);y_ss(27)]'];
        u_history=[u_history;MVs'];
        dx_history=[dx_history;dstatedt'];
    end
    %update states
    states=states+(1/model_sampling_frequency)*dstatedt;
    %controller action
    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(1))==0 & k~=0
        [xxx_O2, yyy_O2]=Transmit(y_ss(37), xxx_O2, yyy_O2, ded_O2, tau_O2, Nded_O2, Ntau_O2, ht_O2, yLO_O2, yHI_O2);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(1))==0 & k~=0
        [MVs(1),xi_O2,flag_O2]=controller(SP_O2, yyy_O2(Ntau_O2), MVs(1), xi_O2, mode_O2, K_O2, Ti_O2, hc_O2,...
            yLO_O2, yHI_O2, uLO_O2, uHI_O2, act_O2, Ponly_O2, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(2))==0 & k~=0
        [xxx_C2H4, yyy_C2H4]=Transmit(y_ss(12), xxx_C2H4, yyy_C2H4, ded_C2H4, tau_C2H4, Nded_C2H4, Ntau_C2H4, ht_C2H4, yLO_C2H4, yHI_C2H4);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(2))==0 & k~=0
        [MVs(2),xi_C2H4,flag_C2H4]=controller(SP_C2H4, yyy_C2H4(Ntau_C2H4), MVs(2), xi_C2H4, mode_C2H4, K_C2H4, Ti_C2H4, hc_C2H4,...
            yLO_C2H4, yHI_C2H4, uLO_C2H4, uHI_C2H4, act_C2H4, Ponly_C2H4, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(3))==0 & k~=0
        [xxx_HAc, yyy_HAc]=Transmit(y_ss(23), xxx_HAc, yyy_HAc, ded_HAc, tau_HAc, Nded_HAc, Ntau_HAc, ht_HAc, yLO_HAc, yHI_HAc);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(3))==0 & k~=0
        [MVs(3),xi_HAc,flag_HAc]=controller(SP_HAc, yyy_HAc(Ntau_HAc), MVs(3), xi_HAc, mode_HAc, K_HAc, Ti_HAc, hc_HAc,...
            yLO_HAc, yHI_HAc, uLO_HAc, uHI_HAc, act_HAc, Ponly_HAc, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(4))==0 & k~=0
        [xxx_LevelVap, yyy_LevelVap]=Transmit(y_ss(2), xxx_LevelVap, yyy_LevelVap, ded_LevelVap, tau_LevelVap, Nded_LevelVap, Ntau_LevelVap, ht_LevelVap, yLO_LevelVap, yHI_LevelVap);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(4))==0 & k~=0
        [MVs(4),xi_LevelVap,flag_LevelVap]=controller(SP_LevelVap, yyy_LevelVap(Ntau_LevelVap), MVs(4), xi_LevelVap, mode_LevelVap, K_LevelVap, Ti_LevelVap, hc_LevelVap,...
            yLO_LevelVap, yHI_LevelVap, uLO_LevelVap, uHI_LevelVap, act_LevelVap, Ponly_LevelVap, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(5))==0 & k~=0
        [xxx_PresVap, yyy_PresVap]=Transmit(y_ss(1), xxx_PresVap, yyy_PresVap, ded_PresVap, tau_PresVap, Nded_PresVap, Ntau_PresVap, ht_PresVap, yLO_PresVap, yHI_PresVap);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(5))==0 & k~=0
        [MVs(5),xi_PresVap,flag_PresVap]=controller(SP_PresVap, yyy_PresVap(Ntau_PresVap), MVs(5), xi_PresVap, mode_PresVap, K_PresVap, Ti_PresVap, hc_PresVap,...
            yLO_PresVap, yHI_PresVap, uLO_PresVap, uHI_PresVap, act_PresVap, Ponly_PresVap, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(6))==0 & k~=0
        [xxx_ReactorInletTemp, yyy_ReactorInletTemp]=Transmit(y_ss(4), xxx_ReactorInletTemp, yyy_ReactorInletTemp, ded_ReactorInletTemp, tau_ReactorInletTemp, Nded_ReactorInletTemp, Ntau_ReactorInletTemp, ht_ReactorInletTemp, yLO_ReactorInletTemp, yHI_ReactorInletTemp);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(6))==0 & k~=0
        [MVs(6),xi_ReactorInletTemp,flag_ReactorInletTemp]=controller(SP_ReactorInletTemp, yyy_ReactorInletTemp(Ntau_ReactorInletTemp), MVs(6), xi_ReactorInletTemp, mode_ReactorInletTemp, K_ReactorInletTemp, Ti_ReactorInletTemp, hc_ReactorInletTemp,...
            yLO_ReactorInletTemp, yHI_ReactorInletTemp, uLO_ReactorInletTemp, uHI_ReactorInletTemp, act_ReactorInletTemp, Ponly_ReactorInletTemp, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(7))==0 & k~=0
        [xxx_TRCT, yyy_TRCT]=Transmit(y_ss(5), xxx_TRCT, yyy_TRCT, ded_TRCT, tau_TRCT, Nded_TRCT, Ntau_TRCT, ht_TRCT, yLO_TRCT, yHI_TRCT);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(7))==0 & k~=0
        [MVs(7),xi_TRCT,flag_TRCT]=controller(SP_TRCT, yyy_TRCT(Ntau_TRCT), MVs(7), xi_TRCT, mode_TRCT, K_TRCT, Ti_TRCT, hc_TRCT,...
            yLO_TRCT, yHI_TRCT, uLO_TRCT, uHI_TRCT, act_TRCT, Ponly_TRCT, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(8))==0 & k~=0
        [xxx_LevelSep, yyy_LevelSep]=Transmit(y_ss(9), xxx_LevelSep, yyy_LevelSep, ded_LevelSep, tau_LevelSep, Nded_LevelSep, Ntau_LevelSep, ht_LevelSep, yLO_LevelSep, yHI_LevelSep);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(8))==0 & k~=0
        [MVs(8),xi_LevelSep,flag_LevelSep]=controller(SP_LevelSep, yyy_LevelSep(Ntau_LevelSep), MVs(8), xi_LevelSep, mode_LevelSep, K_LevelSep, Ti_LevelSep, hc_LevelSep,...
            yLO_LevelSep, yHI_LevelSep, uLO_LevelSep, uHI_LevelSep, act_LevelSep, Ponly_LevelSep, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(9))==0 & k~=0
        [xxx_TempSep, yyy_TempSep]=Transmit(y_ss(10), xxx_TempSep, yyy_TempSep, ded_TempSep, tau_TempSep, Nded_TempSep, Ntau_TempSep, ht_TempSep, yLO_TempSep, yHI_TempSep);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(9))==0 & k~=0
        [MVs(9),xi_TempSep,flag_TempSep]=controller(SP_TempSep, yyy_TempSep(Ntau_TempSep), MVs(9), xi_TempSep, mode_TempSep, K_TempSep, Ti_TempSep, hc_TempSep,...
            yLO_TempSep, yHI_TempSep, uLO_TempSep, uHI_TempSep, act_TempSep, Ponly_TempSep, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(11))==0 & k~=0
        [xxx_CompOutletTemp, yyy_CompOutletTemp]=Transmit(y_ss(11), xxx_CompOutletTemp, yyy_CompOutletTemp, ded_CompOutletTemp, tau_CompOutletTemp, Nded_CompOutletTemp, Ntau_CompOutletTemp, ht_CompOutletTemp, yLO_CompOutletTemp, yHI_CompOutletTemp);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(11))==0 & k~=0
        [MVs(11),xi_CompOutletTemp,flag_CompOutletTemp]=controller(SP_CompOutletTemp, yyy_CompOutletTemp(Ntau_CompOutletTemp), MVs(11), xi_CompOutletTemp, mode_CompOutletTemp, K_CompOutletTemp, Ti_CompOutletTemp, hc_CompOutletTemp,...
            yLO_CompOutletTemp, yHI_CompOutletTemp, uLO_CompOutletTemp, uHI_CompOutletTemp, act_CompOutletTemp, Ponly_CompOutletTemp, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(12))==0 & k~=0
        [xxx_LevelAbs, yyy_LevelAbs]=Transmit(y_ss(13), xxx_LevelAbs, yyy_LevelAbs, ded_LevelAbs, tau_LevelAbs, Nded_LevelAbs, Ntau_LevelAbs, ht_LevelAbs, yLO_LevelAbs, yHI_LevelAbs);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(12))==0 & k~=0
        [MVs(12),xi_LevelAbs,flag_LevelAbs]=controller(SP_LevelAbs, yyy_LevelAbs(Ntau_LevelAbs), MVs(12), xi_LevelAbs, mode_LevelAbs, K_LevelAbs, Ti_LevelAbs, hc_LevelAbs,...
            yLO_LevelAbs, yHI_LevelAbs, uLO_LevelAbs, uHI_LevelAbs, act_LevelAbs, Ponly_LevelAbs, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(14))==0 & k~=0
        [xxx_CircOutletTemp, yyy_CircOutletTemp]=Transmit(y_ss(14), xxx_CircOutletTemp, yyy_CircOutletTemp, ded_CircOutletTemp, tau_CircOutletTemp, Nded_CircOutletTemp, Ntau_CircOutletTemp, ht_CircOutletTemp, yLO_CircOutletTemp, yHI_CircOutletTemp);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(14))==0 & k~=0
        [MVs(14),xi_CircOutletTemp,flag_CircOutletTemp]=controller(SP_CircOutletTemp, yyy_CircOutletTemp(Ntau_CircOutletTemp), MVs(14), xi_CircOutletTemp, mode_CircOutletTemp, K_CircOutletTemp, Ti_CircOutletTemp, hc_CircOutletTemp,...
            yLO_CircOutletTemp, yHI_CircOutletTemp, uLO_CircOutletTemp, uHI_CircOutletTemp, act_CircOutletTemp, Ponly_CircOutletTemp, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(16))==0 & k~=0
        [xxx_ScrubOutletTemp, yyy_ScrubOutletTemp]=Transmit(y_ss(15), xxx_ScrubOutletTemp, yyy_ScrubOutletTemp, ded_ScrubOutletTemp, tau_ScrubOutletTemp, Nded_ScrubOutletTemp, Ntau_ScrubOutletTemp, ht_ScrubOutletTemp, yLO_ScrubOutletTemp, yHI_ScrubOutletTemp);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(16))==0 & k~=0
        [MVs(16),xi_ScrubOutletTemp,flag_ScrubOutletTemp]=controller(SP_ScrubOutletTemp, yyy_ScrubOutletTemp(Ntau_ScrubOutletTemp), MVs(16), xi_ScrubOutletTemp, mode_ScrubOutletTemp, K_ScrubOutletTemp, Ti_ScrubOutletTemp, hc_ScrubOutletTemp,...
            yLO_ScrubOutletTemp, yHI_ScrubOutletTemp, uLO_ScrubOutletTemp, uHI_ScrubOutletTemp, act_ScrubOutletTemp, Ponly_ScrubOutletTemp, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(17))==0 & k~=0
        [xxx_CO2, yyy_CO2]=Transmit(y_ss(31), xxx_CO2, yyy_CO2, ded_CO2, tau_CO2, Nded_CO2, Ntau_CO2, ht_CO2, yLO_CO2, yHI_CO2);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(17))==0 & k~=0
        [MVs(17),xi_CO2,flag_CO2]=controller(SP_CO2, yyy_CO2(Ntau_CO2), MVs(17), xi_CO2, mode_CO2, K_CO2, Ti_CO2, hc_CO2,...
            yLO_CO2, yHI_CO2, uLO_CO2, uHI_CO2, act_CO2, Ponly_CO2, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(18))==0 & k~=0
        [xxx_C2H6, yyy_C2H6]=Transmit(y_ss(33), xxx_C2H6, yyy_C2H6, ded_C2H6, tau_C2H6, Nded_C2H6, Ntau_C2H6, ht_C2H6, yLO_C2H6, yHI_C2H6);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(18))==0 & k~=0
        [MVs(18),xi_C2H6,flag_C2H6]=controller(SP_C2H6, yyy_C2H6(Ntau_C2H6), MVs(18), xi_C2H6, mode_C2H6, K_C2H6, Ti_C2H6, hc_C2H6,...
            yLO_C2H6, yHI_C2H6, uLO_C2H6, uHI_C2H6, act_C2H6, Ponly_C2H6, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(19))==0 & k~=0
        [xxx_FEHE, yyy_FEHE]=Transmit(y_ss(8), xxx_FEHE, yyy_FEHE, ded_FEHE, tau_FEHE, Nded_FEHE, Ntau_FEHE, ht_FEHE, yLO_FEHE, yHI_FEHE);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(19))==0 & k~=0
        [MVs(19),xi_FEHE,flag_FEHE]=controller(SP_FEHE, yyy_FEHE(Ntau_FEHE), MVs(19), xi_FEHE, mode_FEHE, K_FEHE, Ti_FEHE, hc_FEHE,...
            yLO_FEHE, yHI_FEHE, uLO_FEHE, uHI_FEHE, act_FEHE, Ponly_FEHE, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(20))==0 & k~=0
        [xxx_H2OCol, yyy_H2OCol]=Transmit(y_ss(28), xxx_H2OCol, yyy_H2OCol, ded_H2OCol, tau_H2OCol, Nded_H2OCol, Ntau_H2OCol, ht_H2OCol, yLO_H2OCol, yHI_H2OCol);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(20))==0 & k~=0
        [MVs(20),xi_H2OCol,flag_H2OCol]=controller(SP_H2OCol, yyy_H2OCol(Ntau_H2OCol), MVs(20), xi_H2OCol, mode_H2OCol, K_H2OCol, Ti_H2OCol, hc_H2OCol,...
            yLO_H2OCol, yHI_H2OCol, uLO_H2OCol, uHI_H2OCol, act_H2OCol, Ponly_H2OCol, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(21))==0 & k~=0
        [xxx_TempCol, yyy_TempCol]=Transmit(y_ss(22), xxx_TempCol, yyy_TempCol, ded_TempCol, tau_TempCol, Nded_TempCol, Ntau_TempCol, ht_TempCol, yLO_TempCol, yHI_TempCol);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(21))==0 & k~=0
        [MVs(21),xi_TempCol,flag_TempCol]=controller(SP_TempCol, yyy_TempCol(Ntau_TempCol), MVs(21), xi_TempCol, mode_TempCol, K_TempCol, Ti_TempCol, hc_TempCol,...
            yLO_TempCol, yHI_TempCol, uLO_TempCol, uHI_TempCol, act_TempCol, Ponly_TempCol, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(22))==0 & k~=0
        [xxx_DecanterTemp, yyy_DecanterTemp]=Transmit(y_ss(20), xxx_DecanterTemp, yyy_DecanterTemp, ded_DecanterTemp, tau_DecanterTemp, Nded_DecanterTemp, Ntau_DecanterTemp, ht_DecanterTemp, yLO_DecanterTemp, yHI_DecanterTemp);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(22))==0 & k~=0
        [MVs(22),xi_DecanterTemp,flag_DecanterTemp]=controller(SP_DecanterTemp, yyy_DecanterTemp(Ntau_DecanterTemp), MVs(22), xi_DecanterTemp, mode_DecanterTemp, K_DecanterTemp, Ti_DecanterTemp, hc_DecanterTemp,...
            yLO_DecanterTemp, yHI_DecanterTemp, uLO_DecanterTemp, uHI_DecanterTemp, act_DecanterTemp, Ponly_DecanterTemp, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(23))==0 & k~=0
        [xxx_Organic, yyy_Organic]=Transmit(y_ss(18), xxx_Organic, yyy_Organic, ded_Organic, tau_Organic, Nded_Organic, Ntau_Organic, ht_Organic, yLO_Organic, yHI_Organic);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(23))==0 & k~=0
        [MVs(23),xi_Organic,flag_Organic]=controller(SP_Organic, yyy_Organic(Ntau_Organic), MVs(23), xi_Organic, mode_Organic, K_Organic, Ti_Organic, hc_Organic,...
            yLO_Organic, yHI_Organic, uLO_Organic, uHI_Organic, act_Organic, Ponly_Organic, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(24))==0 & k~=0
        [xxx_Aqueous, yyy_Aqueous]=Transmit(y_ss(19), xxx_Aqueous, yyy_Aqueous, ded_Aqueous, tau_Aqueous, Nded_Aqueous, Ntau_Aqueous, ht_Aqueous, yLO_Aqueous, yHI_Aqueous);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(24))==0 & k~=0
        [MVs(24),xi_Aqueous,flag_Aqueous]=controller(SP_Aqueous, yyy_Aqueous(Ntau_Aqueous), MVs(24), xi_Aqueous, mode_Aqueous, K_Aqueous, Ti_Aqueous, hc_Aqueous,...
            yLO_Aqueous, yHI_Aqueous, uLO_Aqueous, uHI_Aqueous, act_Aqueous, Ponly_Aqueous, 0, 0, 0, 0);
    end

    if rem(k,model_sampling_frequency/transmitter_sampling_frequency(25))==0 & k~=0
        [xxx_ColButtom, yyy_ColButtom]=Transmit(y_ss(21), xxx_ColButtom, yyy_ColButtom, ded_ColButtom, tau_ColButtom, Nded_ColButtom, Ntau_ColButtom, ht_ColButtom, yLO_ColButtom, yHI_ColButtom);
    end
    if rem(k,model_sampling_frequency/controller_sampling_frequency(25))==0 & k~=0
        [MVs(25),xi_ColButtom,flag_ColButtom]=controller(SP_ColButtom, yyy_ColButtom(Ntau_ColButtom), MVs(25), xi_ColButtom, mode_ColButtom, K_ColButtom, Ti_ColButtom, hc_ColButtom,...
            yLO_ColButtom, yHI_ColButtom, uLO_ColButtom, uHI_ColButtom, act_ColButtom, Ponly_ColButtom, 0, 0, 0, 0);
    end

end
toc
%plot graphics
my_label=['   %O2  ';'  Pres  ';'  HAc-L ';'  Vap-L ';'  Vap-P ';'  Pre-T ';'  RCT-T ';'  Sep-L ';'  Sep-T ';'  Sep-V ';'  Com-T ';'  Abs-L ';'  Cir-F ';'  Cir-T ';'  Scr-F ';'  Scr-T ';'  %CO2  ';'  %C2H6 ';' FEHE-T ';'  %H2O  ';'  Col-T ';'  Org-L ';'  Aqu-L ';'  Col-L ';' Vap-In ';' Dect-T ';'%VAc E-3'];
MV_label=[' F-O2 ';'F-C2H4';' F-HAc';' Q-Vap';' F-Vap';'Q-Heat';'ShellT';'F-SepL';' T-Sep';'F-SepV';'Q-Comp';'F-AbsL';'F-Circ';'Q-Circ';'F-Scru';'Q-Scru';' F-CO2';' Purge';'bypass';'Reflux';'Q-Rebo';'F-Orga';'F-Aque';' F-Bot';'Q_Cond';'F-Tank'];
setpoint=[SP_O2;SP_C2H4;SP_HAc;SP_LevelVap;SP_PresVap;150;SP_TRCT;SP_LevelSep;SP_TempSep;16.1026;80;SP_LevelAbs;15.1198;25;0.756;25;SP_CO2;SP_C2H6;SP_FEHE;SP_H2OCol;SP_TempCol;0.5;0.5;SP_ColButtom;45.845;2.1924];
warning off
if selected_ID==1
    McAvoy_Plot_1(y_history,u_history,setpoint,my_label,MV_label,storage_sampling_frequency);
elseif selected_ID==2
    McAvoy_Plot_2(y_history,u_history,setpoint,my_label,MV_label,storage_sampling_frequency);
elseif selected_ID==3
    McAvoy_Plot_3(y_history,u_history,setpoint,my_label,MV_label,storage_sampling_frequency);
elseif selected_ID==4
    McAvoy_Plot_4(y_history,u_history,setpoint,my_label,MV_label,storage_sampling_frequency);
else
    Transient_Plot(y_history,u_history,setpoint,my_label,MV_label,storage_sampling_frequency);
end
return


function [bbci_cls, data_adapt]= bbci_adaptation_pcovmean(bbci_cls, data_adapt, marker, varargin)
%BBCI_ADAPTATIOIN_PCOVMEAN - Supervised adapt class means and pooled covariance matrix of an LDA classifier
%
%Technique by Carmen Vidaurre, see
%  Viduarre C et al, J Neural Eng, 2011
%  http://dx.doi.org/10.1088/1741-2560/8/2/025009
%
%Synopsis:
%  [BBCI_CLS, DATA_ADAPT]= ...
%      bbci_adaptation_pcovmean(BBCI_CLS, DATA_ADAPT, 'init', PARAMs, ...)
%  [BBCI_CLS, DATA_ADAPT]= ...
%      bbci_adaptation_pcovmean(BBCI_CLS, DATA_ADAPT, MARKER, FEATURE)
%
%This function is called internally by bbci_apply_adaptation.
%
%The selectable parameters are
%  'UC_mean' - [DOUBLE, default 0.05] Update coefficient for supervised
%              adaptation of the class means.
%  'UC_pcov' - [DOUBLE, default 0.03] Update coefficient for unsupervised
%              adaptation of the pooled covariance matrix (inverse of the
%              extended ..., to be exact).
%  'ival' - [1x2 DOUBLE] Time interval relative to the start marker, during
%              which features are averaged and used for adaptation;
%              no default - needs to be set.
%              Note: When choosing the start of the adaptation interval,
%              you have to take into account bbci.feature.ival (meaning
%              that feature are based on retrospective signals).
%  'mrk_start' - {1xnClasses CELL} defines the markers that trigger the
%              adaptation for each class; no default - needs to be set.
%  'mrk_end' - [1 nMarkers INT, default []] specifies markers that indicate
%              the end of a trial. Gathering feature information for the
%              adaptation of one trial ends, when one of those end-markers
%              is received AND the end of the adaptation interval 'ival'
%              (see above) is reached. If 'mrk_end' is empty, the first part
%              of the condition is ignored, i.e., only 'ival' is taken into
%              account.
%  'scaling' - [BOOL, default true] Defines whether the updated classifier
%              should be (re-) scaled.
%  'log_mean_limit' - [INT, default 100].

% 01-2012 Benjamin Blankertz
% 04-2011 Claudia Sannelli

if ischar(marker) && strcmp(marker, 'init'),
  props= {'UC_mean'          0.05    '!DOUBLE[1]'
          'UC_pcov'          0.03    '!DOUBLE[1]'
          'ival'             []      '!DOUBLE[2]'
          'scaling'          1       '!BOOL'
          'mrk_start'        {}      'CELL'
          'mrk_end'          []      'INT'
          'log_mean_limit'   100     '!INT'
          'tag'              ''      'CHAR'
         };
  opt= opt_proplistToStruct(varargin{:});
  opt= opt_setDefaults(opt, props, 2);
  data_adapt.opt= opt;
  data_adapt.feature= zeros(size(bbci_cls.C.w));
  data_adapt.trial_start= NaN;
  data_adapt.lastcheck= -inf;
  bbci_log_write(data_adapt.log.fid, ...
                 '# %s started with bias=%g and options %s.', ...
                 data_adapt.opt.tag, bbci_cls.C.b, util_toString(opt));
  return;
else
  feature= varargin{1};
end

time= marker.current_time;
check_ival= [data_adapt.lastcheck time];
events= bbci_apply_queryMarker(marker, check_ival);
data_adapt.lastcheck= time;

if ~isempty(events) && isnan(data_adapt.trial_start),
  data_adapt.clidx= 0;
  for k= 1:length(data_adapt.opt.mrk_start),
    marker_idx= find(ismember([events.desc], data_adapt.opt.mrk_start{k},'legacy'));
    if ~isempty(marker_idx),
      data_adapt.clidx= k;
      break;
    end
  end
  if data_adapt.clidx>0,
    data_adapt.trial_start= events(marker_idx(1)).time;
    data_adapt.end_marker_received= isempty(data_adapt.opt.mrk_end);
    data_adapt.counter= 0;
    bbci_log_write(data_adapt.log.fid, ...
        ['# %s at ' data_adapt.log.time_fmt ...
         ' trial started with marker %d -> class %d.'], ...
        data_adapt.opt.tag, data_adapt.trial_start/1000, ...
        events(marker_idx(1)).desc, data_adapt.clidx);
  end
end

if isnan(data_adapt.trial_start),
  return;
end

% within the adaptation interval, add up the features and count them
adapt_ival= data_adapt.trial_start + data_adapt.opt.ival;
if time >= adapt_ival(1) && time <= adapt_ival(2),
  data_adapt.feature= data_adapt.feature + feature.x(:);
  data_adapt.counter= data_adapt.counter + 1;
end

if ~isempty(events) && any(ismember([events.desc], data_adapt.opt.mrk_end,'legacy'));
  data_adapt.end_marker_received= 1;
end
if data_adapt.end_marker_received && time >= adapt_ival(2),
  if data_adapt.counter==0,
    return;
  end
  % handy definitions
  UCm= data_adapt.opt.UC_mean;
  UCp= data_adapt.opt.UC_pcov;
  feat= data_adapt.feature/data_adapt.counter;
  % adapt class means (supervised)
  bbci_cls.C.mean(:,data_adapt.clidx)= UCm * feat + ...
      (1 - UCm) * bbci_cls.C.mean(:,data_adapt.clidx);
  % adapt (inverse of extended) pooled covariance matrix (unsupervised)
  extfeat= [1; feat];
  v= bbci_cls.C.extinvcov*extfeat;
  bbci_cls.C.extinvcov= (1/(1 - UCp)) * ...
    (bbci_cls.C.extinvcov - UCp/(1 - UCp + UCp * extfeat' * v) * v*v');
  bbci_cls.C.extinvcov= 0.5 * (bbci_cls.C.extinvcov + bbci_cls.C.extinvcov');
  % recalculate classifier
  diff_mean= diff(bbci_cls.C.mean, 1, 2);
  bbci_cls.C.w= bbci_cls.C.extinvcov(2:end, 2:end) * diff_mean;

  % rescale projection vector
  if data_adapt.opt.scaling,
    bbci_cls.C.w= bbci_cls.C.w/(bbci_cls.C.w' * diff_mean)*2;
  end
  bbci_cls.C.b= -bbci_cls.C.w' * mean(bbci_cls.C.mean, 2);
  if numel(bbci_cls.C.mean) < data_adapt.opt.log_mean_limit,
    bbci_log_write(data_adapt.log.fid, ...
                   ['# %s at ' data_adapt.log.time_fmt ...
                   ' bias adapted to %g, mean adapted to %s' ...
                   ' with %d features.'], ...
                   data_adapt.opt.tag, marker.current_time/1000, ...
                   bbci_cls.C.b, util_toString(bbci_cls.C.mean), ...
                   data_adapt.counter);
  else
    bbci_log_write(data_adapt.log.fid, ...
                   ['# %s at ' data_adapt.log.time_fmt ...
                   ' bias adapted to %g with %d features.'], ...
                   data_adapt.opt.tag, marker.current_time/1000, ...
                   bbci_cls.C.b, data_adapt.counter);
  end
  data_adapt.feature(:)= 0;
  data_adapt.trial_start= NaN;
end


function exact = p00_exact ( problem )

%*****************************************************************************80
%
%% P00_EXACT returns the exact integral for any problem.
%
%  Discussion:
%
%    This routine provides a "generic" interface to the exact integral
%    routines for the various problems, and allows a problem to be called
%    by index (PROBLEM) rather than by name.
%
%    In most cases, the "exact" value of the integral is not given;
%    instead a "respectable" approximation is available.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the index of the problem.
%
%    Output, real EXACT, the exact value of the integral.
%
  if ( problem == 1 )
    exact = p01_exact ( );
  elseif ( problem == 2 )
    exact = p02_exact ( );
  elseif ( problem == 3 )
    exact = p03_exact ( );
  elseif ( problem == 4 )
    exact = p04_exact ( );
  elseif ( problem == 5 )
    exact = p05_exact ( );
  elseif ( problem == 6 )
    exact = p06_exact ( );
  elseif ( problem == 7 )
    exact = p07_exact ( );
  elseif ( problem == 8 )
    exact = p08_exact ( );
  elseif ( problem == 9 )
    exact = p09_exact ( );
  elseif ( problem == 10 )
    exact = p10_exact ( );
  elseif ( problem == 11 )
    exact = p11_exact ( );
  elseif ( problem == 12 )
    exact = p12_exact ( );
  elseif ( problem == 13 )
    exact = p13_exact ( );
  elseif ( problem == 14 )
    exact = p14_exact ( );
  elseif ( problem == 15 )
    exact = p15_exact ( );
  elseif ( problem == 16 )
    exact = p16_exact ( );
  elseif ( problem == 17 )
    exact = p17_exact ( );
  elseif ( problem == 18 )
    exact = p18_exact ( );
  elseif ( problem == 19 )
    exact = p19_exact ( );
  elseif ( problem == 20 )
    exact = p20_exact ( );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_EXACT - Fatal error!\n' );
    fprintf ( 1, '  Illegal problem number = %d\n', problem );
    error ( 'P00_EXACT - Fatal error!' );
  end

  return
end


function varargout = KUKA_GUI(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @KUKA_GUI_OpeningFcn, ...
                   'gui_OutputFcn',  @KUKA_GUI_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%                                                                        %%
%%%                  Written by Rohit Mishra                               %%
%%%                  A.C. Patil College of Engg.                                            %%
%%%                  March 2013                                            %%
%%%                  Simulation of six axis kuka kr6.                      %%
%%%                                                                        %%
%%%      The purpose of this program is to simulate a six axis kuka kr6    %%
%%%      robot located in the DRHR DEPT. at BARC MUMBAI .  This            %%
%%%      program simulates Forward Kinematics of this robot.               %%
%%%      To operate this program:                                          %%
%%%           1)     Make sure that KUKA.WRL, KUKA_GUI.fig, KUKA_GUI.m     %%
%%%                  are in the appropriate path.                          %%
%%%           2)     Execute KUKA_GUI.m                                    %%
%%%           4)     Have fun!                                             %%
%%%      If you have question about this program email Rohit Mishra        %%
%%%      <mishra.rohit2410@gmail.com> .  Rohit Mishra is Final Year Student%%
%%%      from Mumbai University(ACPCE, TRONIX 2013)has developed this      %%
%%%      project with the help of his friends Tejas Mahadik, Kaushik       %%
%%%      Natrajan and  Siddhesh Chavan .                                   %%
%%%      We are thankful to our project guide and HOD Dr. V.N. Pawar for   %%
%%%      his unwavering support and guidance in helping us with this       %%
%%%      project and also to Mrs. Varsha Shirwalkar at Barc, Mumbai.       %%
%%%                                                                        %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function KUKA_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
KUKA = vrworld('KUKA.wrl');
open(KUKA)
view(KUKA)

    radian=0
    KUKA.shoulder.rotation = [0, 1, 0, radian];

    KUKA.elbow.rotation = [0, 0, 1, radian];

    KUKA.pitch.rotation = [0, 0, 1, radian];

    KUKA.roll.rotation = [1, 0, 0, radian];

    KUKA.yaw.rotation = [0, 0, 1, radian];

    KUKA.drill.rotation = [1, 0, 0, radian];

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T1=get(handles.slider1,'value');
set(handles.edit57,'String',num2str(T1));
guidata(hObject, handles);
    radian=T1*pi/180;
    q1=radian;
    KUKA.shoulder.rotation = [0, 1, 0, radian];

% --- Executes on slider movement.
function slider2_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T2=get(handles.slider2,'value');
set(handles.edit58,'String',num2str(T2));
guidata(hObject, handles);
    radian=T2*pi/180;
    q2=radian;
    KUKA.elbow.rotation = [0, 0, 1, radian];

% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T3=get(handles.slider3,'value');
set(handles.edit59,'String',num2str(T3));
guidata(hObject, handles);
    radian=T3*pi/180;
    q3=radian;
    KUKA.pitch.rotation = [0, 0, 1, radian];

% --- Executes on slider movement.
function slider4_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T4=-get(handles.slider4,'value');
set(handles.edit60,'String',num2str(T4));
guidata(hObject, handles);
    radian=T4*pi/180;
    q4=radian;
    KUKA.roll.rotation = [1, 0, 0, radian];

% --- Executes on slider movement.
function slider5_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T5=-get(handles.slider5,'value');
    set(handles.edit61,'String',num2str(T5));
    guidata(hObject, handles);
    radian=T5*pi/180;
    q5=radian;
    KUKA.yaw.rotation = [0, 0, 1, radian];

    % --- Executes on slider movement.
function slider6_Callback(hObject, eventdata, handles)
KUKA = vrworld('KUKA.wrl');
open(KUKA)
T6=-get(handles.slider6,'value');
set(handles.edit62,'String',num2str(T6));
guidata(hObject, handles);
    radian=T6*pi/180;
    q6=radian;
    KUKA.drill.rotation = [1, 0, 0, radian];

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)

% % % GIVEN JOINT VARIABLES

d=[335   0   0   -295    0   -80];
a=[75    270 90  0   0   0];

% % TRANSFORMATION MATRIX 1.
q1=get(handles.slider1,'Value');
T1=[    cos(q1)     0       -sin(q1) a(1)*cos(q1)
        sin(q1)     0       -cos(q1) a(1)*sin(q1)
        0           -1          0       d(1)
        0           0           0        1      ];

% % TRANSFORMATION MATRIX 2.
q2=get(handles.slider2,'Value');
T2=[    cos(q2)     -sin(q2)    0   a(2)*cos(q2)
        sin(q2)     cos(q2)     0   a(2)*sin(q2)
        0               0       1       0
        0               0       0       1   ];

% % TRANSFORMATION MATRIX 3.
q3=get(handles.slider3,'Value');
T3=[    cos(q3)         0    sin(q3)   a(3)*cos(q3)
        sin(q3)         0    -cos(q3)   a(3)*sin(q3)
        0               0       0       0
        0               0       0       1   ];
% % TRANSFORMATION MATRIX 4.
q4=get(handles.slider4,'Value');
T4=[    cos(q4)         0   -sin(q4)    0
        sin(q4)         0    cos(q4)    0
        0              -1       0      d(4)
        0               0       0       1   ];

% % TRANSFORMATION MATRIX 5.
q5=get(handles.slider5,'Value');
T5=[    cos(q5)     0       sin(q5)           0
        sin(q5)     0       -cos(q5)          0
        0           1          0               0
        0           0          0               1       ];

% % TRANSFORMATION MATRIX 6.
q6=get(handles.slider6,'Value');
T6=[    cos(q6)     -sin(q6)        0           0
        sin(q6)     cos(q6)     0               0
        0           0           1           0
        0           0           0               1   ];

A=T1*T2*T3*T4*T5*T6;

set(handles.edit42,'String',num2str(A(13)));
set(handles.edit43,'String',num2str(A(14)));
set(handles.edit44,'String',num2str(A(15)));
set(handles.edit48,'String',num2str(A(1)));
set(handles.edit49,'String',num2str(A(5)));
set(handles.edit50,'String',num2str(A(9)));
set(handles.edit51,'String',num2str(A(2)));
set(handles.edit52,'String',num2str(A(6)));
set(handles.edit53,'String',num2str(A(10)));
set(handles.edit54,'String',num2str(A(3)));
set(handles.edit55,'String',num2str(A(7)));
set(handles.edit56,'String',num2str(A(11)));
guidata(hObject, handles);


function [lrp] = ft_lateralizedpotential(cfg, avgL, avgR)

% FT_LATERALIZEDPOTENTIAL computes lateralized potentials such as the
% lateralized readiness potential (LRP)
%
% Use as
%   [lrp] = ft_lateralizedpotential(cfg, avgL, avgR)
%
% where the input datasets should come from FT_TIMELOCKANALYSIS
% and the configuration should contain
%   cfg.channelcmb = Nx2 cell-array
%
% An example channelcombination containing the homologous channels
% in the 10-20 standard system is
%    cfg.channelcmb = {'Fp1'   'Fp2'
%                      'F7'    'F8'
%                      'F3'    'F4'
%                      'T7'    'T8'
%                      'C3'    'C4'
%                      'P7'    'P8'
%                      'P3'    'P4'
%                      'O1'    'O2'}
%
% The lateralized potential is computed on combinations of channels and
% not on indivudual channels. However, if you want to make a topographic
% plot with e.g. FT_MULTIPLOTER, you can replace the output lrp.label
% with lrp.plotlabel.
%
% The concept for the LRP was introduced approximately simultaneously in the
% following two papers
% - M. G. H. Coles. Modern mind-brain reading - psychophysiology,
%   physiology, and cognition. Psychophysiology, 26(3):251-269, 1988.
% - R. de Jong, M. Wierda, G. Mulder, and L. J. Mulder. Use of
%   partial stimulus information in response processing. J Exp Psychol
%   Hum Percept Perform, 14:682-692, 1988.
% and it is discussed in detail on a technical level in
% - R. Oostenveld, D.F. Stegeman, P. Praamstra and A. van Oosterom.
%   Brain symmetry and topographic analysis of lateralized event-related
%   potentials. Clin Neurophysiol. 114(7):1194-202, 2003.
%
% To facilitate data-handling and distributed computing you can use
%   cfg.inputfile   =  ...
%   cfg.outputfile  =  ...
% If you specify one of these (or both) the input data will be read from a *.mat
% file on disk and/or the output data will be written to a *.mat file. These mat
% files should contain only a single variable, corresponding with the
% input/output structure.
%
% See also FT_TIMELOCKANALYSIS, FT_MULTIPLOTER

% Copyright (C) 2004, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble loadvar avgL avgR
ft_preamble provenance avgL avgR

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% check if the input data is valid for this function
avgL = ft_checkdata(avgL, 'datatype', 'timelock');
avgR = ft_checkdata(avgR, 'datatype', 'timelock');

% check if the input cfg is valid for this function
cfg = ft_checkconfig(cfg, 'forbidden',  {'channels'}); % prevent accidental typos, see issue 1729

% set the defaults
if ~isfield(cfg, 'channelcmb')
  cfg.channelcmb = {
    'Fp1'   'Fp2'
    'F7'    'F8'
    'F3'    'F4'
    'T7'    'T8'
    'C3'    'C4'
    'P7'    'P8'
    'P3'    'P4'
    'O1'    'O2'
    };
end

if ~isequal(avgL.time, avgR.time)
  ft_error('the time axes are not the same');
end

% start with an empty output structure
lrp.label     = {};
lrp.plotlabel = {};
lrp.avg       = [];
lrp.time      = avgL.time;

% add timelock signature
if isfield(avgL, 'dimord') && isfield(avgR, 'dimord')
    if ~strcmp(avgL.dimord, avgR.dimord)
        ft_error('The input data are of different dimord types');
    else
        lrp.dimord = avgL.dimord;
    end
else
    ft_error('''dimord'' not found. The function expects timelock data');
end

% compute the lateralized potentials
Nchan = size(cfg.channelcmb,1);
for i=1:Nchan
  % here the channel names "C3" and "C4" are used to clarify the
  % computation of the lateralized potential on all channel pairs
  C3R = strcmp(cfg.channelcmb{i,1}, avgR.label);
  C4R = strcmp(cfg.channelcmb{i,2}, avgR.label);
  C3L = strcmp(cfg.channelcmb{i,1}, avgL.label);
  C4L = strcmp(cfg.channelcmb{i,2}, avgL.label);
  if any(C3R) && any(C4R) && any(C3L) && any(C4L)
    lrp.label{end+1}     = sprintf('%s/%s', cfg.channelcmb{i,1}, cfg.channelcmb{i,2});
    lrp.plotlabel{end+1} = cfg.channelcmb{i,1};
    erpC3L = avgL.avg(C3L,:);
    erpC4L = avgL.avg(C4L,:);
    erpC3R = avgR.avg(C3R,:);
    erpC4R = avgR.avg(C4R,:);
    lrp.avg(end+1,:) = 1/2 * ((erpC3R - erpC4R) + (erpC4L - erpC3L));
  end
end

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble previous   avgL avgR
ft_postamble provenance lrp
ft_postamble history    lrp
ft_postamble savevar    lrp


function [s,error] = openDEeph( s, denum, ineph, dontSave )
% open a binary JPL planetary ephemeris file and sets initial values
% short int ephem_open (char *ephem_name,
%                       double *jd_begin, double *jd_end,
%                       short int *de_number)
%
% ------------------------------------------------------------------------
%
%    PURPOSE:
%       This function opens a JPL planetary ephemeris file and
%       sets initial values.  This function must be called
%       prior to calls to the other JPL ephemeris functions.
%
%    REFERENCES:
%       Standish, E.M. and Newhall, X X (1988). "The JPL Export
%          Planetary Ephemeris"; JPL document dated 17 June 1988.
%
%    INPUT
%    ARGUMENTS:
%       *ephem_name (char)
%          Name of the direct-access ephemeris file.
%
%    OUTPUT
%    ARGUMENTS:
%       *jd_begin (double)
%          Beginning Julian date of the ephemeris file.
%       *jd_end (double)
%          Ending Julian date of the ephemeris file.
%       *de_number (short int)
%          DE number of the ephemeris file opened.
%
%    RETURNED
%    VALUE:
%       (short int)
%           0   ...file exists and is opened correctly.
%           1   ...file does not exist/not found.
%           2-10...error reading from file header.
%           11  ...unable to set record length; ephemeris (DE number)
%                  not in look-up table.
%
%    GLOBALS
%    USED:
%       SS                eph_manager.h
%       JPLAU             eph_manager.h
%       PC                eph_manager.h
%       VC                eph_manager.h
%       TWOT              eph_manager.h
%       EM_RATIO          eph_manager.h
%       BUFFER            eph_manager.h
%       IPT               eph_manager.h
%       LPT               eph_manager.h
%       NRL               eph_manager.h
%       KM                eph_manager.h
%       NP                eph_manager.h
%       NV                eph_manager.h
%       RECORD_LENGTH     eph_manager.h
%       EPHFILE           eph_manager.h
%
%    FUNCTIONS
%    CALLED:
%       fclose            stdio.h
%       free              stdlib.h
%       fopen             stdio.h
%       fread             stdio.h
%       calloc            stdlib.h
%
%    VER./DATE/
%    PROGRAMMER:
%       V1.0/06-90/JAB (USNO/NA)
%       V1.1/06-92/JAB (USNO/AA): Restructure and add initializations.
%       V1.2/07-98/WTH (USNO/AA): Modified to open files for different
%                                 ephemeris types. (200,403,404,405,406)
%       V1.3/11-07/WKP (USNO/AA): Updated prolog.
%       V1.4/09-10/WKP (USNO/AA): Changed ncon and denum variables and
%                                 sizeof ipt array to type 'int' for
%                                 64-bit system compatibility.
%       V1.5/09-10/WTH (USNO/AA): Added support for DE421, default case
%                                 for switch, close file on error.
%       V1.6/10-10/WKP (USNO/AA): Renamed function to lowercase to
%                                 comply with coding standards.
%
%    NOTES:
%       KM...flag defining physical units of the output states.
%          = 1, km and km/sec
%          = 0, AU and AU/day
%       Default value is 0 (KM determines time unit for nutations.
%                           Angle unit is always radians.)
%
% ------------------------------------------------------------------------
  persistent m;
  if isempty(m)
    m = containers.Map('KeyType','char','ValueType','any');
  end
  if nargin < 4
    dontSave = false;
  end
  s.de_number = 0;
  s.jd_begin = 0.0;
  s.jd_end = 0.0;
  if isnumeric(denum)
    denum = sprintf('%d',denum);
  end
  error = 0;
  if isempty(ineph)
    error = 1;
    return;
  elseif exist(ineph, 'file') ~= 2
    inasc = ineph;
    inasc(1:3) = 'asc';
    Ephem.asc2eph(denum,inasc,ineph);
  end
  if exist(ineph, 'file') == 2
    % found locally
    if m.isKey(ineph)
      st = m(ineph);
    else
      EPHFILE = fopen (ineph,'rb');
      if EPHFILE ~= -1
        for i=1:3
          [st.ttl{i},count] = fread (EPHFILE, Ephem.TTLsize, '*char');
          if count ~= Ephem.TTLsize
            error = 1;
            fprintf(2,'openDEeph: Error TTL retrieved %d from "%s", expected %d\n',...
              count,ineph,Ephem.TTLsize);
          end
          st.ttl{i} = strcat(transpose(st.ttl{i}));
        end
        % pos 252
        for i=1:Ephem.OLDCONMAX
          [st.CNAM{i},count] = fread (EPHFILE, Ephem.CNAMsize, '*char');
          if count ~= Ephem.CNAMsize
            error = 1;
            fprintf(2,'openDEeph: Error CNAM retrieved %d from "%s", expected %d\n',...
              count,ineph,Ephem.CNAMsize);
          end
          st.CNAM{i} = strcat(transpose(st.CNAM{i}));
        end
        % pos 2652
        [st.SS,count] = fread (EPHFILE, 3, 'double');
        if count ~= 3
          error = 1;
          fprintf(2,'openDEeph: Error SS retrieved %d from "%s", expected %d\n',...
            count,ineph,3);
        end
        [st.NCON,count] = fread (EPHFILE, 1, 'int32');
        if count ~= 1
          error = 1;
          fprintf(2,'openDEeph: Error NCON retrieved %d from "%s", expected %d\n',...
            count,ineph,1);
        end
        [st.JPLAU,count] = fread (EPHFILE, 1, 'double');
        if count ~= 1
          error = 1;
          fprintf(2,'openDEeph: Error JPLAU retrieved %d from "%s", expected %d\n',...
            count,ineph,1);
        end
        [st.EM_RATIO,count] = fread (EPHFILE, 1, 'double');
        if count ~= 1
          error = 1;
          fprintf(2,'openDEeph: Error EM_RATIO retrieved %d from "%s", expected %d\n',...
            count,ineph,1);
        end
        % pos 2652+8*3+4+8+8
        for i=1:12
          for j=1:3
            [st.IPT(j,i),count] = fread (EPHFILE, 1, 'int32');
            if count ~= 1
              error = 1;
              fprintf(2,'openDEeph: Error IPT retrieved %d from "%s", expected %d\n',...
                count,ineph,1);
            end
          end
        end
        % pos 2652+8*3+4+8+8+12*3*4
        [st.de_number,count] = fread (EPHFILE, 1, 'int32');
        st.de_number = sprintf('%d',st.de_number);
        if count ~= 1
          error = 1;
          fprintf(2,'openDEeph: Error de_number retrieved %d from "%s", expected %d\n',...
            count,ineph,1);
        end
        % pos 2652+8*3+4+8+8+12*3*4+4
        if strcmp(st.de_number,denum(1:min(length(st.de_number),length(denum)))) == false
          if s.output > 0
            fprintf(s.output,'openDEeph: Warning DE# retrieved %s from "%s", expected %s\n',...
              st.de_number,ineph,denum);
          end
        end
        [LPT,count] = fread (EPHFILE, 3, 'int32');
        if count ~= 3
          error = 1;
          fprintf(2,'openDEeph: Error LPT retrieved %d from "%s", expected %d\n',...
            count,ineph,3);
        end
        % pos 2652+8*3+4+8+8+12*3*4+4+3*4
        for i=Ephem.OLDCONMAX+1:st.NCON
          [st.CNAM{i},count] = fread (EPHFILE, Ephem.CNAMsize, '*char');
          if count ~= Ephem.CNAMsize
            error = 1;
            fprintf(2,'openDEeph: Error CNAM retrieved %d from "%s", expected %d\n',...
              count,ineph,Ephem.CNAMsize);
          end
          st.CNAM{i} = strcat(transpose(st.CNAM{i}));
        end
        [RPT,count] = fread (EPHFILE, 3, 'int32');
        if count ~= 3
          error = 1;
          fprintf(2,'openDEeph: Error RPT retrieved %d from "%s", expected %d\n',...
            count,ineph,3);
        end
        [TPT,count] = fread (EPHFILE, 3, 'int32');
        if count ~= 3
          error = 1;
          fprintf(2,'openDEeph: Error TPT retrieved %d from "%s", expected %d\n',...
            count,ineph,3);
        end
        for i=1:3
          st.IPT(i,13) = LPT(i);
          st.IPT(i,14) = RPT(i);
          st.IPT(i,15) = TPT(i);
        end
        st.NCOEFF = Ephem.numCoeff( st.IPT );
        st.RECORD_LENGTH = 8*st.NCOEFF;
        status = fseek(EPHFILE,(2-1)*st.RECORD_LENGTH,'bof');
        if status == -1
          fprintf(2,'openDEeph seek error at %d\n',2);
        end
        [st.CVAL,count] = fread (EPHFILE, st.NCON, 'double');
        if count ~= st.NCON
          error = 1;
          fprintf(2,'openDEeph: Error CVAL retrieved %d from "%s", expected %d\n',...
            count,ineph,st.NCON);
        end
        for i=1:st.NCON
          cnm = deblank(st.CNAM{i});
          indx = strfind(cnm,'.');
          for j=1:length(indx)
            cnm(indx(j)) = '_';
          end
          if ~isempty(cnm)
            st.(cnm) = st.CVAL(i);
          else
            st.('blank') = st.CVAL(i);
          end
        end
        st.masses(Ephem.Mercury) = st.GM1;
        st.masses(Ephem.Venus) = st.GM2;
        st.masses(Ephem.Mars) = st.GM4;
        st.masses(Ephem.Jupiter) = st.GM5;
        st.masses(Ephem.Saturn) = st.GM6;
        st.masses(Ephem.Uranus) = st.GM7;
        st.masses(Ephem.Neptune) = st.GM8;
        st.masses(Ephem.Pluto) = st.GM9;
        st.masses(Ephem.Sun) = st.GMS;
        st.masses(Ephem.EarthMoonBarycenter) = st.GMB;
        st.masses(Ephem.Moon) = st.GMB/(1+s.EM_RATIO);
        st.masses(Ephem.Earth) = st.GMB*s.EM_RATIO/(1+s.EM_RATIO);
        mm = 0;
        for i=Ephem.Mercury:Ephem.Sun
          mm = mm + st.masses(i);
        end
        st.masses(Ephem.SolarSystemBarycenter) = mm;

        pos = 1;
        status = fseek(EPHFILE,(3-1)*st.RECORD_LENGTH,'bof');
        if status == -1
          if s.output > 0
            fprintf(s.output,'openDEeph: Bad fseek of "%s"\n',ineph);
          end
          fclose (EPHFILE);
          error = 9;
          return;
        end
        st.scan = zeros(1,0);
        for NROUT = 3:281474976710655
          [sc,count] = fread (EPHFILE,st.NCOEFF,'double');
          if isempty(sc) || count == 0 % expected end
            break;
          end
          if st.NCOEFF ~= count
            fprintf(2,'openDEeph: Error COEFF retrieved %d from "%s", expected %d\n',...
              count,ineph,st.NCOEFF);
            %break;
          else
            for K=1:st.NCOEFF
              st.scan(pos) = sc(K);
              pos = pos + 1;
            end
          end
        end
        fclose (EPHFILE);
        if isempty(st.scan)
          if s.output > 0
            fprintf(s.output,'openDEeph: Bad textscan of "%s"\n',ineph);
          end
          error = 9;
          return;
        end
        if dontSave == false
          m(ineph) = st;
        end
      else
        if s.output > 0
          fprintf(s.output,'openDEeph: Could not open "%s"\n',ineph);
        end
        error = 10;
        return;
      end
    end
  else
    if s.output > 0
      fprintf(2,'openDEeph: Bad file access for "%s"\n',ineph);
    end
    error = 10;
    return;
  end

  s.scan = st.scan;
  s.SS = st.SS;
  s.de_number = denum;
  s.RECORD_LENGTH = st.RECORD_LENGTH;
  s.IPT = st.IPT;
  s.JPLAU = st.JPLAU;
  s.EM_RATIO = st.EM_RATIO;
  for i=Ephem.Mercury:Ephem.EarthMoonBarycenter
    s.masses(i) = st.masses(i);
  end

  s.jd_begin = s.SS(1);
  s.jd_end = s.SS(2);
  s.jd_inc = s.SS(3);
  s.numRecs =  1 + (s.jd_end-s.jd_begin)/s.jd_inc;
  if mod(s.numRecs,1.0) ~= 0
    if s.output > 0
      fprintf(s.output,'openDEeph: DE%s Bad jd_inc (%g) numRecs (%g) should be integer\n',...
        denum,s.indexInc,s.numRecs);
    end
    s.jd_begin = 0.0;
    s.jd_end = 0.0;
    s.jd_inc = 0.0;
    error = 12;
    return;
  end
  s.indexInc = s.RECORD_LENGTH / 8;
  s.indexOffset = -1;
end


function [resample] = resampledesign(cfg, design)

% RESAMPLEDESIGN returns a resampling matrix, in which each row can be
% used to resample either the original design matrix or the original data.
% The random resampling is done given user-specified constraints on the
% experimental design, e.g. to swap within paired observations but not
% between pairs.
%
% Use as
%   [resample] = randomizedesign(cfg, design)
% where the configuration can contain
%   cfg.resampling       = 'permutation' or 'bootstrap'
%   cfg.numrandomization = number (e.g. 300), can be 'all' in case of two conditions
%   cfg.ivar             = number or list with indices, independent variable(s)
%   cfg.uvar             = number or list with indices, unit variable(s)
%   cfg.wvar             = number or list with indices, within-cell variable(s)
%   cfg.cvar             = number or list with indices, control variable(s)
%
% The "Independent variable" codes the condition number. Since the data is
% assumed to be independent from the condition number any reshuffeling of
% the condition number is allowed and ivar does NOT affect the resampling
% outcome.
%
% The "Unit of observation variable" corresponds to the subject number (in a
% within-subject manipulation) or the trial number (in a within-trial
% manipulation). It is best understood by considering that it corresponds
% to the "pairing" of the data in a paired T-test or repeared measures
% ANOVA. The uvar affects the resampling outcome in the way that only
% resamplings within one unit of observation are returned (e.g. swap
% conditions within a subject, not over subjects).
%
% The "Within-cell variable" corresponds to the grouping of the data in
% cells, where the multiple observations in a groups should not be broken
% apart. This for example applies to multiple tapers in a spectral estimate
% of a single trial of data (the "rpttap" dimension), where different
% tapers should not be shuffled separately. Another example is a blocked
% fMRI design, with a different condition in each block and multiple
% repetitions of the same condition within a block. Assuming that there is
% a slow HRF that convolutes the trials within a block, you can shuffle the
% blocks but not the individual trials in a block.
%
% The "Control variable" can be seen as the opposite from the within-cell
% variable: it allows you to specify blocks in which the resampling should
% be done, at the same time controlling that repetitions are not shuffled
% between different control blocks.
%
% See also FT_STATISTICS_MONTECARLO

% Copyright (C) 2005-2020, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

ft_checkopt(cfg, 'ivar', {'numericscalar', 'numericvector', 'empty'});
ft_checkopt(cfg, 'uvar', {'numericscalar', 'numericvector', 'empty'});
ft_checkopt(cfg, 'wvar', {'numericscalar', 'numericvector', 'empty'});
ft_checkopt(cfg, 'cvar', {'numericscalar', 'numericvector', 'empty'});
ft_checkopt(cfg, 'numrandomization', {'numericscalar', 'char'});
ft_checkopt(cfg, 'resampling', {'char'});

cfg.ivar = ft_getopt(cfg, 'ivar'); % the default is empty
cfg.uvar = ft_getopt(cfg, 'uvar'); % the default is empty
cfg.wvar = ft_getopt(cfg, 'wvar'); % the default is empty
cfg.cvar = ft_getopt(cfg, 'cvar'); % the default is empty

% the default is 'no', consistent with the situation prior to 14 Sept 2011
% FIXME this needs finalization
efficient = ft_getopt(cfg, 'efficient', 'no');

% if size(design,1)>size(design,2)
%   % this function wants the replications in the column direction
%   % the matrix seems to be transposed
%   design = transpose(design);
% end

Nvar  = size(design,1);   % number of factors or regressors
Nrepl = size(design,2);   % number of replications

if ~isempty(intersect(cfg.ivar, cfg.uvar)), ft_warning('there is an intersection between cfg.ivar and cfg.uvar'); end
if ~isempty(intersect(cfg.ivar, cfg.wvar)), ft_warning('there is an intersection between cfg.ivar and cfg.wvar'); end
if ~isempty(intersect(cfg.ivar, cfg.cvar)), ft_warning('there is an intersection between cfg.ivar and cfg.cvar'); end
if ~isempty(intersect(cfg.uvar, cfg.wvar)), ft_warning('there is an intersection between cfg.uvar and cfg.wvar'); end
if ~isempty(intersect(cfg.uvar, cfg.cvar)), ft_warning('there is an intersection between cfg.uvar and cfg.cvar'); end
if ~isempty(intersect(cfg.wvar, cfg.cvar)), ft_warning('there is an intersection between cfg.wvar and cfg.cvar'); end

fprintf('total number of measurements     = %d\n', Nrepl);
fprintf('total number of variables        = %d\n', Nvar);
fprintf('number of independent variables  = %d\n', length(cfg.ivar));
fprintf('number of unit variables         = %d\n', length(cfg.uvar));
fprintf('number of within-cell variables  = %d\n', length(cfg.wvar));
fprintf('number of control variables      = %d\n', length(cfg.cvar));
fprintf('using a %s resampling approach\n', cfg.resampling);

if ~isempty(cfg.cvar)
  % the different levels of the control variable indicate the blocks in which the resampling can be done
  % the replications should not be resampled over the blocks
  blocklevel = unique(design(cfg.cvar,:)', 'rows')';
  for i=1:size(blocklevel,2)
    blocksel{i} = find(all(design(cfg.cvar,:)==repmat(blocklevel(:,i), 1, Nrepl), 1));
    blocklen(i) = length(blocksel{i});
  end
  for i=1:size(blocklevel,2)
    fprintf('------------------------------------------------------------\n');
    if length(cfg.cvar)>1
      fprintf('resampling the subset where the control variable level is [%s]\n', num2str(blocklevel(:,i)));
    else
      fprintf('resampling the subset where the control variable level is %s\n', num2str(blocklevel(:,i)));
    end
    % use recursion to resample the replications within each block
    tmpcfg = cfg;
    tmpcfg.cvar = [];
    blockres{i} = blocksel{i}(resampledesign(tmpcfg, design(:, blocksel{i})));
  end
  % concatenate the blocks and return the result
  resample = cat(2, blockres{:});
  return
end

if isnumeric(cfg.numrandomization) && cfg.numrandomization==0
  % no randomizations are requested, return an empty shuffling matrix
  resample = zeros(0,Nrepl);
  return;
end

if ~isempty(cfg.wvar)
  % keep the elements within a cell together, e.g. multiple tapers in a trial
  % this is realized by replacing the design matrix temporarily with a smaller version
  blkmeas = unique(design(cfg.wvar,:)', 'rows')';
  for i=1:size(blkmeas,2)
    blksel{i} = find(all(design(cfg.wvar,:)==repmat(blkmeas(:,i), 1, Nrepl), 1));
    blklen(i) = length(blksel{i});
  end
  if any(blklen~=blklen(1))
    ft_error('the number of repetitions per block should be constant');
  end
  for i=1:size(blkmeas,2)
    if any(diff(design(:, blksel{i}), 1, 2)~=0)
      ft_error('the design matrix variables should be constant within a block');
    end
  end
  orig_design = design;
  orig_Nrepl  = Nrepl;
  % replace the design matrix by a blocked version
  design = zeros(size(design,1), size(blkmeas,2));
  Nrepl  = size(blkmeas,2);
  for i=1:size(blkmeas,2)
    design(:,i) = orig_design(:, blksel{i}(1));
  end
end

% do some validity checks
if Nvar==1 && ~isempty(cfg.uvar)
  ft_error('A within-units shuffling requires a at least one unit variable and at least one independent variable');
end

if isempty(cfg.uvar) && strcmp(cfg.resampling, 'permutation')
  % reshuffle the colums of the design matrix
  if ischar(cfg.numrandomization) && strcmp(cfg.numrandomization, 'all')
    % systematically shuffle the columns in the design matrix
    Nperm = prod(1:Nrepl);
    fprintf('creating all possible permutations (%d)\n', Nperm);
    resample = perms(1:Nrepl);
  elseif ~ischar(cfg.numrandomization)
    % randomly shuffle the columns in the design matrix the specified number of times
    resample = zeros(cfg.numrandomization, Nrepl);
    for i=1:cfg.numrandomization
      resample(i,:) = randperm(Nrepl);
    end
  end

elseif isempty(cfg.uvar) && strcmp(cfg.resampling, 'bootstrap')
  % randomly draw with replacement, keeping the number of elements the same in each class
  % only the test under the null-hypothesis (h0) is explicitely implemented here
  % but the h1 test can be achieved using a control variable
  resample = zeros(cfg.numrandomization, Nrepl);
  for i=1:cfg.numrandomization
    resample(i,:) = randsample(1:Nrepl, Nrepl, true);
  end

elseif ~isempty(cfg.uvar) && strcmp(cfg.resampling, 'permutation')
  % reshuffle the colums of the design matrix, keep the rows of the design matrix with the unit variable intact
  unitlevel = unique(design(cfg.uvar,:)', 'rows')';
  for i=1:size(unitlevel,2)
    unitsel{i} = find(all(design(cfg.uvar,:)==repmat(unitlevel(:,i), 1, Nrepl), 1));
    unitlen(i) = length(unitsel{i});
  end
  if length(cfg.uvar)==1
    fprintf('repeated measurement in variable %d over %d levels\n', cfg.uvar, length(unitlevel));
    fprintf('number of repeated measurements in each level is '); fprintf('%d ', unitlen); fprintf('\n');
  else
    fprintf('repeated measurement in mutiple variables over %d levels\n', length(unitlevel));
    fprintf('number of repeated measurements in each level is '); fprintf('%d ', unitlen); fprintf('\n');
  end
  fprintf('the maximum number of unique permutations is %d\n', prod(unitlen));

  if ischar(cfg.numrandomization) && strcmp(cfg.numrandomization, 'all')
    % create all possible permutations by systematic assignment
    if any(unitlen~=2)
      % it would be possible to also implement it for other cases
      % but so far ther has not been a concrete need for it
      ft_error('cfg.numrandomization=''all'' is only supported for two repeated measurements');
    end
    Nperm = 2^(length(unitlevel));
    resample = zeros(Nperm, Nrepl);
    for i=1:Nperm
      flip  = dec2bin( i-1, length(unitlevel));
      for j=1:length(unitlevel)
        if     strcmp('0', flip(j))
          resample(i, unitsel{j}(1)) = unitsel{j}(1);
          resample(i, unitsel{j}(2)) = unitsel{j}(2);
        elseif strcmp('1', flip(j))
          resample(i, unitsel{j}(1)) = unitsel{j}(2);
          resample(i, unitsel{j}(2)) = unitsel{j}(1);
        end
      end
    end
    fprintf('generated all %d possible permutations\n', 2^(length(unitlevel)));

  elseif ~ischar(cfg.numrandomization)
    % see https://github.com/fieldtrip/fieldtrip/issues/1313
    if cfg.numrandomization > prod(unitlen)
      ft_warning('the number of randomizations (%d) is larger than the maximum number of unique permutations (%d), better use cfg.numrandomization=''all''', cfg.numrandomization, prod(unitlen))
    elseif cfg.numrandomization/prod(unitlen) > 0.5
      ft_warning('the number of randomizations (%d) is close to the maximum number of unique permutations (%d), better use cfg.numrandomization=''all''', cfg.numrandomization, prod(unitlen))
    end

    % create the desired number of permutations by random shuffling
    resample = zeros(cfg.numrandomization, Nrepl);
    for i=1:cfg.numrandomization
      for j=1:length(unitlevel)
        resample(i, unitsel{j}) = unitsel{j}(randperm(length(unitsel{j})));
      end
    end
    fprintf('generated %d random permutations\n', cfg.numrandomization);
  end

elseif length(cfg.uvar)==1 && strcmp(cfg.resampling, 'bootstrap') && isempty(cfg.cvar)
  % randomly draw with replacement, keeping the number of elements the same in each class
  % only the test under the null-hypothesis (h0) is explicitely implemented here
  % but the h1 test can be achieved using a control variable

  % FIXME allow for length(cfg.uvar)>1, does it make sense in the first place
  % bootstrap the units of observation
  units = design(cfg.uvar,:);
  for k = 1:length(unique(units))
    sel = find(units==k);
    indx(:,k) = sel;
    Nrep(k)   = length(sel);
  end
  resample = zeros(cfg.numrandomization, Nrepl);

  %sanity check on number of repetitions
  if any(Nrep~=Nrep(1)), ft_error('all units of observation should have an equal number of repetitions'); end

  if max(units(:))<20
    ft_warning('fewer than 20 units warrants explicit checking of double occurrences of ''bootstraps''');
    checkunique = 1;
  else
    checkunique = 0;
  end

  if ~checkunique
    for i=1:cfg.numrandomization
      tmp           = randsample(1:Nrepl/Nrep(1), Nrepl/Nrep(1), true);
      for k=1:size(indx,1)
        resample(i,indx(k,:)) = indx(k,tmp);
      end
    end
  else
    tmp = zeros(cfg.numrandomization*10, Nrepl/Nrep(1));
    for i=1:cfg.numrandomization*10
      tmp(i,:) = sort(randsample(1:Nrepl/Nrep(1), Nrepl/Nrep(1), true));
    end

    tmp = unique(tmp, 'rows');
    fprintf('found %d unique rows in bootstrap matrix of %d bootstraps', size(tmp,1), cfg.numrandomization*10);

    if size(tmp,1)<cfg.numrandomization
      fprintf('using only %d unique bootstraps\n', size(tmp,1));
      cfg.numrandomization = size(tmp,1);
      index = 1:size(tmp,1);
    else
      index = randperm(size(tmp,1));
      index = index(1:cfg.numrandomization);
    end

    tmp = tmp(index,:);
    for i=1:cfg.numrandomization
      for k=1:size(indx,1)
        resample(i,indx(k,:)) = indx(k,tmp(i,:));
      end
    end

  end

else
  ft_error('Unsupported configuration for resampling.');
end

if ~isempty(cfg.wvar)
  % switch back to the original design matrix and expand the resample ordering
  % matrix so that it reorders all elements within a cell together
  Nrepl  = orig_Nrepl;
  expand = zeros(size(resample,1), Nrepl);
  for i=1:size(resample,1)
    expand(i,:) = cat(2, blksel{resample(i,:)});
  end
  resample = expand;
  % replace the blocked version of the design by the original one
  design = orig_design;
  Nrepl  = orig_Nrepl;
end

% in some cases it is possible to reduce the number of permutations by taking only the ones that result in unique condition sequences
% but important is that the relative requencies of the condition sequences remains the same
if strcmp(efficient, 'yes')
  if numel(cfg.ivar)<1
    ft_error('this reqiures at least one independent variable to be specified (ivar)');
  end
  if numel(cfg.uvar)>0
    ft_error('this is not yet supported in combination with a unit of observation (uvar)');
  end

  original = zeros(size(resample,1), numel(cfg.ivar)*size(resample,2));
  for i=1:size(resample,1)
    for j=1:numel(cfg.ivar)
      sel = (1:Nrepl) + (j-1)*Nrepl;
      original(i,sel) = design(cfg.ivar(j), resample(i,:));
    end
  end

  [reduced, indx1, indx2] = unique(original, 'rows');
  % this returns the reduced condition sequences, where
  % indx1 contains for the reduced row number the original (last) row number
  % indx2 contains for the original condition sequences the reduced row number
  frequency = zeros(size(reduced,1),1);
  for i=1:size(reduced,1)
    frequency(i) = sum(indx2==i);
  end

  if all(frequency==frequency(1))
    % the relative frequency of the reduced condition sequences is the same
    % as the relative frequency of the original condition sequences, which
    % means that the reduced set of permutations is appropriate
    fprintf('using the reduced set of permutations (%d) instead of the original permutations (%d)\n', size(reduced,1), size(resample,1));
    resample = resample(indx1,:);
  else
    % don't use the reduced set of permutations
    fprintf('the reduced set has different relative frequencies of the conditions, retaining the original permutations\n')
  end
end % if efficient


%%*****************************************************************************
%% HSDsqlpcheckconvg: check convergence.
%%
%% ZpATynorm, AX, normX, normZ are with respect to the
%% original variables, not the HSD variables.
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************************

function [param,breakyes,use_olditer,msg] = HSDsqlpcheckconvg(param,runhist)

termcode    = param.termcode;
iter        = param.iter;
obj         = param.obj;
relgap      = param.relgap;
gap         = param.gap;
prim_infeas = param.prim_infeas;
dual_infeas = param.dual_infeas;
mu          = param.mu;
prim_infeas_bad = param.prim_infeas_bad;
dual_infeas_bad = param.dual_infeas_bad;
printlevel  = param.printlevel;
stoplevel   = param.stoplevel;
inftol      = param.inftol;
gaptol      = param.gaptol;
kap         = param.kap;
tau         = param.tau;
theta       = param.theta;
breakyes    = 0;
use_olditer = 0;
msg         = [];
infeas      = max(prim_infeas,dual_infeas);
prim_infeas_min = min(param.prim_infeas_min, max(prim_infeas,1e-10));
dual_infeas_min = min(param.dual_infeas_min, max(dual_infeas,1e-10));
%%
err = max(infeas,relgap);
if (obj(2) > 0); homRd = param.ZpATynorm/obj(2); else homRd = inf; end
if (obj(1) < 0); homrp = norm(param.AX)/(-obj(1)); else homrp = inf; end
if (param.normX > 1e15*param.normX0 || param.normZ > 1e15*param.normZ0)
    termcode = 3;
    breakyes = 1;
end
if (homRd < min(1e-6,1e-2*sqrt(err*inftol)) && tau < 1e-4 ...
        && prim_infeas > 0.5*runhist.pinfeas(iter)) ...
        || (homRd < 10*tau && tau < 1e-7)
    termcode = 1;
    breakyes = 1;
end
if (homrp < min(1e-6,1e-2*sqrt(err*inftol)) && tau < 1e-4 ...
        && dual_infeas > 0.5*runhist.dinfeas(iter)) ...
        || (homrp < 10*tau && tau < 1e-7)
    termcode = 2;
    breakyes = 1;
end
if (err < gaptol)
    msg = sprintf('Stop: max(relative gap,infeasibilities) < %3.2e',gaptol);
    if (printlevel); fprintf('\n  %s',msg); end
    termcode = 0;
    breakyes = 1;
end
min_prim_infeas = min(runhist.pinfeas(1:iter));
prim_infeas_bad = prim_infeas_bad + (prim_infeas > ...
    max(1e-10,5*min_prim_infeas) && (min_prim_infeas < 1e-2));
if (mu < 1e-6)
    idx = max(1,iter-1): iter;
elseif (mu < 1e-3);
    idx = max(1,iter-2): iter;
else
    idx = max(1,iter-3): iter;
end
idx2 = max(1,iter-4): iter;
gap_ratio2 = runhist.gap(idx2+1)./runhist.gap(idx2);
gap_slowrate = min(0.8,max(0.6,2*mean(gap_ratio2)));
gap_ratio = runhist.gap(idx+1)./runhist.gap(idx);
pstep = runhist.step(iter+1);
if (infeas < 1e-4 || prim_infeas_bad) && (relgap < 1e-3) ...
        && (iter > 5) && (prim_infeas > (1-pstep/2)*runhist.pinfeas(iter))
    gap_slow = all(gap_ratio > gap_slowrate) && (relgap < 1e-3);
    min_pinfeas = min(runhist.pinfeas);
    if (relgap < 0.1*infeas) ...
            && ((runhist.step(iter+1) < 0.5) || (min_pinfeas < min(1e-6,0.1*prim_infeas))) ...
            && (dual_infeas > 0.9*runhist.dinfeas(iter) || (dual_infeas < 1e-2*gaptol))
        msg = 'Stop: relative gap < infeasibility';
        if (printlevel); fprintf('\n  %s',msg); end
        termcode = -1;
        breakyes = 1;
    elseif (gap_slow) && (infeas > 0.9*runhist.infeas(iter)) ...
            && (theta < 1e-8)
        msg = 'Stop: progress is too slow';
        if (printlevel); fprintf('\n  %s',msg); end
        termcode = -5;
        breakyes = 1;
    end
elseif (prim_infeas_bad) && (iter >50) && all(gap_ratio > gap_slowrate)
    msg = 'Stop: progress is bad';
    if (printlevel); fprintf('\n  %s',msg); end
    termcode = -5;
    breakyes = 1;
elseif (infeas < 1e-8) && (gap > 1.2*mean(runhist.gap(idx)))
    msg = 'Stop: progress is bad*';
    if (printlevel); fprintf('\n  %s',msg); end
    termcode = -5;
    breakyes = 1;
end
if (err < 1e-3) && (iter > 10) ...
        && (runhist.pinfeas(iter+1) > 0.9*runhist.pinfeas(max(1,iter-5))) ...
        && (runhist.dinfeas(iter+1) > 0.9*runhist.dinfeas(max(1,iter-5))) ...
        && (runhist.relgap(iter+1)  > 0.1*runhist.relgap(max(1,iter-5)));
    msg = 'Stop: progress is bad**';
    if (printlevel); fprintf('\n  %s',msg); end
    termcode = -5;
    breakyes = 1;
end
if (infeas > 100*max(1e-12,min(runhist.infeas)) && relgap < 1e-4)
    msg = 'Stop: infeas has deteriorated too much';
    if (printlevel); fprintf('\n  %s, %3.1e',msg,infeas); end
    use_olditer = 1;
    termcode = -7;
    breakyes = 1;
end
if (min(runhist.infeas) < 1e-4 || prim_infeas_bad) ...
        && (max(runhist.infeas) > 1e-4) && (iter > 5)
    relgap2 = abs(diff(obj))/(1+mean(abs(obj)));
    if (relgap2 < 1e-3);
        step_short = all(runhist.step(iter:iter+1) < 0.1) ;
    elseif (relgap2 < 1)
        idx = max(1,iter-3): iter+1;
        step_short = all(runhist.step(idx) < 0.05);
    else
        step_short = 0;
    end
    if (step_short)
        msg = 'Stop: steps too short consecutively';
        if (printlevel); fprintf('\n  %s',msg); end
        termcode = -5;
        breakyes = 1;
    end
end
if (iter > 3 && iter < 20) && (max(runhist.step(max(1,iter-3):iter+1)) < 1e-3) ...
        && (infeas > 1) && (min(homrp,homRd) > 1000*inftol)
    if (stoplevel >= 2)
        msg = 'Stop: steps too short consecutively';
        if (printlevel); fprintf('\n  %s',msg); end
        termcode = -5;
        breakyes = 1;
    end
end
if (pstep < 1e-4) && (err > 1.1*max(runhist.relgap(iter),runhist.infeas(iter)))
    msg = 'Stop: steps are too short';
    if (printlevel); fprintf('\n  %s',msg); end
    use_olditer = 1;
    termcode = -5;
    breakyes = 1;
end
if (iter == param.maxit)
    termcode = -6;
    msg = 'Stop: maximum number of iterations reached';
    if (printlevel); fprintf('\n  %s',msg); end
end
if (infeas < 1e-8 && relgap < 1e-10 && kap < 1e-13 && theta < 1e-15)
    msg = 'Stop: obtained accurate solution';
    if (printlevel); fprintf('\n  %s',msg); end
    termcode = 0;
    breakyes = 1;
end
param.prim_infeas_bad = prim_infeas_bad;
param.prim_infeas_min = prim_infeas_min;
param.dual_infeas_bad = dual_infeas_bad;
param.dual_infeas_min = dual_infeas_min;
param.termcode = termcode;
%%*****************************************************************************