%%   FDI Wind Turbines
% This script containing parameters for Bench Mark Model By Peter Fogh
% Odgaard, kk-electronic a/s, Viby J Denmark -Date 7.11.2008-
% with little modification by Nassim Laouti Date 13.11.2010
% Latest modification Date 16.02.2012

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
c3=10;c4=1000;P_r=4.8e6;
% Simple time and time
Ts=1/100;Time=Ts:Ts:4400;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Wind data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
D_v_wind=[Time', 9+4*sin(0.01*Time)'];

load winddata
D_v_wind=[windtime windspeed];

%% Wind Model
seed1 = 256;
seed2 = 894;
turbulence_seeds=[seed1 seed2];
R=57.5;
H=87;
k =4.7;
a=2.2;
alpha = 0.1;
D_rotor=2*R;
r = D_rotor/2;
m = 1+alpha*(alpha-1)*R^2/(8*H^2);
Length_scale = 600; %[m]
L=Length_scale;
Turbulence_intensity = 12;
turb_int=Turbulence_intensity;
T_sample=0.05;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Pitch and Blade Model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
omega_n=11.11;xi=0.6;rho=1.225;
R=57.5;r0 = 1.5;

% cq table
load AeroDynamics

% Fault models
% Fault 6
xi2=0.45;omega_n2=5.73;
% Fault 7
xi3=0.9;omega_n3=3.42;

%transfers to ss models
[Apb,Bpb,Cpb,Dpb]=tf2ss([omega_n^2],[1 2*xi*omega_n omega_n^2]);
[Apb1,Bpb1,Cpb1,Dpb1]=tf2ss([omega_n2^2],[1 2*xi2*omega_n2 omega_n2^2]);
[Apb2,Bpb2,Cpb2,Dpb2]=tf2ss([omega_n3^2],[1 2*xi3*omega_n3 omega_n3^2]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Drive Train Model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
B_dt=775.49;
B_r=7.11;
B_g=45.6;
N_g=95;
K_dt=2.7e9
eta_dt=0.97;
J_g=390
J_r=55e6

Addt=[-(B_dt+B_r)/J_r B_dt/N_g/J_r -K_dt/J_r; eta_dt*B_dt/N_g/J_g -(eta_dt*B_dt/N_g^2+B_g)/J_g eta_dt*K_dt/N_g/J_g; 1 -1/N_g 0];
Bddt=[1/J_r 0; 0 -1/J_g;0 0];
Cddt=[1 0 0;0 1 0];
Dddt=[0 0;0 0];

% Fault models
% Fault 9
eta_dt2=.91

Addt2=[-(B_dt+B_r)/J_r B_dt/N_g/J_r -K_dt/J_r; eta_dt2*B_dt/N_g/J_g -(eta_dt2*B_dt/N_g^2+B_g)/J_g eta_dt2*K_dt/N_g/J_g; 1 -1/N_g 0];
Bddt2=[1/J_r 0; 0 -1/J_g;0 0];
Cddt2=[1 0 0;0 1 0];
Dddt2=[0 0;0 0];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generator & Converter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
alpha_gc=1/20e-3;
eta_gc=0.98;

%Fault models
%fault 8
Constant_tau_gc=100;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Controller
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
K_opt=.5* rho* pi*R^2*eta_dt*R^3*0.4554/(N_g*8)^3

K_i=1;
K_p=4;
Omega_nom=162;
Omega_delta=5;
P_r=4.8e6;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Sensors
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
m_vw=1.5;
sigma_vm=0.5;
m_omega_r=0;
sigma_omega_r=0.004*2*pi;
m_omega_g=0;
sigma_omega_g=0.05;
m_tau_g=0;
sigma_tau_g=90;
m_P_g=0;
sigma_P_g=1e3;
m_Beta=0;
sigma_Beta=0.2;

%% Fault models (choose the scenario of fault parameters and magnitude)

% %1st fault scenario
% Constant_Beta_1_m1=5;Gain_Beta_2_m2=1.2;Constant_Beta_3_m1=10;Constant_Omega_r_m1=1.4;Gain_Omega_r_m2=1.1;Gain_Omega_g_m2=0.9;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=100;eta_dt2=.92;Constant_Omega_g_m1=140;

% %2nd fault scenario
% Constant_Beta_1_m1=6;Gain_Beta_2_m2=1.5;Constant_Beta_3_m1=8;Constant_Omega_r_m1=0.2;Gain_Omega_r_m2=1.2;Gain_Omega_g_m2=0.8;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=100;eta_dt2=.71;Constant_Omega_g_m1=80;

%3rd fault scenario
Constant_Beta_1_m1=4;Gain_Beta_2_m2=1.8;Constant_Beta_3_m1=12;Constant_Omega_r_m1=1.2;Gain_Omega_r_m2=0.7;Gain_Omega_g_m2=1.7;
xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=700;eta_dt2=0.3;Constant_Omega_g_m1=100;

%4th fault scenario
% Constant_Beta_1_m1=2;Gain_Beta_2_m2=3;Constant_Beta_3_m1=15;Constant_Omega_r_m1=1.7;Gain_Omega_r_m2=1.7;Gain_Omega_g_m2=0.7;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=-500;eta_dt2=.6;Constant_Omega_g_m1=130;

% %5th fault scenario
% Constant_Beta_1_m1=-5;Gain_Beta_2_m2=10;Constant_Beta_3_m1=3;Constant_Omega_r_m1=2.5;Gain_Omega_r_m2=0.9;Gain_Omega_g_m2=0.2;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=1500;eta_dt2=.25;Constant_Omega_g_m1=120;

%6th fault scenario
% Constant_Beta_1_m1=1;Gain_Beta_2_m2=2;Constant_Beta_3_m1=6;Constant_Omega_r_m1=0.5;Gain_Omega_r_m2=0.2;Gain_Omega_g_m2=2.8;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=2500;eta_dt2=0.1;Constant_Omega_g_m1=150;

% % %7th fault scenario
% Constant_Beta_1_m1=24;Gain_Beta_2_m2=5;Constant_Beta_3_m1=20;Constant_Omega_r_m1=3.5;Gain_Omega_r_m2=3;Gain_Omega_g_m2=5;
% xi2=0.25;omega_n2=8.73;xi3=0.95;omega_n3=1.42;Constant_tau_gc=900;eta_dt2=0.4;Constant_Omega_g_m1=50;

%8th fault scenario
% Constant_Beta_1_m1=-3;Gain_Beta_2_m2=5;Constant_Beta_3_m1=7;Constant_Omega_r_m1=2;Gain_Omega_r_m2=0.5;Gain_Omega_g_m2=1.5;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=-1000;eta_dt2=0.22;Constant_Omega_g_m1=100;

% %9th fault scenario
% Constant_Beta_1_m1=2;Gain_Beta_2_m2=3;Constant_Beta_3_m1=7;Constant_Omega_r_m1=2;Gain_Omega_r_m2=0.5;Gain_Omega_g_m2=1.5;
% xi2=0.45;omega_n2=5.73;xi3=0.9;omega_n3=3.42;Constant_tau_gc=800;eta_dt2=0.42;Constant_Omega_g_m1=110;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[Apb1,Bpb1,Cpb1,Dpb1]=tf2ss([omega_n2^2],[1 2*xi2*omega_n2 omega_n2^2]);
[Apb2,Bpb2,Cpb2,Dpb2]=tf2ss([omega_n3^2],[1 2*xi3*omega_n3 omega_n3^2]);
%
Addt2=[-(B_dt+B_r)/J_r B_dt/N_g/J_r -K_dt/J_r; eta_dt2*B_dt/N_g/J_g -(eta_dt2*B_dt/N_g^2+B_g)/J_g eta_dt2*K_dt/N_g/J_g; 1 -1/N_g 0];
Bddt2=[1/J_r 0; 0 -1/J_g;0 0];
Cddt2=[1 0 0;0 1 0];
Dddt2=[0 0;0 0];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Fault signals (choose the scenario of fault appearance)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %1st fault scenario
% D_Fault1=[Time' 1-[zeros(1,2000/Ts) ones(1,100/Ts) zeros(1,2300/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,2300/Ts) ones(1,100/Ts) zeros(1,2000/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,2600/Ts) ones(1,100/Ts) zeros(1,1700/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,1500/Ts) ones(1,100/Ts) zeros(1,2800/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,1000/Ts) ones(1,100/Ts) zeros(1,3300/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,2900/Ts) ones(1,100/Ts) zeros(1,1400/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,3800/Ts) ones(1,100/Ts) zeros(1,500/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,4000/Ts) ones(1,200/Ts) zeros(1,200/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,3600/Ts) ones(1,100/Ts) zeros(1,700/Ts) ]'];

%%2nd fault scenario
% D_Fault1=[Time' 1-[zeros(1,1000/Ts) ones(1,100/Ts) zeros(1,3300/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,3900/Ts) ones(1,100/Ts) zeros(1,400/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,1600/Ts) ones(1,100/Ts) zeros(1,2700/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,500/Ts) ones(1,100/Ts) zeros(1,3800/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,4000/Ts) ones(1,100/Ts) zeros(1,300/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,2900/Ts) ones(1,100/Ts) zeros(1,1400/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,1800/Ts) ones(1,100/Ts) zeros(1,2500/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,3000/Ts) ones(1,200/Ts) zeros(1,1200/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,2600/Ts) ones(1,100/Ts) zeros(1,1700/Ts) ]'];

%3nd fault scenario
D_Fault1=[Time' 1-[zeros(1,100/Ts) ones(1,100/Ts) zeros(1,4200/Ts)]'];
D_Fault2=[Time' 1-[zeros(1,2500/Ts) ones(1,100/Ts) zeros(1,1800/Ts)]'];
D_Fault3=[Time' 1-[zeros(1,900/Ts) ones(1,100/Ts) zeros(1,3400/Ts)]'];
D_Fault4=[Time' 1-[zeros(1,1200/Ts) ones(1,100/Ts) zeros(1,3100/Ts)]'];
D_Fault5=[Time' 1-[zeros(1,1700/Ts) ones(1,100/Ts) zeros(1,2600/Ts)]'];
D_Fault6=[Time' 1-[zeros(1,3200/Ts) ones(1,100/Ts) zeros(1,1100/Ts)]'];
D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
D_Fault8=[Time' 1-[zeros(1,4200/Ts) ones(1,100/Ts) zeros(1,100/Ts)]'];
D_Fault9=[Time' 1-[zeros(1,2000/Ts) ones(1,200/Ts) zeros(1,2200/Ts)]'];
D_Fault10=[Time' 1-[zeros(1,3900/Ts) ones(1,100/Ts) zeros(1,400/Ts)]'];

% %4th fault scenario
% D_Fault1=[Time' 1-[zeros(1,250/Ts) ones(1,100/Ts) zeros(1,4050/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,3200/Ts) ones(1,100/Ts) zeros(1,1100/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,1000/Ts) ones(1,100/Ts) zeros(1,3300/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,800/Ts) ones(1,100/Ts) zeros(1,3500/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,2200/Ts) ones(1,100/Ts) zeros(1,2100/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,2800/Ts) ones(1,100/Ts) zeros(1,1500/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,1200/Ts) ones(1,100/Ts) zeros(1,3100/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,3900/Ts) ones(1,200/Ts) zeros(1,300/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,4200/Ts) ones(1,100/Ts) zeros(1,100/Ts)]'];

% %5th fault scenario
% D_Fault1=[Time' 1-[zeros(1,3000/Ts) ones(1,100/Ts) zeros(1,1300/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,1300/Ts) ones(1,100/Ts) zeros(1,3000/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,500/Ts) ones(1,100/Ts) zeros(1,3800/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,200/Ts) ones(1,100/Ts) zeros(1,4100/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,2000/Ts) ones(1,100/Ts) zeros(1,2300/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,3600/Ts) ones(1,100/Ts) zeros(1,700/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,2400/Ts) ones(1,100/Ts) zeros(1,1900/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,2700/Ts) ones(1,200/Ts) zeros(1,1500/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,3300/Ts) ones(1,100/Ts) zeros(1,1000/Ts)]'];

% % %6th fault scenario
% D_Fault1=[Time' 1-[zeros(1,3800/Ts) ones(1,100/Ts) zeros(1,500/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,2600/Ts) ones(1,100/Ts) zeros(1,1700/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,4000/Ts) ones(1,100/Ts) zeros(1,300/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,2900/Ts) ones(1,100/Ts) zeros(1,1400/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,600/Ts) ones(1,100/Ts) zeros(1,3700/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,1500/Ts) ones(1,100/Ts) zeros(1,2800/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,1800/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,2500/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,100/Ts) ones(1,100/Ts) zeros(1,4200/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,2000/Ts) ones(1,200/Ts) zeros(1,2200/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,3500/Ts) ones(1,100/Ts) zeros(1,800/Ts)]'];
%
% %7th fault scenario
% D_Fault1=[Time' 1-[zeros(1,4200/Ts) ones(1,100/Ts) zeros(1,100/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,4000/Ts) ones(1,100/Ts) zeros(1,300/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,3700/Ts) ones(1,100/Ts) zeros(1,600/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,3500/Ts) ones(1,100/Ts) zeros(1,800/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,3000/Ts) ones(1,100/Ts) zeros(1,1300/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,2700/Ts) ones(1,100/Ts) zeros(1,1600/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,2500/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,1800/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,2100/Ts) ones(1,100/Ts) zeros(1,2200/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,1400/Ts) ones(1,200/Ts) zeros(1,2800/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,1000/Ts) ones(1,100/Ts) zeros(1,3300/Ts)]'];

% % 8th fault scenario
% D_Fault1=[Time' 1-[zeros(1,100/Ts) ones(1,100/Ts) zeros(1,4200/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,500/Ts) ones(1,100/Ts) zeros(1,3800/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,900/Ts) ones(1,100/Ts) zeros(1,3400/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,1200/Ts) ones(1,100/Ts) zeros(1,3100/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,1700/Ts) ones(1,100/Ts) zeros(1,2600/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,2900/Ts) ones(1,100/Ts) zeros(1,1400/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,3400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,4200/Ts) ones(1,100/Ts) zeros(1,100/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,300/Ts) ones(1,200/Ts) zeros(1,3900/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,2200/Ts) ones(1,100/Ts) zeros(1,2100/Ts)]'];

% 9th fault scenario

% D_Fault2=[Time' 1-[zeros(1,100/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,2330/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,1830/Ts) ]'];
% Offset_Beta_2_m2=[Time' [zeros(1,100/Ts) 0.5*ones(1,10/Ts) zeros(1,5/Ts) 1*ones(1,10/Ts) zeros(1,5/Ts) 1.5*ones(1,10/Ts) zeros(1,5/Ts) 2*ones(1,10/Ts) zeros(1,5/Ts) 3*ones(1,10/Ts) zeros(1,2330/Ts) 0.5*ones(1,10/Ts) zeros(1,5/Ts) 1*ones(1,10/Ts) zeros(1,5/Ts) 1.5*ones(1,10/Ts) zeros(1,5/Ts) 2*ones(1,10/Ts) zeros(1,5/Ts) 3*ones(1,10/Ts) zeros(1,1830/Ts) ]'];
%
% D_Fault5=[Time' 1-[zeros(1,500/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,2330/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,5/Ts) ones(1,10/Ts) zeros(1,1430/Ts) ]'];
% Offset_Omega_r_m2=[Time' [zeros(1,500/Ts) 0.1*ones(1,10/Ts) zeros(1,5/Ts) 0.2*ones(1,10/Ts) zeros(1,5/Ts) 0.5*ones(1,10/Ts) zeros(1,5/Ts) 1*ones(1,10/Ts) zeros(1,5/Ts) 2*ones(1,10/Ts) zeros(1,2330/Ts) 0.1*ones(1,10/Ts) zeros(1,5/Ts) 0.2*ones(1,10/Ts) zeros(1,5/Ts) 0.5*ones(1,10/Ts) zeros(1,5/Ts) 1*ones(1,10/Ts) zeros(1,5/Ts) 2*ones(1,10/Ts) zeros(1,1430/Ts) ]'];
% Offset_Omega_g_m2=[Time' [zeros(1,500/Ts) 2.5*ones(1,10/Ts) zeros(1,5/Ts) 4*ones(1,10/Ts) zeros(1,5/Ts) 5*ones(1,10/Ts) zeros(1,5/Ts) 6*ones(1,10/Ts) zeros(1,5/Ts) 8*ones(1,10/Ts) zeros(1,2330/Ts) 2.5*ones(1,10/Ts) zeros(1,5/Ts) 4*ones(1,10/Ts) zeros(1,5/Ts) 5*ones(1,10/Ts) zeros(1,5/Ts) 6*ones(1,10/Ts) zeros(1,5/Ts) 8*ones(1,10/Ts) zeros(1,1430/Ts) ]'];

% D_Fault1=[Time' 1-[zeros(1,300/Ts) ones(1,100/Ts) zeros(1,4000/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,700/Ts) ones(1,100/Ts) zeros(1,3600/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,1000/Ts) ones(1,100/Ts) zeros(1,3300/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,1900/Ts) ones(1,100/Ts) zeros(1,2400/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,1400/Ts) (0:1/3000:2999/3000) ones(1,40/Ts) (2999/3000:-1/3000:0) zeros(1,2900/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,4200/Ts) ones(1,100/Ts) zeros(1,100/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,3300/Ts) ones(1,200/Ts) zeros(1,900/Ts)]'];
% D_Fault10=[Time' 1-[zeros(1,2200/Ts) ones(1,100/Ts) zeros(1,2100/Ts)]'];

% %without Fault
% D_Fault1=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault2=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault3=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault4=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault5=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault6=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault7=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault8=[Time' 1-[zeros(1,4400/Ts)]'];
% D_Fault9=[Time' 1-[zeros(1,4400/Ts)]'];
%  D_Fault10=[Time' 1-[zeros(1,4400/Ts)]'];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Noise Seeds
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

min_seed = 0;
max_seed = 999;
% Generate random seeds for 13 'Random Number' Generators blocks
seed = min_seed + (max_seed-min_seed).*rand(13, 1);
% Round up to integer
seed = ceil(seed);

%% Simulation
open_system('FDI_measures.mdl');

tic
sim('FDI_measures.mdl');
toc


function shCoeff = ShearTransform3D(X,shearingFilter)
level=size(shearingFilter,2);
shCoeff.D=cell(3,level);

%Do the Band Pass of noisy Data
BP=DoPyrDec(X,level);
shCoeff.A=BP{1};
for pyrCone=1:3
  shCoeff.D(pyrCone,:) = ShDec(pyrCone,shearingFilter,BP,level,'single');
end


 function F_enhance= RMSHEg_gray( F )
% clear all;
% close all;
% clc;
x0=F;
%x0=imread('om.bmp');
%x0=imread('11.bmp');
 %x0=imread('12.bmp');
%y0=rgb2ycbcr(x0);
luma=x0;%(:,:,1);
[m,n]=size(luma);
% cb=y0(:,:,2);
% cr=y0(:,:,3);
k=mean(mean(luma));
XM=k;
r=round(k);
l=length(luma(luma<=r));
         listindex=find(luma<=r);
 k1=reshape(luma(listindex),l,1);%obtained below fist mean values put it into an arry
 k2=mean(k1);%find mean of mean in first half
 k3=round(k2);%round to nearest integer to find pdf and cdf till first quarter
  sum=0;
 l1=length(luma(luma<=k3));%find all  values in luma falls below fist mean
 listindex1=find(luma<=k3);%all  values in luma falls below fist mean given in their locations
 k4=reshape(luma(listindex1),l1,1);%arrange all fist mean values in a vector
     xpdf=hist(k4,[0:k3]);%pdf from 0:r
      xpdf=xpdf/l1;%normalized pdf to get nk/n,l=sum of xpdf,total no of pixels form 0 to r.
     % plot(xpdf);
%      plot(imhist(luma));
%       xlabel('gray levels up to mean');
%       ylabel('pdf up to mean');
%       title('histogram for half an image up to mean');
      sk=xpdf*triu(ones(k3+1));
%       figure(2);
%       plot(sk);
%       xlabel('gray levels upto 1st mean');
%       ylabel('cdf upto mean');
%       title('cdf for half  of an image up to ist mean');
      alpha=0.6;
      for l2=0:k3
              list1=find(k4==l2);%find value in an vector i.e converted from matrix
              %list(list1)=alpha*sk(l2+1)*(k3+1)+(1-alpha)*(k3+1);
              list(list1)=sk(l2+1)*(k3+1);%map dont disturb to get bhe as
              %it is 13/3/2011
              ert(l2+1)=sk(l2+1)*(k3+1);
      end
          p=zeros(m,n);
      p(listindex1)= list;
%      figure(3);
%      imshow(p);
%      xlabel('gray levels up to first mean');
%       ylabel('luma component equilized image up to first mean');
%      title('processed luma image up to first mean');
     k=mean(mean(luma));
r=round(k);
l=length(luma(luma<=r));
        listindex=find(luma<=r);
 k1=reshape(luma(listindex),l,1);%obtained below fist mean values put it into an arry
 k2=mean(k1);%find mean of mean in first half
 k3=round(k2);%round to nearest integer to find pdf and cdf till first quarter
%   sum=0;
   b=k3;
%  l2=length(luma(luma>k3));%find all  values in luma falls below fist mean
  listindex2=find((luma>k3)&(luma<=r));%all  values in luma falls below fist mean given in their locations
  l2=length(listindex2);
  k5=reshape(luma(listindex2),l2,1);%arrange all fist mean values in a vector
      x2pdf=hist(k5,[k3+1:r]);%pdf from 0:r
       x2pdf=x2pdf/l2;%normalized pdf to get nk/n,l=sum of xpdf,total no of pixels form 0 to r.
%        figure(4);
%        plot(x2pdf);
%        xlabel('gray levels 2nd mean');
%        ylabel('pdf of 2nd mean');
%        title('histogram for 2nd mean');
       sk2=x2pdf*triu(ones(r-k3));
%        figure(5);
%        plot(sk2);
%        xlabel('gray levels of 2nd mean');
%        ylabel('cdf upto mean');
%        title('cdf for half  of an image of 2nd mean');
       k2u=1;
       for l3=k3+1:r
               list2=find(k5==l3);%find value in an vector i.e converted from matrix
               %list1(list2)=alpha*(sk2(k2u)*(r-k3)+(k3+1))+(1-alpha)*(k3+1);
               list1(list2)=(k3+1)+(sk2(k2u))*(r-k3);%map dont disturb to
               %get BHE 13/3/2011
               ert(l3)=(k3+1)+(sk2(k2u))*(r-k3);
               k2u=k2u+1;
       end
           p1=zeros(m,n);
       p1(listindex2)= list1;
%       figure(6);
%       imshow(p1);
%      xlabel('gray levels up to first 2nd mean');
%       ylabel('luma component equilized image 2nd mean');
%      title('processed luma image up to 2nd mean');
 %lupper30=length(luma(luma>r);
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 lupper30=length(luma(luma>r));
%for i=0:r
    %if(luma(luma<=r))
        listindexupper3=find(luma>r);
   % end
%end
 k1upper=reshape(luma(listindexupper3),lupper30,1);
 mean3=mean(k1upper);
  r3=round(mean3);
 %length30=length((luma<=r3)&(luma>r));
  listindexupper30=find((luma>r)&(luma<=r3));
  length30=length(listindexupper30);
  k30upper=reshape(luma(listindexupper30),length30,1);

  %length30=length((luma<=r3)&(luma>r));
%  sum=0;
      xpdfupper30=hist(k30upper,[r+1:r3]);%pdf from r+1:r3
      xpdfupper30=xpdfupper30/length30;%normalized pdf to get nk/n,l=sum of xpdf,total no of pixels form r+1 to 255.
%       figure(7);
%      plot(xpdfupper30);
%      xlabel('gray levels   3rd mean');
%      ylabel('pdf of 3rd mean');
%      title('histogram for upper half an image  3rd mean');
      skupper30=xpdfupper30*triu(ones(r3-r));
%       figure(8);
%       plot(skupper30);
%       xlabel('gray levels after mean');
%       ylabel('cdf after mean');
%       title('cdf for upper half  of an image after mean');
      k3u=1;
      for k3upper=(r+1):r3
              list1upper30=find(k30upper==k3upper);%find value in an vector i.e converted from matrix
              listnew(list1upper30)=(r+1)+skupper30(k3u)*(r3-r);%map dont
              %disturg to get original heq 14/3/2011
              %listnew(list1upper30)=alpha*(skupper30(k3u)*(r3-r)+(r+1))+(1-alpha)*(r+1);
              ert(k3upper)=(r+1)+skupper30(k3u)*(r3-r);
         k3u=k3u+1;
     end

          p2=zeros(m,n);

     p2(listindexupper30)= listnew;
%     figure(9);
%      imshow(p2);
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     listindexupper40=find(luma>r3);
     lupper40=length(listindexupper40);
   % end
%end
 k1upper40=reshape(luma(listindexupper40),lupper40,1);
 %sum=0;
 %for i=0:r
     xpdfupper40=hist(k1upper40,[r3+1:255]);%pdf from r+1:255
     xpdfupper40=xpdfupper40/lupper40;%normalized pdf to get nk/n,l=sum of xpdf,total no of pixels form r+1 to 255.
%      figure(10);
%      plot(xpdfupper40);
%      xlabel('gray levels after 4mean');
%      ylabel('pdf after 4mean');
%      title('histogram for upper half an image after 4mean');
     skupper40=xpdfupper40*triu(ones(255-r3));
%      figure(11);
%      plot(skupper40);
%      xlabel('gray levels after 4mean');
%      ylabel('cdf after 4mean');
%      title('cdf for upper half  of an image after 4mean');
     k4u=1;
     for k4upper=(r3+1):255
         %if(xpdfupper(k2upper)>r)
             list1upper40=find(k1upper40==k4upper);%find value in an vector i.e converted from matrix
             %for k2u=1:58
             %listnew4(list1upper40)=alpha*(198+skupper40(k4u)*(255-r3))+(1-alpha)*(r3+1);
             listnew4(list1upper40)=(r3+1)+skupper40(k4u)*(255-r3);%map
             %dont disturb to get original bbhe 14/3/2011
         %end
         ert(k4upper)=(r3+1)+skupper40(k4u)*(255-r3);
         k4u=k4u+1;
     end

%      for i=0:l-1
          p3=zeros(m,n);
%          if (p(listindex))
%              p(:)=list;
%          end
%      end

     p3(listindexupper40)= listnew4;
%     figure(12);
%     imshow(p3);
%     xlabel('gray levels after 4mean');
%      ylabel('luma component equilized image after 4mean');
%      title('processed luma image after 4mean');
     om=p+p1+p2+p3;
      F_enhance=om;
 end
     %ommmmm=p1+p;
%     figure(13);
% %     imshow(ommmmm);
%      colormap('gray');
%       xlabel('gray level');
%      ylabel('combined lower and upper half luma component equilized image');
%      title('combined luma image');
%     figure(8);
%     imshow(uint8(om));
%     for j1=0:255
%         count=0;
%         for i1=0:m*n-1
%             if om(i1+1)==j1
%                 count=count+1;
%             end
%         end
%             prob(j1+1)=count/m*n;
%     end
%     figure(16);
%     plot(prob);
%
%    for j2=0:255
%         count1=0;
%         for i2=0:m*n-1
%             if luma(i2+1)==j2
%                 count1=count1+1;
%             end
%         end
%             prob2(j2+1)=count1/m*n;
%     end
%     figure(17);
%     plot(prob2);
%     xlabel('gray levels after mean');
%      ylabel('luma component equilized image after mean');
%      title('processed luma image after mean');
%     ommmmm=p1+p;
%     figure(7);
%      colormap('gray');
%       xlabel('gray level');
%      ylabel('combined lower and upper half luma component equilized image');
%      title('combined luma image');
%     image(ommmmm);
% % % %      cat1=cat(3,om,cb,cr);
% % % %     figure(14);
% % % %     imshow(cat1);
% % % %     xlabel('gray level(ycbcr)');
% % % %      ylabel('combined lower and upper half luma,cromablue,croma red component equilized image');
% % % %      title('luma croma b and r color processed image');
% % % %     catconversion=ycbcr2rgb(cat1);
% % % %     figure(15);
% % % %     imshow(catconversion);
%     xlabel('gray level(rgb)');
%      ylabel('combined lower and upper half  RGB component equilized image');
%      title('converted from ycbcr2rgb color(RGB) processed image');
%      YM=mean(mean(om));
%      AMBE=abs(XM-YM);
%      disp('Absolute mean brightness error=');
%      disp(AMBE);
%      MSE = MeanSquareError(luma, om);
%     % figure(16);
% disp('Mean Square Error = ');
% disp(MSE);
% PSNR = PeakSignaltoNoiseRatio(luma, om);
% %figure(17);
% disp('Peak Signal to Noise Ratio = ');
% disp(PSNR);
% E=entropy(uint8(om));
% disp('Entropy=');
% disp(E);
%      figure(16);
%      plot(imhist(om));


function [fluxROOM, solutionROOM, totalFluxDiff] = linearROOM(model, fluxWT, rxnKO, varargin)
% Performs a LP version of the ROOM (Regulatory on/off minimization of
% metabolic flux changes) approach
%
% USAGE:
%
%    [fluxROOM, solutionROOM, totalFluxDiff] = linearROOM(model, WTflux, rxnKO, delta, epsilon, printLevel)
%
% INPUTS:
%    model:            Metabolic model
%    fluxWT:           Numeric array with flux distribution of wild type
%    rxnKO:            List of perturbations performed to the model
%                      (reactions that are eliminated)
%
% OPTIONAL INPUTS:
%    delta:            Multiplicative tol for flux change (Default = 0.03)
%    epsilon:          Additive tolerance for flux change (Default = 0.001)
%    printLevel:       Verbose output (Default = 1)
%
% OUTPUTS:
%    fluxROOM:         Flux distribution after ROOM calculation
%    solutionROOM:     Solution structure
%    totalFluxDiff:    Euclidean distance of ROOM objective, i.e.
%                      :math:`\sum (v_{wt}-v_{del})^2`
%
% Solve the following problem:
%
% .. math::
%      min ~&~ \sum y_{i} \\
%          ~&~ S_{del}v_{del} = 0 \\
%          ~&~ lb_{del} \leq v_{del} \leq ub_{del} \\
%          ~&~ for i=1:nRxns\\
%          ~&~ v_{i} - y_{i}(v_{max,i}-w_{wt,i}^u) \leq w_{wt,i}^u \\
%          ~&~ v_{i} - y_{i}(v_{min,i}-w_{wt,i}^l) \geq w_{wt,i}^l \\
%          ~&~ 0 \leq y_{i} \leq 1 \\
%          ~&~ w_{wt,i}^u = w_{wt,i} + \delta |w_{wt,i}| + \epsilon \\
%          ~&~ w_{wt,i}^l = w_{wt,i} - \delta |w_{wt,i}| - \epsilon \\
%
% NOTE::
%
%    The code here has been based on:
%    Shlomi, T., Berkman, O., & Ruppin, E. (2005). Regulatory on/off
%    minimization of metabolic flux changes after genetic perturbations.
%    Proceedings of the National Academy of Sciences, 102(21), 7695-7700
%
% .. Authors:
%       - Luis V. Valcarcel, 23/01/2019, University of Navarra, CIMA & TECNUN School of Engineering.

p = inputParser;
% check required arguments
addRequired(p, 'model');
addRequired(p, 'WTflux', @(x)isnumeric(x)&&isvector(x));
addRequired(p, 'rxnKO', @(x)iscell(x));
% Check optional arguments
addParameter(p, 'delta', 0.03, @(x)isnumeric(x)&&isscalar(x));
addParameter(p, 'epsilon', 0.001, @(x)isnumeric(x)&&isscalar(x));
addParameter(p, 'printLevel', 1, @(x)isnumeric(x)&&isscalar(x));
% extract variables from parser
parse(p, model, fluxWT, rxnKO, varargin{:});
delta = p.Results.delta;
epsilon = p.Results.epsilon;
printLevel = p.Results.printLevel;

% LP solution tolerance
global CBT_LP_PARAMS
if (exist('CBT_LP_PARAMS', 'var'))
    if isfield(CBT_LP_PARAMS, 'objTol')
        tol = CBT_LP_PARAMS.objTol;
    else
        tol = 1e-6;
    end
else
    tol = 1e-6;
end

% Check the inputs
fluxWT = reshape(fluxWT,[],1); % reshape flux vector
assert(numel(model.rxns)==numel(fluxWT), 'This flux distribution has different number of reactions than the model')
assert(norm(model.S * fluxWT)< 10*tol, 'This flux distribution cannot exist in this model')
assert(all(ismember(rxnKO, model.rxns)), 'Some reactions are not in the model')

% Eliminate almost-zero fluxes
fluxWT(abs(fluxWT)<tol) = 0;

% generate auxiliary variables
WT_upperTol = fluxWT + delta*abs(fluxWT) + epsilon;
WT_lowerTol = fluxWT - delta*abs(fluxWT) - epsilon;

%auxiliary variables
[nMets, nRxns] = size(model.S);

% Generate model
ROOMmodel = model;
new_variables = strcat('binary_',model.rxns);
% add novel variables
ROOMmodel = addCOBRAVariables(ROOMmodel,new_variables,'lb',0,'ub',1);
% add novel constrains
for i=1:nRxns
    ROOMmodel = addCOBRAConstraints(ROOMmodel, {model.rxns{i}, strcat('binary_',model.rxns{i})}, WT_upperTol(i),...
        'c', [+1, -(model.ub(i)-WT_upperTol(i))], 'dsense', 'L');
end
for i=1:nRxns
    ROOMmodel = addCOBRAConstraints(ROOMmodel, {model.rxns{i}, strcat('binary_',model.rxns{i})}, WT_lowerTol(i),...
        'c', [+1, -(model.lb(i)-WT_lowerTol(i))], 'dsense', 'G');
end
% Block reactions in model
ROOMmodel = changeRxnBounds(ROOMmodel, rxnKO, 0, 'b');
% change objective function
ROOMmodel.c(:) = 0;
ROOMmodel.evarc(cellfun(@length,regexp(ROOMmodel.evars,'^binary_'))==1) = 1;
ROOMmodel.osenseStr = 'min';

solutionROOM = optimizeCbModel(ROOMmodel);

if solutionROOM.stat == 1
    fluxROOM = solutionROOM.v(1:nRxns);
    totalFluxDiff = norm(fluxROOM-fluxWT);
else
    fluxROOM = nan(nRxns,1);
    totalFluxDiff = nan;
end

end


function pathG = build_initial_path()
global parameters
pathG=[];
j=1;
for i=1:size(parameters.trajectory,2)
    line = parameters.trajectory{i}.line;
    p0 = line(:,1);
    p1 = line(:,2);
    T = parameters.trajectory{i}.T0;

    partial_path = build_partial_path(p0, p1, T);
    %append
    for k=1:size(partial_path,2)
        pathG{j}.T=partial_path{k}.T;
        j=j+1;
    end
end

function partial_path = build_partial_path(p0, pf, T0)
global parameters
%this defines the line to follow in direction
deltaV = pf - p0;
deltaV = deltaV/norm(deltaV);
%and total length of the movement
total_length = norm(pf - p0); %m
n_steps = total_length/parameters.delta_mov;
n_steps = round(n_steps);
%linspace!!
%mov = linspace(0, total_length, parameters.N);
%line0 = [p0 pf];
%plot(line0(1,:),line0(2,:),'k')

partial_path=[];
Ti = T0;
for i=1:n_steps %length(mov)
    fprintf('Fast global plan %d out of %d\n', i, n_steps)
    %update to next point in trajectory
    %Ti(1:3,4) = p0 + mov(i)*deltaV;
    Ti(1:3,4) = p0 + i*parameters.delta_mov*deltaV;
    partial_path{i}.T = Ti;
end


function net = fcnInitializeModel16s(net)
%FCNINITIALIZEMODEL16S Initialize the FCN-16S model from FCN-32

%% Remove the last layer
net.removeLayer('deconv32') ;

%% Add the first Deconv layer
filters = single(bilinear_u(4, 1, 21)) ;
net.addLayer('deconv2', ...
  dagnn.ConvTranspose('size', size(filters), ...
                      'upsample', 2, ...
                      'crop', [1 1 1 1], ...
                      'hasBias', false), ...
             'x38', 'x39', 'deconv1f') ;
f = net.getParamIndex('deconv1f') ;
net.params(f).value = filters ;
net.params(f).learningRate = 0 ;
net.params(f).weightDecay = 1 ;

%% Add skip layers on top of pool4
net.addLayer('skip4', ...
     dagnn.Conv('size', [1 1 512 21], 'pad', 0), ...
     'x24', 'x40', {'skip4f','skip4b'});

f = net.getParamIndex('skip4f') ;
net.params(f).value = zeros(1, 1, 512, 21, 'single') ;
net.params(f).learningRate = 0.1 ;
net.params(f).weightDecay = 1 ;

f = net.getParamIndex('skip4b') ;
net.params(f).value = zeros(1, 1, 21, 'single') ;
net.params(f).learningRate = 2 ;
net.params(f).weightDecay = 1 ;

%% Add the summation layer
net.addLayer('sum1', dagnn.Sum(), {'x39', 'x40'}, 'x41') ;

%% Add deconvolutional layer implementing bilinear interpolation
filters = single(bilinear_u(32, 21, 21)) ;
net.addLayer('deconv16', ...
  dagnn.ConvTranspose('size', size(filters), ...
                      'upsample', 16, ...
                      'crop', 8, ...
                      'numGroups', 21, ...
                      'hasBias', false, ...
                      'opts', net.meta.cudnnOpts), ...
             'x41', 'prediction', 'deconv16f') ;

f = net.getParamIndex('deconv16f') ;
net.params(f).value = filters ;
net.params(f).learningRate = 0 ;
net.params(f).weightDecay = 1 ;

% Make sure that the output of the bilinear interpolator is not discared for
% visualization purposes
net.vars(net.getVarIndex('prediction')).precious = 1 ;

% empirical test
if 0
  figure(100) ; clf ;
  n = numel(net.vars) ;
  for i=1:n
    vl_tightsubplot(n,i) ;
    showRF(net, 'input', net.vars(i).name) ;
    title(sprintf('%s', net.vars(i).name)) ;
    drawnow ;
  end
end


function cS = forsterite
% Olivine

cs_Fo = crystalSymmetry('mmm',[0.466 1 0.586]);
N = Miller({0,1,0},{0,0,1},{0,2,1},{1,1,0},{1,0,1},{1,2,0},cs_Fo);
dist = [0.4, 1.3, 1.4, 1.05, 1.85, 1.35];
cS = crystalShape(N./dist);


filename='Bridge_hexahedra_fine';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
optimizer = 'PROJECTED GRADIENT'; incrementFactor = 1;
filterType = 'P1';

nsteps = 5;
Vfrac_final = 0.05;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-2;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Author: Eugenio Alcala Baselga
% Date: 02/06/2018
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [ u_opt, u_predicted, x_predicted, x_err] = MPC_Kinematic_Computation...
    ( controller, Hp, KC, oldu, u_predicted, x_predicted, x_Real,...
    kin_states, kin_inputs, x_Ref, y_Ref, theta_Ref, vel_Ref, omega_Ref,...
    longitud_vect, car, frozen_based, references_based)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\\ Vehicle kinematic control:
%   controller: object provided by the MPC design
%   Hp: Prediction horizon
%   KC: discrete kinematic time
%   oldu: previous control action
%   u_predicted: vector of predicted control actions in the last iteration
%   x_predicted: vector of predicted states in the last iteration
%   x_Real: vector of measured vehicle states [x y theta v alpha w]
%   kin_states: number of kinematic states: 3
%   kin_inputs: number of kinematic control actions: 2
%   x_Ref: x reference (planner)
%   y_Ref: y reference (planner)
%   theta_Ref: theta reference (planner)
%   vel_Ref: velocity reference (planner)
%   omega_Ref: angular velocity reference (planner)
%   longitud_vect: length of vectors for simulation
%   car: vehicle object
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if KC==1
    % Initializing vectors:
    theta_cos           = ones(1,Hp+1);
    theta_sin           = zeros(1,Hp+1);
    theta_err_cos       = ones(1,Hp);
    U_OPT_VECTOR        = zeros(kin_inputs,Hp,longitud_vect);
    X_OPT_VECTOR        = zeros(kin_states,Hp,longitud_vect);
end

%%%% Constraints %%%%
% Control action constraints:
    % CA
        u_min_ini   = vehicle.u_min_ini;
        u_max_ini   = vehicle.u_max_ini;
        u_min       = vehicle.u_min;
        u_max       = vehicle.u_max;
    % derivative of CA
        du_min_ini  = vehicle.du_min_ini;
        du_max_ini  = vehicle.du_max_ini;
        du_min      = vehicle.du_min;
        du_max      = vehicle.du_max;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% Terminal Set LMIs
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %[ PP, WW ] = TerminalSet_Continuous_Knemtic_Cmputtion();
    %[ PP, WW ] = TerminalSet_Discrete_Knemtic_Cmputtion(Ts_Kcontrol);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Errors de verdad (no forecasted from the LPV model):
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    x_err(1)    = (x_Ref(1)-x_Real(1))*cos(x_Real(3)) + (y_Ref(1)-x_Real(2))*sin(x_Real(3));
    x_err(2)    = -(x_Ref(1)-x_Real(1))*sin(x_Real(3)) + (y_Ref(1)-x_Real(2))*cos(x_Real(3));
    x_err(3)    = theta_Ref(1) - x_Real(3);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Moving Horizon Constraints:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    if KC>1
        for j=1:Hp+1
            theta_cos(j) = cos(theta_Ref(1));
            theta_sin(j) = sin(theta_Ref(1));
            if(j>1)
                theta_err_cos(j-1) = cos(x_predicted(3,1)); % cos (theta_ERROR forecasted)
            end
        end
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Computing PREDICTIONS of KIN-DYN LPV Vehicle Model. Note that
        % this A and B matrices are in continuous time due to the
        % discretization is carried out inside the controller object.
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        [Ac_pred, Bc_pred, Bref] = KinemError_LPV_Model_predicted(KC,Hp,x_predicted(3,:),...
            omega_Ref, vel_Ref );
        if frozen_based == true
            for i=1:Hp
                Ac_pred(:,:,i) = Ac_pred(:,:,1);
                Bc_pred(:,:,i) = Bc_pred(:,:,1);
            end
        elseif references_based == true
            for i=1:Hp
                Ac_pred(:,:,i) = Ac_pred(:,:,i);
                Bc_pred(:,:,i) = Bc_pred(:,:,i);
            end
        end
    else
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % Computing KIN-DYN LPV Vehicle Model for First iteration. Note that
        % this A and B matrices are in continuous time due to the
        % discretization is carried out inside the controller object.
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        [Ac_pred, Bc_pred, Bref] = KinemError_LPV_Model(KC,Hp,x_err(3),...
            omega_Ref(1), vel_Ref(1) );
    end

    %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Optimization stage:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%     if(KC > car.t_ini)
        inputs = {x_err', oldu, vel_Ref, omega_Ref, Ac_pred, Bc_pred,...
            theta_cos, theta_sin, theta_err_cos, u_min, u_max, du_min, du_max};
%     else
%         inputs = {x_err', oldu, vel_Ref, omega_Ref, Ac_pred, Bc_pred,...
%             theta_cos, theta_sin, theta_err_cos, u_min_ini, u_max_ini,...
%             du_min_ini, du_max_ini};
%     end

    [solutions,diagnostics] = controller{inputs};

    if diagnostics == 1
        u_opt = oldu;
        U_OPT_VECTOR(:,:,KC) = U_OPT_VECTOR(:,:,KC-1);
        X_OPT_VECTOR(:,:,KC) = X_OPT_VECTOR(:,:,KC-1);
    else
        U_OPT_VECTOR(:,:,KC) = solutions{1};
        u_opt = U_OPT_VECTOR(:,1,KC);
        X_OPT_VECTOR(:,:,KC) = solutions{2}; % Kinematic errors
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Predictions obtained from the solver:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    x_predicted = X_OPT_VECTOR(:,:,KC);
    u_predicted = U_OPT_VECTOR(:,:,KC);

end


function [cl] = mi32cl(mi3)
% Convert volume from cubic miles to centiliters.
% Chad Greene 2012
cl = mi3*416818182540000;


% Gtomosyn_test.m
% Copyright 2010-07-27, Jeff Fessler, University of Michigan

% small system for basic test
if ~isvar('As'), printm 'setup small'
	f.down = 16;
	f.dx = 0.1; % 100 um
	f.dz = 1; % 1 mm
	igs = image_geom('nx', 2304, 'ny', 48, 'nz', 1920, ...
		'dx', f.dx, 'dy', f.dz, 'dz', f.dx, ...
		'down', f.down);

	cgs = ct_geom('fan', 'ns', 2304, 'nt', 1920, 'na', 1, ...
			'orbit', 0, ...
			'ds', f.dx, 'dt', f.dx, ...
			'dfs', inf, ... % flat
			'dsd', 650, ...
			'dod', abs(igs.ny*igs.dy/2), ... % compressed on detector
			'down', f.down);

	As = Gtomosyn(cgs, igs, 'chat', 0); % set to 1 to see geometry!

	tmp = As * igs.unitv;
	im(tmp), cbar

%	Fatrix_test_basic(As, igs.mask)
	tester_tomo2(As, igs.mask, 'halt', 0, 'nblock', 0) % todo: ordering problem

	test_adjoint(As, 'big', 1, 'tol', 2e-6)
prompt
end

% big system for timing test
if ~isvar('A'), printm 'setup big'
	f.down = 4;
	f.dx = 0.1; % 100 um
	f.dz = 1; % 1 mm
	ig = image_geom('nx', 2304, 'ny', 48, 'nz', 1920, ...
		'dx', f.dx, 'dy', f.dz, 'dz', f.dx, ...
		'down', f.down);

	cg = ct_geom('fan', 'ns', 2304, 'nt', 1920, 'na', 1, ...
			'orbit', 0, ...
			'ds', f.dx, 'dt', f.dx, ...
			'dfs', inf, ... % flat
			'dsd', 650, ...
			'dod', abs(igs.ny*igs.dy/2), ... % compressed on detector
			'down', f.down);

	A = Gtomosyn(cg, ig, 'chat', 0);
end

if 1 && jf('ncore') >= 8, printm('time with %d threads', jf('ncore'))
	x = ig.circ;

	tmp1 = sprintf('%s, A*x time:', A.arg.blocks{1}.type);
	cpu etic
	y1 = A * x;
	cpu('etoc', tmp1) % 0.8 s on ir71 (20 cores)

	A2 = Gtomosyn(cg, ig, 'chat', 0, 'type', 'sf2');
	tmp2 = sprintf('%s, A*x time:', A2.arg.blocks{1}.type);
	cpu etic
	y2 = A2 * x;
	cpu('etoc', tmp2) % 1.4 s

	equivs(y1, y2)
end

% todo: compare to analytical - oblique views look funny


function node_num = grid_ql_node_num ( nelemx, nelemy )

%*****************************************************************************80
%
%% GRID_QL_NODE_NUM counts the nodes in a grid of QL elements.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NELEMX, NELEMY, the number of elements along the
%    X and Y directions.  The number of elements generated will be
%    NELEMX * NELEMY.
%
%    Output, integer NODE_NUM, the number of nodes in the grid.
%
  node_num = 2 * nelemx * nelemy + 2 * nelemx + nelemy + 1;

  return
end


function [F,C] = bfs_orient(F);
  % BFS_ORIENT Consistently orient faces in orientable patches using BFS
  %
  % F = bfs_orient(F);
  %
  % Inputs:
  %  F  #F by 3 list of faces
  % Outputs:
  %  F  #F by 3 list of faces
  %  C  #F list of component ids
  %
  % Example:
  %  RF = F;
  %  I = rand(size(F,1),1)<0.5;
  %  RF(I,:) = fliplr(RF(I,:));
  %  [FF,C] = bfs_orient(RF);
  %  FF = orient_outward(V,F,C);
  %  I = randperm(max(C))';
  %  meshplot(V,RF,'ScalarFieldF',I(C));
  %  meshplot(V,FF,'ScalarFieldF',I(C));
  %
  % See also: orient_outward, manifold_patches
  %

  [C,A] = manifold_patches(F);
  % No self matches
  A = A-diag(diag(A));
  % loop over components
  for c = 1:max(C)
    F(C==c,:) = bfs_orient_patch(F(C==c,:),A(C==c,C==c));
  end

  function FF = bfs_orient_patch(FF,AA)
    % short circuit if already oriented
    E = [FF(:,[2 3]); FF(:,[3 1]); FF(:,[1 2])];
    % Direct all edges so sortE(:,1) < sortE(:,2)
    sortE = sort(E,2);
    OA = sparse(sortE(:,1),sortE(:,2),1-2*(E(:,1)<E(:,2)));
    DA = sparse(sortE(:,1),sortE(:,2),1);
    % Don't count boundary edges (where "redirected" edge only occured once).
    OA(DA==1) = 0;
    if nnz(OA) == 0
      return;
    end

    m = size(FF,1);
    seen = false(m,1);

    es = [2 3;3 1;1 2];
    Q = 1;
    while ~isempty(Q)
      % pop
      f = Q(1);
      Q = Q(2:end);
      if seen(f)
        continue;
      end
      seen(f) = true;
      % only consider manifold-edge neighbors
      neighbors = find(AA(:,f));
      % number of neighbors
      nn = numel(neighbors);
      % loop over edges
      for ei = 1:3
        % this directed edge
        e = FF(f,es(ei,:));
        % All directed edges of neighbors
        E = [FF(neighbors,[2 3]);FF(neighbors,[3 1]);FF(neighbors,[1 2])];
        % Neighbors with matching directed edge ...
        match = neighbors(mod(find(all(bsxfun(@eq,e,E),2))-1,nn)+1);
        % ... must be flipped
        FF(match,:) = fliplr(FF(match,:));
        % Append neighbors to queue
        Q = [Q;neighbors];
      end

    end
    assert(all(seen));
  end

end


function model = yalmip2coneprog(interfacedata);

options = interfacedata.options;
F_struc = interfacedata.F_struc;
c       = interfacedata.c;
K       = interfacedata.K;
x0      = interfacedata.x0;
Q       = interfacedata.Q;
lb      = interfacedata.lb;
ub      = interfacedata.ub;

ops = options.coneprog;
switch options.verbose
case 0
    ops.Display = 'off';
case 1
    ops.Display = 'final';
otherwise
    ops.Display = 'iter';
end

Aeq = -F_struc(1:1:K.f,2:end);
beq = F_struc(1:1:K.f,1);
A =-F_struc(K.f+1:K.f+K.l,2:end);
b = F_struc(K.f+1:K.f+K.l,1);

if any(K.q)
    top = K.f + K.l + 1;
    for i = 1:length(K.q)
        base = F_struc(top:top+K.q(i)-1,:);
        top = top + K.q(i);
        socConstraints(i) = secondordercone(base(2:end,2:end),-base(2:end,1),base(1,2:end),-base(1));
    end
else
    socConstraints = [];
end

model.f = c;
model.A = A;
model.b = b;
model.Aeq = Aeq;
model.beq = beq;
model.lb = lb;
model.ub = ub;
model.ops = ops;
model.x0 = interfacedata.x0;
model.socConstraints = socConstraints;


function [LeakMets,modelClosed,FluxExV] = fastLeakTest(model, testRxns,test)
% This function performs a leak test, i.e., it tests whether the model can produce mass from nothing (i.e., when all lower bound on boundary reactions are set to be 0 corresponding to no uptake).
%
% [LeakMets,modelClosed,FluxExV] = fastLeakTest(model, testRxns,test)
%
% INPUT
% model         Model structure
% testRxns      Reactiosn to be tested
% test          If empty (''), the input model structure will be tested as is.
%               If 'demand' is provided as input or no entry is provided, then demand
%               reactions for each internal metabolite will be added and the function
%               will test whether any of the internal metabolites can be produced from
%               nothing.
%
% OUTPUT
% LeakMets      List of metabolites that can be produced from nothing. If
%               empty the model is leak free.
% modelClosed   Model structure with closed boundary reactions (lower bound
%               = 0.
% FluxExV       List of boundary reactions that produce metabolites from
%               nothing.
%
% Ines Thiele Jan 2015

if nargin<3
    test = 'demands';
end
tol = 1e-06;
modelClosed = model;
% find all reactions that have only one entry in S
clear count ExR
count=false(size(modelClosed.S,2),1);
for i = 1 :size(modelClosed.S,2)
    if length(find(modelClosed.S(:,i))<0)==1
        count(i,1)=1;
        modelClosed.lb(i)=0;
        % modelClosed.ub(i)=0;
    elseif length(find(modelClosed.S(:,i))>0)==1
        count(i,1)=1;
        %   modelClosed.ub(i)=0;
        modelClosed.lb(i)=0;
    end
end
ExR = modelClosed.rxns(count);

modelexchangesAbbr = unique([testRxns;ExR]);
FluxEx = [];
cnt =1;
%% test for all demand reactions is an option
if strcmp(test,'demands')
    % add demand reactions for all metabolites in model to check for those too
    [modelClosed,rxnNames] = addDemandReaction(modelClosed,modelClosed.mets,0);
else
    rxnNames = '';
end
modelexchangesAbbr = unique([modelexchangesAbbr;rxnNames']);
TestRxnNum = length(modelexchangesAbbr)
FluxExV =[];
while cnt == 1
    modelClosed = changeObjective(modelClosed,modelexchangesAbbr);
    FF2=optimizeCbModel(modelClosed,'max');
    ObjValue = FF2.f
    if FF2.f >= tol
        FluxR = modelClosed.rxns(find(abs(FF2.x)>tol));
        FluxEx = [FluxEx;intersect(modelexchangesAbbr,FluxR)];
        FluxExV = [FluxExV;FF2.x(find(ismember( modelClosed.rxns,intersect(modelexchangesAbbr,FluxR))))];
        modelexchangesAbbr = setdiff(modelexchangesAbbr, FluxEx);
        length(unique(FluxEx))
    else
        cnt = 2;
    end
end

LeakMets = FluxEx;


function [colorCodes, signChange, errorFlag]= getColorCodes(referenceFluxes, fluxes, maxChange, defaultColor, upColor, downColor)
% getColorCodes
%	Calculates the coloring for a number of fluxes by comparing them to
%   reference fluxes.
%
%   referenceFluxes     vector of reference fluxes
%   fluxes              vector of fluxes. The number of elements in fluxes
%                       and referenceFluxes must be equal
%   maxChange           the logfold increase or decrease that corresponds
%                       to full negative or full positive coloring. Must
%                       be a positive value (opt, default 1)
%   defaultColor        a color in Matlab format to be used if there are no
%                       changes between the fluxes. This color is also used to
%                       calculate the transition between the colors for up and
%                       down regulated fluxes (opt, default [1 1 1])
%   upColor             a color in Matlab format to be used if the flux is
%                       larger than the reference flux (opt, default [0 1 0])
%   downColor           a color in Matlab format to be used if the flux is
%                       smaller than the reference flux (opt, default [1 0 0])

%   colorCodes          array list of colors in Matlab format in the same
%                       order as the fluxes
%   signChange          array list of boolean values where true indicates
%                       that there has been a sign change between the
%                       fluxes. Reactions with sign changes are not
%                       colored, but rather marked in another way. The
%                       order correspondes to the order of the fluxes
%   errorFlag           true if there has been an error
%
%   Usage: [colorCodes, signChange, errorFlag]=getColorCodes(referenceFluxes,...
%           fluxes, maxChange, defaultColor, upColor, downColor)

if nargin<6
    downColor=[1 0 0];
end
if nargin<5
    upColor=[0 1 0];
end
if nargin<4
    defaultColor=[1 1 1];
end
if nargin<3
    maxChange=1;
end

%Checks that the flux vector and the reference flux vector have the same
%number of elements
if length(fluxes)~=length(referenceFluxes)
    colorCodes={};
    signChange={};
    errorFlag=1;
    fprintf('fluxes and referenceFluxes must have the same dimensions');
    return;
end

%Loops through the fluxes. If the reference flux is 0, then mark as
%upColor, if the flux is 0 then mark as downColor, and if both fluxes are 0
%then mark as defaultColor
for i=1:length(fluxes)
    signChange{i}=false;

    if referenceFluxes(i)==0 || fluxes(i)==0
        if referenceFluxes(i)==0 && fluxes(i)==0
            colorCodes{i}=defaultColor;
        else
            if referenceFluxes(i)==0
                colorCodes{i}=upColor;
            else
                colorCodes{i}=downColor;
            end
        end
    else
        %At the moment a negative flux that gets more negative is counted
        %as being upregulated. This might be counter intuitive.
        logvalue=log10(abs(fluxes(i))/abs(referenceFluxes(i)));

        %If there is a sign change
        if fluxes(i)*referenceFluxes(i)<0
            colorCodes{i}=defaultColor;
            signChange{i}=true;
        else
            colorCodes{i}=getColor(logvalue, defaultColor, upColor, downColor, maxChange);
        end
    end
end
end

function colorValue=getColor(logvalue, defaultColor, upColor, downColor, maxChange)
% getColor
%   Calculates the color for a specified logvalue.
%
%   logvalue            the logfold increase or desrease of a flux
%   compared to the
%                       corresponding reference flux. Must be a
%                       positive value
%   defaultColor        a color in Matlab format to be used if
%   there are no
%                       changes between the fluxes. This color is
%                       also used to calculate the transition
%                       between the colors for up and down
%                       regulated fluxes
%   upColor             a color in Matlab format to be used if the
%   flux is
%                       larger than the reference flux
%   downColor           a color in Matlab format to be used if the
%   flux is
%                       smaller than the reference flux
%   maxChange           the logfold increase or decrease that
%   corresponds
%                       to full negative or full positive coloring
%
%   colorValue          vector with the calculated color
%
%   Usage: colorValue=getColor(logvalue, defaultColor, upColor,
%   downColor, maxChange)

%If the flux has decreased
if logvalue<0
    %If the flux is lower than 10^-maxChange of the original then
    %color as downColor
    if logvalue<-maxChange
        colorValue=downColor;
    else
        %The color is linear from defaultColor to downColor
        colorValue=[defaultColor(1)+(downColor(1)-defaultColor(1))*logvalue/(-maxChange)...
            defaultColor(2)+(downColor(2)-defaultColor(2))*logvalue/(-maxChange)...
            defaultColor(3)+(downColor(3)-defaultColor(3))*logvalue/(-maxChange)];
    end
    %If it has increased
else
    %If the flux is higher than 10^maxChange times the original
    %then color green
    if logvalue>maxChange
        colorValue=upColor;
    else
        %The color is linear from defaultColor to upColor
        colorValue=[defaultColor(1)+(upColor(1)-defaultColor(1))*logvalue/(maxChange)...
            defaultColor(2)+(upColor(2)-defaultColor(2))*logvalue/(maxChange)...
            defaultColor(3)+(upColor(3)-defaultColor(3))*logvalue/(maxChange)];
    end
end
end


classdef spinoperator
%SPINOPERATOR   Abstract class for representing the spatial part of differential
%operators for time-dependent PDEs.
%   SPINOPERATOR is a class for representing the spartial part S of a
%   time-dependent PDE of the form u_t = S(u) = Lu + N(u), where L is a linear
%   operator and N is a nonlinear operator. SPINOP (in 1D), SPINOP2 (in 2D),
%   SPINOP3 (in 3D) and SPINOPSPHERE (on the sphere) are full implementations.
%
% See also SPINOP, SPINOP2, SPINOP3, SPINOPSPHERE.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS PROPERTIES:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    properties ( Access = public )
        domain              % Spatial domain (1x2 DOUBLE in 1D, 1x4 in 2D and on
                            % the sphere, 1x6 in 3D)
        init                % Initial condition (CHEBFUN in 1D, CHEBFUN2 in 2D,
                            % CHEBFUN3 in 3D, SPHEREFUN on the SPHERE,
                            % CHEBMATRIX for systems)
        lin                 % Linear part of the operator (FUNCTION HANDLE)
        nonlin              % Nonlinear part of the operator (FUNCTION HANDLE)
        tspan               % Vector of strictly increasing time
                            % samples (DOUBLE)
    end

    % DEPENDENT PROPERTIES:
    properties ( Access = public, Dependent = true )
        numVars             % Number of unknown functions (1x1 INT)
    end

    % DEPENDENT AND HIDDEN PROPERTIES:
    properties ( Access = public, Hidden = true, Dependent = true )
        nonlinearPartCoeffs % Differential part of the operator in coefficient
                            % space (FUNCTION HANDLE)
        nonlinearPartVals   % Nondifferential part of the operator in value
                            % space (FUNCTION HANDLE)
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% METHODS FOR DEPENDENT PROPERTIES:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods

        % METHOD for numVars:
        function nVars = get.numVars(S)

            nVars = nargin(S.lin);

        end

        % METHOD for nonlinearPartCoeffs:
        function Nc = get.nonlinearPartCoeffs(S)

            % Extract the nonlinear part:
            N = S.nonlin;

            % If N is empty, we are done:
            if ( isempty(N) == 1 )
                Nc = @(u) 0*u;
                return
            end

            % Else, get the variables of the workspace:
            func = functions(N);
            wrk = func.workspace{1};
            names = fieldnames(wrk);
            if ( isempty(names) == 0 )
                lengthNames = size(names, 1);
                for iter = 1:lengthNames
                    eval(sprintf('%s = wrk.(names{iter});', names{iter}));
                end
            end

            % Convert FUNCN to a string STRN:
            strN = func2str(N);

            % Get the number of variables NVARS:
            nVars = nargin(N);

            % For scalar equations in 1D, we support nonlinearities of the form
            % diff(f(u),m) with m>=0:
            if ( isa(S, 'spinop') == 1 && nVars == 1 )

                % Compute the differentiation order to get NC=diff(u,m):
                diffOrderTwoOrGreater = regexp(strN, ',\d*', 'match');
                diffOrderOne = regexp(strN, 'diff(', 'match');
                if ( isempty(diffOrderTwoOrGreater) == 0 )
                    diffOrder = diffOrderTwoOrGreater{1}(2:end);
                elseif ( isempty(diffOrderOne) == 0 )
                    diffOrder = '1';
                else
                    diffOrder = '0';
                end
                Nc = ['@(u) diff(u,', diffOrder, ')'];
                Nc = eval(Nc);

            % For scalar equations in 2D/3D and on the sphere, and for systems
            % of equations in 1D/2D/3D and on the sphere, we only support
            % nonlinearities of the form f_i(u_1,...,u_n), i.e., with no
            % differentiation, so Nc=1:
            else

                % Nc=1:
                Nc = 1;

            end

        end

        % METHOD for nonlinearPartVals:
        function Nv = get.nonlinearPartVals(S)

            % Extract the nonlinear part:
            N = S.nonlin;

            % If N is empty, we are done:
            if ( isempty(N) == 1 )
                Nv = @(u) 0*u;
                return
            end

            % Else, get the variables of the workspace:
            func = functions(N);
            wrk = func.workspace{1};
            names = fieldnames(wrk);
            if ( isempty(names) == 0 )
                lengthNames = size(names, 1);
                for iter = 1:lengthNames
                    eval(sprintf('%s = wrk.(names{iter});', names{iter}));
                end
            end

            % Convert FUNCN to a string STRN:
            strN = func2str(N);

            % Get the number of variables NVARS:
            nVars = nargin(N);

            % For scalar equations in 1D, we support nonlinearities of the form
            % diff(f(u),m) with m>=0:
            if ( isa(S, 'spinop') == 1 && nVars == 1 )

                % Get rid of the differentiation part in STRN to get NV=f(u):
                oldString = {'diff', ',\d*)'};
                newString = {'', ')'};
                Nv = regexprep(strN, oldString, newString);
                Nv = eval(Nv);

            % For scalar equations in 2D/3D and on the sphere, and for systems
            % of equations in 1D/2D/3D and on the sphere, we only support
            % nonlinearities of the form f_i(u_1,...,u_n), i.e., with no
            % differentiation, so Nv=N:
            else

                % Nv=N:
                strNv = func2str(N);

                % We're going to relabel the variables, e.g., @(u,v) u + v is
                % going to be relabelled @(u) u(1:length(u)/2) + ...
                % u(length(u)/2+1:end). First, get the names of the variables:
                openParenthesis = strfind(strNv, '(');
                openParenthesis = openParenthesis(1);
                closeParenthesis = strfind(strNv, ')');
                closeParenthesis = closeParenthesis(1);
                variablesNames = strNv(openParenthesis+1:closeParenthesis-1);
                variablesNames = regexp(variablesNames,  ',', 'split');

                % Second, relabel the variables:
                strNv = strNv(closeParenthesis+1:end);
                for iter = 1:nVars
                    idx1 = [num2str(rats((iter-1)/nVars)), '*', 'length(u)', '+1'];
                    idx2 = [num2str(rats(iter/nVars)), '*', 'length(u)'];
                    strNvNew = strrep(strNv, variablesNames{iter}, ...
                        ['u(', idx1, ':', idx2, ',:,:)']);
                    strNv = strNvNew;
                end
                Nv = ['@(u)', strNvNew];
                Nv = eval(Nv);

            end
        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% ABSTRACT AND NON-STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Abstract = true, Static = false )

        % Discretize a SPINOPERATOR:
        [L, Nc] = discretize(S, N)

        % Returns indexes for dealiasing procedure (2/3-rule):
        idx = getDealiasingIndexes(S, N, nVars)

        % Returns the type of CHEBFUN on which the SPINOPERATOR acts:
        out = getChebfunType(S)

        % Returns the transform coeffs -> values:
        F = getCoeffs2ValsTransform(S)

        % Returns the spatial dimension:
        dim = getDimension(S)

        % Returns a grid correspoding to a SPINOPRERATOR object:
        grid = getGrid(S, N, dom)

        % Returns the adequate SPINPREFERENCE object:
        pref = getPreference(S)

        % Returns the transform values -> coeffs:
        F = getVals2CoeffsTransform(S)

        % Returns 1 if the linear part of the SPINOPERATOR is diagonal,
        % 0 otherwise:
        out = isDiag(S)

        % Initialize a movie when solving a PDE specified by a SPINOPERATOR:
        [p, opts] = initializeMovie(S, dt, pref, v, compGrid, plotGrid)

        % Update the movie when solving a PDE specified by a SPINOPERATOR:
        opts = updateMovie(S, dt, p, options, t, v, compGrid, plotGrid)

        % Reshape the data that will be used for constructing the solution at
        % the end of the time-stepping: (For example, for SPINOPSPEHRE, it
        % extracts half of the data, since the data has been doubled-up with
        % the DFS method.)
        data = reshapeData(S, data, nVars)

        % Add the (repeated) endpoints to a periodic grid:
        grid = reshapeGrid(S, grid)

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CONCRETE AND STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Abstract = false, Static = true )

        % Solve a PDE defined by a SPINOPERATOR:
        [uout, tout, computingTime] = solvepde(varargin)

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CONCRETE AND NON-STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Abstract = false, Static = false )

        % Create a contour around each eigenvalue of the linear part of a
        % SPINOPERATOR:
        LR = computeLR(S, dt, L, M)

    end

end


classdef ConnecCoordFromInterpAndMesh < handle

    properties (Access = public)
        coord
        connec
    end

    properties (Access = private)
        mesh
        interp
    end

    methods (Access = public)

        function obj = ConnecCoordFromInterpAndMesh(cParams)
            obj.init(cParams)
        end

        function compute(obj)
            m = obj.mesh;
            shapesInVarNodes = obj.computeShapesInVariableNodes(m);
            xPointsMesh      = m.coord;
            Tmesh            = m.connec;

            xPoints = zeros(1,obj.interp.ndime);
            Tinterp = zeros(m.nelem,obj.interp.nnode);

            inode = 1;
            for ielem = 1:m.nelem
                for inodeVar = 1:obj.interp.nnode
                    xNode = zeros(1,obj.interp.ndime);
                    for inodeMesh = 1:m.nnodeElem
                        node = Tmesh(ielem,inodeMesh);
                        shapes = shapesInVarNodes(inodeVar,inodeMesh);
                        xNode = xNode + shapes*xPointsMesh(node,:);
                    end

                    node = obj.findPointInList(xNode,xPoints);

                    if isempty(node)
                        xPoints(inode,:) = xNode;
                        Tinterp(ielem,inodeVar) = inode;
                        inode = inode+1;
                    else
                        Tinterp(ielem,inodeVar) = node;
                    end
                end
            end
            obj.coord = xPoints;
            obj.connec = Tinterp;
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.mesh   = cParams.mesh;
            obj.interp = cParams.interpolation;
        end

        function shapes = computeShapesInVariableNodes(obj,mesh)
            interpMesh = Interpolation.create(mesh,'LINEAR');
            nNodeMesh = interpMesh.nnode;
            nNodeVar  = obj.interp.nnode;
            shapes    = zeros(nNodeVar,nNodeMesh);
            nodesVar  = obj.interp.pos_nodes;
            for inodeVar = 1:obj.interp.nnode
                nodesPoints = nodesVar(inodeVar,:);
                interpMesh.computeShapeDeriv(nodesPoints')
                shapes(inodeVar,:) = interpMesh.shape;
            end
        end

    end

    methods (Access = private, Static)

        function ind = findPointInList(node,xPoints)
            match = true(size(xPoints,1),1);
            for idime = 1:size(node,2)
                match = match & xPoints(:,idime) == node(idime);
            end
            ind = find(match);
        end

    end

end


function u = unicycle_index_to_sequence ( n, u_index )

%*****************************************************************************80
%
%% UNICYCLE_INDEX_TO_SEQUENCE converts a unicycle from index to sequence form.
%
%  Example:
%
%    N = 4
%
%    U_INDEX = 3 1 4 2
%    U       = 1 3 4 2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the unicycles.
%
%    Output, integer U_INDEX(N), the unicycle index vector.
%
%    Input, integer U(N), the unicycle sequence vector.
%
  u(1) = 1;
  i = 1;

  for j = 2 : n

    i = u_index(i);
    u(j) = i;

    if ( i == 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'UNICYCLE_INDEX_TO_SEQUENCE - Fatal error!\n' );
      fprintf ( 1, '  The index vector does not represent a unicycle.\n' );
      fprintf ( 1, '  On step %d, u_index(%d) = 1.\n', j, i );
      error ( 'UNICYCLE_INDEX_TO_SEQUENCE - Fatal error!' );
    end

  end

  return
end


function [MB] = GB2MB(GB)
% Convert computery things from gigabytes to megabytes.
% Chad A. Greene 2012
MB = GB*1024 ;


function [ ap, kpvt, rcond, z ] = sspco ( ap, n )

%*****************************************************************************80
%
%% SSPCO factors a real symmetric matrix stored in packed form.
%
%  Discussion:
%
%    SSPCO uses elimination with symmetric pivoting and estimates
%    the condition of the matrix.
%
%    If RCOND is not needed, SSPFA is slightly faster.
%
%    To solve A*X = B, follow SSPCO by SSPSL.
%
%    To compute inverse(A)*C, follow SSPCO by SSPSL.
%
%    To compute inverse(A), follow SSPCO by SSPDI.
%
%    To compute determinant(A), follow SSPCO by SSPDI.
%
%    To compute inertia(A), follow SSPCO by SSPDI.
%
%  Packed storage:
%
%    The following program segment will pack the upper triangle of a
%    symmetric matrix.
%
%      k = 0
%      do j = 1, n
%        do i = 1, j
%          k = k + 1
%          ap(k) = a(i,j)
%        end
%      end
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 November 2006
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Dongarra, Moler, Bunch and Stewart,
%    LINPACK User's Guide,
%    SIAM, (Society for Industrial and Applied Mathematics),
%    3600 University City Science Center,
%    Philadelphia, PA, 19104-2688.
%    ISBN 0-89871-172-X
%
%  Parameters:
%
%    Input, real AP(N*(N+1)/2), the packed form of a symmetric matrix A.  The
%    columns of the upper triangle are stored sequentially in a one-dimensional array.
%
%    Input, integer N, the order of the matrix.
%
%    Output, real AP(N*(N+1)/2), a block diagonal matrix and the multipliers
%    which were used to obtain it, stored in packed form.  The
%    factorization can be written A = U*D*U' where U is a product of
%    permutation and unit upper triangular matrices, U' is the transpose
%    of U, and D is block diagonal with 1 by 1 and 2 by 2 blocks.
%
%    Output, integer KPVT(N), the pivot indices.
%
%    Output, real RCOND, an estimate of the reciprocal condition
%    of A.  For the system A*X = B, relative perturbations in A and B of size
%    EPSILON may cause relative perturbations in X of size EPSILON/RCOND.
%    If RCOND is so small that the logical expression
%      1.0 + RCOND == 1.0
%    is true, then A may be singular to working precision.  In particular,
%    RCOND is zero if exact singularity is detected or the estimate underflows.
%
%    Output, real Z(N) a work vector whose contents are usually
%    unimportant.  If A is close to a singular matrix, then Z is an
%    approximate null vector in the sense that
%      norm(A*Z) = RCOND * norm(A) * norm(Z).
%

%
%  Find norm of A using only upper half.
%
  j1 = 1;
  for j = 1 : n
    z(j) = sasum ( j, ap(j1:j1+j-1), 1 );
    ij = j1;
    j1 = j1 + j;
    for i = 1 : j-1
      z(i) = z(i) + abs ( ap(ij) );
      ij = ij + 1;
    end
  end

  anorm = max ( z(1:n) );
%
%  Factor.
%
  [ ap, kpvt, info ] = sspfa ( ap, n );
%
%  RCOND = 1/(norm(A)*(estimate of norm(inverse(A)))).
%
%  Estimate = norm(Z)/norm(Y) where A*Z = Y and A*Y = E.
%
%  The components of E are chosen to cause maximum local
%  growth in the elements of W where U*D*W = E.
%
%  The vectors are frequently rescaled to avoid overflow.
%
%  Solve U * D * W = E.
%
  ek = 1.0;
  z(1:n) = 0.0;

  k = n;
  ik = floor ( ( n * ( n - 1 ) ) / 2 );

  while ( k ~= 0 )

    kk = ik + k;
    ikm1 = ik - ( k - 1 );

    if ( kpvt(k) < 0 )
      ks = 2;
    else
      ks = 1;
    end

    kp = abs ( kpvt(k) );
    kps = k + 1 - ks;

    if ( kp ~= kps )
      t = z(kps);
      z(kps) = z(kp);
      z(kp) = t;
    end

    if ( z(k) ~= 0.0 )
      ek = abs ( ek ) * r4_sign ( z(k) );
    end

    z(k) = z(k) + ek;
    z(1:k-ks) = saxpy ( k-ks, z(k), ap(ik+1:ik+k-ks), 1, z(1:k-ks), 1 );

    if ( ks ~= 1 )
      if ( z(k-1) ~= 0.0 )
        ek = abs ( ek ) * r4_sign ( z(k-1) );
      end
      z(k-1) = z(k-1) + ek;
      z(1:k-ks) = saxpy ( k-ks, z(k-1), ap(ikm1+1:ikm1+k-ks), 1, z(1:k-ks), 1 );
    end

    if ( ks ~= 2 )

      if ( abs ( ap(kk) ) < abs ( z(k) ) )
        s = abs ( ap(kk) ) / abs ( z(k) );
        z(1:n) = s * z(1:n);
        ek = s * ek;
      end

      if ( ap(kk) ~= 0.0 )
        z(k) = z(k) / ap(kk);
      else
        z(k) = 1.0;
      end

    else

      km1k = ik + k - 1;
      km1km1 = ikm1 + k - 1;
      ak = ap(kk) / ap(km1k);
      akm1 = ap(km1km1) / ap(km1k);
      bk = z(k) / ap(km1k);
      bkm1 = z(k-1) / ap(km1k);
      denom = ak * akm1 - 1.0;
      z(k) = ( akm1 * bk - bkm1 ) / denom;
      z(k-1) = ( ak * bkm1 - bk ) / denom;

    end

    k = k - ks;
    ik = ik - k;
    if ( ks == 2 )
      ik = ik - ( k + 1 );
    end

  end

  z(1:n) = z(1:n) / sasum ( n, z(1:n), 1 );
%
%  Solve U' * Y = W.
%
  k = 1;
  ik = 0;

  while ( k <= n )

    if ( kpvt(k) < 0 )
      ks = 2;
    else
      ks = 1;
    end

    if ( k ~= 1 )

      z(k) = z(k) + sdot ( k-1, ap(ik+1:ik+k-1), 1, z(1:k-1), 1 );
      ikp1 = ik + k;

      if ( ks == 2 )
        z(k+1) = z(k+1) + sdot ( k-1, ap(ikp1+1:ikp1+k-1), 1, z(1:k-1), 1 );
      end

      kp = abs ( kpvt(k) );

      if ( kp ~= k )
        t = z(k);
        z(k) = z(kp);
        z(kp) = t;
      end

    end

    ik = ik + k;
    if ( ks == 2 )
      ik = ik + ( k + 1 );
    end
    k = k + ks;

  end

  s = 1.0 / sasum ( n, z(1:n), 1 );
  z(1:n) = s * z(1:n);
  ynorm = 1.0;
%
%  Solve U * D * V = Y.
%
  k = n;

  ik = floor ( n * ( n - 1 ) / 2 );

  while ( 0 < k )

    kk = ik + k;
    ikm1 = ik - ( k - 1 );

    if ( kpvt(k) < 0 )
      ks = 2;
    else
      ks = 1;
    end

    if ( k ~= ks )

      kp = abs ( kpvt(k) );
      kps = k + 1 - ks;

      if ( kp ~= kps )
        t = z(kps);
        z(kps) = z(kp);
        z(kp) = t;
      end

      z(1:k-ks) = saxpy ( k-ks, z(k), ap(ik+1:ik+k-ks), 1, z(1:k-ks), 1 );

      if ( ks == 2 )
        z(1:k-ks) = saxpy ( k-ks, z(k-1), ap(ikm1+1:ikm1+k-ks), 1, z(1:k-ks), 1 );
      end

    end

    if ( ks ~= 2 )

      if ( abs ( ap(kk) ) < abs ( z(k) ) )
        s = abs ( ap(kk) ) / abs ( z(k) );
        z(1:n) = s * z(1:n);
        ynorm = s * ynorm;
      end

      if ( ap(kk) ~= 0.0 )
        z(k) = z(k) / ap(kk);
      else
        z(k) = 1.0;
      end

    else

      km1k = ik + k - 1;
      km1km1 = ikm1 + k - 1;
      ak = ap(kk) / ap(km1k);
      akm1 = ap(km1km1) / ap(km1k);
      bk = z(k) / ap(km1k);
      bkm1 = z(k-1) / ap(km1k);
      denom = ak * akm1 - 1.0;
      z(k) = ( akm1 * bk - bkm1 ) / denom;
      z(k-1) = ( ak * bkm1 - bk ) / denom;

    end

    k = k - ks;
    ik = ik - k;
    if ( ks == 2 )
      ik = ik - ( k + 1 );
    end

  end

  s = 1.0 / sasum ( n, z(1:n), 1 );
  z(1:n) = s * z(1:n);
  ynorm = s * ynorm;
%
%  Solve U' * Z = V.
%
  k = 1;
  ik = 0;

  while ( k <= n )

    if ( kpvt(k) < 0 )
      ks = 2;
    else
      ks = 1;
    end

    if ( k ~= 1 )

      z(k) = z(k) + sdot ( k-1, ap(ik+1:ik+k-1), 1, z(1:k-1), 1 );
      ikp1 = ik + k;

      if ( ks == 2 )
        z(k+1) = z(k+1) + sdot ( k-1, ap(ikp1+1:ikp1+k-1), 1, z(1:k-1), 1 );
      end

      kp = abs ( kpvt(k) );

      if ( kp ~= k )
        t = z(k);
        z(k) = z(kp);
        z(kp) = t;
      end

    end

    ik = ik + k;
    if ( ks == 2 )
      ik = ik + ( k + 1 );
    end
    k = k + ks;

  end
%
%  Make ZNORM = 1.0.
%
  s = 1.0 / sasum ( n, z(1:n), 1 );
  z(1:n) = s * z(1:n);
  ynorm = s * ynorm;

  if ( anorm ~= 0.0 )
    rcond = ynorm / anorm;
  else
    rcond = 0.0;
  end

  return
end


function combo_test17 ( )

%*****************************************************************************80
%
%% COMBO_TEST17 tests MOUNTAIN.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2011
%
%  Author:
%
%    John Burkardt
%
  n = 5;

  fprintf ( 1, ' \n' );
  fprintf ( 1, 'COMBO_TEST17\n' );
  fprintf ( 1, '  MOUNTAIN computes mountain numbers.\n' );
  fprintf ( 1, ' \n' );
  fprintf ( 1, '   Y    MXY\n' );
  fprintf ( 1, ' \n' );

  for y = 0 : n
    fprintf ( 1, '  %2d   ', y );
    for x = 0 : 2 * n
      mxy = mountain ( n, x, y );
      fprintf ( 1, '%4d', mxy );
    end
    fprintf ( 1, '\n' );
  end

  return
end


function [x_best, psi_best, out] = LevMar(mapp, lin_sym_solver, x0, options)
% LevMar is a Levenberg-Marquardt trust-region algorithm for solving
% systems of nonlinear equations :math:`h(x) = 0`, `x` in :math:`R^m`
% using the nonlinear unconstrained minimization :math:`\textrm{min}\ \psi(x) = 1/2 ||h(x)||^2`
% s.t. `x` in :math:`R^m`.
%
% USAGE:
%
%    [x_best, psi_best, out] = LevMar(mapp, lin_sym_solver, x0, options)
%
% INPUTS:
%    mapp:              function handle provides `h(x)` and gradient `h(x)`
%    lin_sym_solver:    function handle for solving the linear system
%    x0:                initial point
%    options:           structure including the parameteres of scheme
%
%                         * .eta - parameter of the scheme
%                         * .MaxNumIter - maximum number of iterations
%                         * .MaxNumMapEval - maximum number of function evaluations
%                         * .MaxNumGmapEval - maximum number of subgradient evaluations
%                         * .TimeLimit - maximum running time
%                         * .epsilon - accuracy parameter
%                         * .x_opt - optimizer
%                         * .psi_opt - optimum
%                         * .adaptive - update lambda adaptively
%                         * .flag_x_error - 1: saves :math:`x_{error}`, 0: do not saves :math:`x_{error}` (default)
%                         * .flag_psi_error - 1: saves :math:`\psi_{error}`, 0: do not saves :math:`\psi_{error}` (default)
%                         * .flag_time - 1: saves :math:`\psi_{error}`, 0: do not saves :math:`\psi_{error}` (default)
%                         * .Stopping_Crit - stopping criterion
%
%                           1. stop if :math:`||grad|| \leq \epsilon`
%                           2. stop if :math:`||nhxk|| \leq \epsilon`
%                           3. stop if `MaxNumIter` is reached
%                           4. stop if `MaxNumMapEval` is reached
%                           5. stop if `MaxNumGmapEval` is reached
%                           6. stop if `TimeLimit` is reached
%                           7. stop if :math:`||grad|| \leq \textrm{max}(\epsilon, \epsilon^2 * ngradx0)`
%                           8. stop if :math:`||nhxk|| \leq \textrm{max}(\epsilon, \epsilon^2 * nhx0)`
%                           9. stop if (default) :math:`||hxk|| \leq \epsilon` or `MaxNumIter` is reached
%
% OUTPUT:
%    x_best:            the best approximation of the optimizer
%    psi_best:          the best approximation of the optimum
%    out:               structure including more output information
%
%                         * .T - running time
%                         * .Niter - total number of iterations
%                         * .Nmap - total number of mapping evaluations
%                         * .Ngmap - total number of mapping gradient evaluations
%                         * .merit_func - array including all merit function values
%                         * .x_error - relative error :math:`\textrm{norm}(x_k(:)-x_{opt}(:))/\textrm{norm}(x_{opt})`
%                         * .psi_error - relative error :math:`(\psi_k-\psi_{opt})/(\psi_0-\psi_{opt}))`
%                         * .Status - reason of termination
%
% .. REFERENCE:
% .. 1. I.C.F. Ipsen, C.T. Kelley, S.R. Pope, Rank-deficient nonlinear least squares problems and subset selection, SIAM Journal on Numerical Analysis, 49(3), 1244-1266 (2011
% .. 2. C.T. Kelley, Iterative Methods for Optimization. SIAM Press, Philadelphia, 1999.
% .. Author: - Masoud Ahookhosh, System Biochemistry Group, Luxembourg Center for System Biomedicine, University of Luxembourg, Luxembourg
%            - Update: July 2017, M. Ahookhosh

format longG ;

% ================ Error messages for input and output =================
if nargin > 4
    error('The number of input arguments is more than what is needed');
elseif nargin < 4
    error('The number of input arguments is not enough');
end;

if isempty(mapp)
    error('the function handle mapp has to be defined');
elseif ~isa(mapp,'function_handle')
    error('mapp should be a function handle');
end

if isempty(lin_sym_solver)
    error('the function handle lin_sym_solver has to be defined');
elseif ~isa(lin_sym_solver,'function_handle')
    error('lin_sym_solver should be a function handle');
end

if isempty(x0)
    error('The starting point x0 has to be defined');
elseif ~isa(x0,'numeric')
    error('x0 should be a numeric vector');
end

% =================== initializing the parameters ======================
% ===== user has requested viewing the default values of "options" =====
[eta,epsilon,MaxNumIter,MaxNumMapEval,MaxNumGmapEval,adaptive, ...
    TimeLimit,flag_x_error,flag_psi_error,flag_time,Stopping_Crit] ...
    = Initialization(options);

if ~isa(eta,'numeric') || (eta <= 0)
    error('eta should be numeric and eta in (0,4*delta)');
end

if isfield(options,'x_opt')
    x_opt=options.x_opt;
elseif flag_x_error==1
    error('x_error requires to x_opt be specified');
end

if flag_x_error == 1
    Nxopt      = sqrt(sum(x_opt(:).^2));
    x_error(1) = sqrt(sum((x0(:)-x_opt(:)).^2))/Nxopt;
end

if flag_psi_error == 1
    psi_error(1) = 1;
end

if flag_time == 1
    Time(1) = 0;
end

mu0        = 1e-4;
mulow      = 0.25;
muhigh     = 0.75;
wdown      = 0.5;
wup        = 2;
nu0        = 1e-3;

xk         = x0;
Niter      = 1;
[hxk,ghxk] = mapp(x0);
Nmap       = 1;
Ngmap      = 1;
grad       = ghxk*hxk;
ngradx0    = norm(grad);
nhx0       = norm(hxk);
nhxk       = nhx0;
I          = eye(length(xk));
psik       = 0.5*nhxk^2;
merit_func = psik;
nuk        = ngradx0;
StopFlag   = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%% Main body of LevMar.m %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
T0 = tic;

% ======================= start of the main loop =======================
while ~StopFlag

    Gk    = ghxk*ghxk';
    Hk    = Gk+nuk*I;
    dk    = lin_sym_solver(Hk,grad);
    xk1   = xk+dk;
    hxk1  = mapp(xk1);

    Nmap  = Nmap+1;

    flag   = 0;
    initer = 0;
    while ~flag
        nhxk1  = norm(hxk1);
        psik1 = 0.5*nhxk1^2;
        ared  = psik-psik1;
        pred  = -0.5*(grad'*dk);
        rk    = ared/pred;
        if rk < mu0
            nuk    = max(nuk*wup,nu0);
		    Hk     = Gk+nuk*I;
            dk     = lin_sym_solver(Hk,grad);
            xk1    = xk+dk;
            hxk1   = mapp(xk1);
            Nmap   = Nmap+1;
            initer = initer+1;
            if initer>30
                flag = 1;
            end
	    elseif rk < mulow
	    	xk    = xk1;
            Niter = Niter+1;
            nuk   = max(nuk*wup,nu0);
            flag  = 1;
        else
		    xk    = xk1;
            Niter = Niter+1;
            if rk > muhigh
		        nuk = wdown*nuk;
                %if nuk < 10^(-3)
                if nuk < 10^(-3)
                    nuk =1e-8;
                end
            end
            flag = 1;
        end
    end

    [hxk,ghxk] = mapp(xk);
    Nmap       = Nmap+1;
    grad       = ghxk*hxk;
    nhxk       = norm(hxk);

    % ================= Gathering output information ===================
    psik              = 0.5*nhxk^2;
    merit_func(Niter) = psik;
    if flag_time == 1
        Time(Niter+1) = toc(T0);
    end

    if flag_x_error == 1
        Nx_opt = norm(x_opt);
        x_error(Niter+1) = sqrt(sum((xk(:)-x_opt(:)).^2))/Nx_opt;
    end

    if flag_psi_error == 1
        psi_error(Niter+1) = (psik-psi_opt)/(psi0-psi_opt);
    end

    % ================== checking stopping criteria ====================
    T = toc(T0);

    [StopFlag,Status] = StopCriterion(grad,nhxk,Niter,Nmap, ...
    Ngmap,MaxNumIter,MaxNumMapEval,MaxNumGmapEval,T,TimeLimit, ...
    epsilon,nhx0,ngradx0,Stopping_Crit);

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Outputs %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Status
x_best         = xk;
psi_best       = psik;
out.T          = T;
out.nhx        = nhxk;
out.merit_func = merit_func';
out.Niter      = Niter;
out.Nmap       = Nmap;
out.Ngmap      = Ngmap;
out.Status     = Status;

if flag_x_error == 1
    out.x_error = x_error;
end
if flag_psi_error == 1
    out.psi_error = psi_error;
end
if flag_time == 1
    out.Time = Time;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%% End of LevMar.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function [R1,t1] = invert_transformation(R,t)
R1      = R';
t1      = - R'*t;
end


function bnet = mk_qmr_bnet(G, inhibit, leak, prior, tabular_findings, onodes)
% MK_QMR_BNET Make a QMR model
% bnet = mk_qmr_bnet(G, inhibit, leak, prior)
%
% G(i,j) = 1 iff there is an arc from disease i to finding j
% inhibit(i,j) = inhibition probability on i->j arc
% leak(j) = inhibition prob. on leak->j arc
% prior(i) = prob. disease i is on
% tabular_findings = 1 means multinomial leaves (ignores leak/inhibit params)
%   = 0 means noisy-OR leaves (default = 0)

if nargin < 5, tabular_findings = 0; end

[Ndiseases Nfindings] = size(inhibit);
N = Ndiseases + Nfindings;
finding_node = Ndiseases+1:N;
ns = 2*ones(1,N);
dag = zeros(N,N);
dag(1:Ndiseases, finding_node) = G;
if nargin < 6, onodes = finding_node; end
bnet = mk_bnet(dag, ns, 'observed', onodes);

for d=1:Ndiseases
    CPT = [1-prior(d) prior(d)];
    bnet.CPD{d} = tabular_CPD(bnet, d, CPT');
end

for i=1:Nfindings
    fnode = finding_node(i);
    ps = parents(G, i);
    if tabular_findings
        bnet.CPD{fnode} = tabular_CPD(bnet, fnode);
    else
        bnet.CPD{fnode} = noisyor_CPD(bnet, fnode, leak(i), inhibit(ps, i));
    end
end


function [Z] = backProjection(Y, X)
% Back projection technique for fixing the frequency-wise scales of the
% signals estimated by ICA-based blind source separation techniques.
% Both monaural and multichannel outputs are supported.
%
% Coded by D. Kitamura (d-kitamura@ieee.org)
%
% Copyright 2018 Daichi Kitamura
%
% These programs are distributed only for academic research at
% universities and research institutions.
% It is not allowed to use or modify these programs for commercial or
% industrial purpose without our permission.
% When you use or modify these programs and write research articles,
% cite the following references:
%
% # Original paper (The algorithm was called "Rank-1 MNMF" in this paper)
% D. Kitamura, N. Ono, H. Sawada, H. Kameoka, H. Saruwatari, "Determined
% blind source separation unifying independent vector analysis and
% nonnegative matrix factorization," IEEE/ACM Trans. ASLP, vol. 24,
% no. 9, pp. 1626-1641, September 2016.
%
% # Book chapter (The algorithm was renamed as "ILRMA")
% D. Kitamura, N. Ono, H. Sawada, H. Kameoka, H. Saruwatari, "Determined
% blind source separation with independent low-rank matrix analysis,"
% Audio Source Separation. Signals and Communication Technology.,
% S. Makino, Ed. Springer, Cham, pp. 125-155, March 2018.
%
% See also:
% http://d-kitamura.net
% http://d-kitamura.net/demo-ILRMA_en.html
%
% [syntax]
%   [Z, D] = backProjection(Y, X)
%
% [inputs]
%   Y: estimated (separated) signals (frequency bin x time frame x source)
%   X: reference channel of observed (mixture) signal (frequency bin x time frame x 1)
%      or observed multichannel signals (frequency bin x time frame x channels)
%
% [outputs]
%   Z: scale-fitted estimated signals (frequency bin x time frame x source)
%      or scale-fitted estimated source images (frequency bin x time frame x source x channel)
%

% check errors
if (nargin<2)
    error('Too few input arguments.\n');
end
[I,J,M] = size(Y); % frequency bin x time frame x source

% back projection
if (size(X,3)==1) % calculate scale-fixed estimated signals using X(:,:,1)
    A = zeros(1,M,I);
    Z = zeros(I,J,M);
    for i=1:I
        Yi = squeeze(Y(i,:,:)).'; % channels x frames (M x J)
        A(1,:,i) = X(i,:,1)*Yi'/(Yi*Yi');
    end
    A(isnan(A)) = 0;
    A(isinf(A)) = 0;
    for m=1:M
        for i=1:I
            Z(i,:,m) = A(1,m,i)*Y(i,:,m);
        end
    end
elseif (size(X,3)==M) % calculate scale-fixed source images of estimated signals
    A = zeros(M,M,I);
    Z = zeros(I,J,M,M); % frequency bin x time frame x source x channel
    for i=1:I
        for m=1:M
            Yi = squeeze(Y(i,:,:)).'; % channels x frames (M x J)
            A(m,:,i) = X(i,:,m)*Yi'/(Yi*Yi');
        end
    end
    A(isnan(A)) = 0;
    A(isinf(A)) = 0;
    for n=1:M
        for m=1:M
            for i=1:I
                Z(i,:,n,m) = A(m,n,i)*Y(i,:,n);
            end
        end
    end
else
    error('The number of channels in X must be 1 or equal to that in Y.\n');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EOF %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function cin_lta()
    %

    % turned into function by Celso G Reyes 2017

    ZG=ZmapGlobal.Data; % used by get_zmap_globals
    report_this_filefun();

    var1 = zeros(1,ncu);
    var2 = zeros(1,ncu);
    lta = zeros(1,ncu);
    maxlta = zeros(1,ncu);
    maxlta = maxlta -5;

    cu = [cumuall(1:ti-1,:) ; cumuall(ti+winlen_days+1:len,:)];
    mean1 = mean(cu(:,:));
    mean2 = mean(cumuall(it:it+winlen_days,:));
    it

    for i = 1:ncu
        var1(i) = cov(cu(:,i));
    end     % for i

    for i = 1:ncu
        var2(i) = cov(cumuall(it:it+winlen_days,i));
    end     % for i

    lta = (mean1 - mean2)./(sqrt(var1/(len-winlen_days)+var2/(winlen_days)));
    valueMap = reshape(lta,length(gy),length(gx));

    % define size of the plot etc.
    %
    % set values gretaer ZG.tresh_km = nan
    %
    %[len, ncu] = size(cumuall);
    s = cumuall(len,:);
    r = reshape(s,length(gy),length(gx));
    re4 = valueMap;
    re4(r > ZG.tresh_km) = nan;

    figure(tmp);
    clf reset
    rect = [0.10 0.30 0.55 0.50 ];
    rect1 = rect;

    % find max and min of data for automatic scaling
    %

    % plot image
    %
    orient landscape
    axes('position',rect)
    pco1 = pcolor(gx,gy,re4);
    shading interp
    caxis([ZG.minc ZG.maxc]);
    colormap(jet)
    set(gca,'NextPlot','add')
    % plot overlay
    %
    overlay

    tx2 = text(0.07,0.85 ,['ti=' char(it*ZG.bin_dur+t0b)  ] ,...
        'Units','Norm','FontSize',14,'Color','k','FontWeight','bold');

    tx = text(0.07,0.95 ,['LTA;' char(ZG.compare_window_dur_v3)] ,...
        'Units','Norm','FontSize',14,'Color','k','FontWeight','bold');

    has = gca;

end


%% Copyright (C) 2014-2022 Colin B. Macdonald
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy 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.
%%
%% This software 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 this software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym log (@var{x})
%% Symbolic log function.
%%
%% Example:
%% @example
%% @group
%% syms x
%% y = log (x)
%%   @result{} y = (sym) log(x)
%% @end group
%% @end example
%%
%% Note: this file is autogenerated: if you want to edit it, you might
%% want to make changes to 'generate_functions.py' instead.
%%
%% @end defmethod

function y = log(x)
  if (nargin ~= 1)
    print_usage ();
  end
  y = elementwise_op ('log', x);
end

%!error log (sym(1), 2)
%!assert (isequaln (log (sym(nan)), sym(nan)))

%!shared x, d
%! d = 1;
%! x = sym('1');

%!test
%! f1 = log(x);
%! f2 = log(d);
%! assert( abs(double(f1) - f2) < 1e-15 )

%!test
%! D = [d d; d d];
%! A = [x x; x x];
%! f1 = log(A);
%! f2 = log(D);
%! assert( all(all( abs(double(f1) - f2) < 1e-15 )))

%!test
%! % round trip
%! y = sym('y');
%! A = log (d);
%! f = log (y);
%! h = function_handle (f);
%! B = h (d);
%! assert (A, B, -eps)


function [favar]=favar_fevd(gamma_record,It,Bu,n,IRFperiods,FEVDband,favar,IRFt,strctident)

% function [fevd_estimates]=bear.olsfevd(irf_estimates,IRFperiods,gamma,n,endo,datapath)
% computes and displays fevd values for the OLS VAR model
% inputs:  - cell 'irf_estimates': lower bound, point estimates, and upper bound for the IRFs
%          - integer 'IRFperiods': number of periods for IRFs
%          - matrix 'gamma': structural disturbance variance-covariance matrix (defined p 48 of technical guide)
%          - integer 'n': number of endogenous variables in the BVAR model (defined p 7 of technical guide)
%          - cell 'endo': list of endogenous variables of the model
%          - string 'datapath': user-supplied path to excel data spreadsheet
% outputs: - cell 'fevd_estimates': lower bound, point estimates, and upper bound for the FEVD

% preliminary tasks
npltX=favar.npltX;

% load IRFs
favar_irf_record=favar.IRF.favar_irf_record;

if IRFt==1||IRFt==2||IRFt==3
    identified=n; % fully identified
elseif IRFt==4 || IRFt==6 %if the model is identified by sign restrictions or sign restrictions (+ IV)
    identified=size(strctident.signreslabels,1); % count the labels provided in the sign res sheet (+ IV)
elseif IRFt==5
    identified=1; % one IV shock
end

% create the first cell
temp=cell(npltX,identified+1);

% start by filling the first column of every Tij matrix in the cell
% loop over rows of temp
for jj=1:npltX
    % loop over columns of temp
    for ii=1:identified
        % square each element
        temp{jj,ii}(:,1)=favar_irf_record{jj,ii}(:,1).^2;
    end
end
% fill all the other entries of the Tij matrices
% loop over rows of temp
for jj=1:npltX
    % loop over columns of temp
    for ii=1:identified
        % loop over remaining columns
        for kk=2:IRFperiods
            % define the column as the square of the corresponding column in orthogonalised_irf_record
            % additioned to the value of the preceeding columns, which creates the cumulation
            temp{jj,ii}(:,kk)=favar_irf_record{jj,ii}(:,kk).^2+temp{jj,ii}(:,kk-1);
        end
    end
end

% reshape gamma for loop
gamma_gibbs=reshape(gamma_record,n,n,It-Bu);

% recall L from the sampling process in this case, analogue to beta and sigma
Lgibbs=reshape(favar.L_gibbs,size(favar.L,1),size(favar.L,2),It-Bu);
%relevant loadings of restricted information variables
Lgibbs=Lgibbs(favar.plotX_index,:,:);
% R2 for scaling
R2_gibbs=reshape(favar.R2_gibbs,size(favar.plotX_index,1),1,It-Bu);

% multiply each matrix in the cell by the variance of the structural shocks
% to do so, loop over simulations (rows of the Tij matrices)
for kk=1:It-Bu
    % recover the covariance matrix of structural shocks gamma for this iteration
    gamma=squeeze(gamma_gibbs(:,:,kk));
    L=squeeze(Lgibbs(:,:,kk));
    R2=squeeze(R2_gibbs(:,:,kk));

    % scale gamma, irf estimates are already scaled,do we need this step????
    for ii=1:npltX
        for ll=1:identified
            favar_gamma{ii}(:,ll)=L(ii,ll)*gamma(:,ll);
        end
    end

    % loop over rows of temp
    for ii=1:npltX
        % loop over columns of temp
        for jj=1:identified
            % multiply column jj of the matrix by the variance of the structural shock
            temp{ii,jj}(1,:)=temp{ii,jj}(1,:)*favar_gamma{ii}(jj,jj);
        end
    end
end

% obtain now the values for Ti, the (n+1)th matrix of each row
% loop over rows of temp
for ii=1:npltX
    % start the summation over Tij matrices
    temp{ii,identified+1}=temp{ii,1};
    % sum over remaining columns
    for jj=2:identified
        temp{ii,identified+1}=temp{ii,identified+1}+temp{ii,jj};
    end
end

% create the output cell fevd_record, scale the shocks with R2 in spirit of BBE (2005)
favar_fevd_record=cell(npltX,identified);

% fill the cell
% loop over rows of fevd_estimates
for ii=1:npltX
    % load the R2 to determine the "true" share of variance explained by
    % the common component
    scale=R2(ii);
    shocks=[];
    % loop over columns of fevd_estimates
    for jj=1:identified
        % define the matrix Vfij as the division (pairwise entry) of Tfij by Tfj
        shock=(temp{ii,jj}./temp{ii,identified+1})*scale;
        favar_fevd_record{ii,jj}=shock; % changed to abs(shock) from shock here
        % save shocks to compute residual
        shocks(:,:,jj)=shock;
    end
    % finally add the residual, reflecting the share explained by the idiosyncratic component (residual)
    favar_fevd_record{ii,jj+1}=1-sum(shocks,3);
end

%% create the FEVD estimates output
% create first the cell that will contain the estimates
favar_fevd_estimates=cell(npltX,identified+1);

% for each variable and each variable contribution along with each period, compute the median, lower and upper bound from the Gibbs sampler records
% consider variables in turn
for ii=1:npltX
    % consider contributions in turn
    for jj=1:identified+1
        % consider periods in turn
        for kk=1:IRFperiods
            % compute first the lower bound
            favar_fevd_estimates{ii,jj}(1,kk)=quantile(favar_fevd_record{ii,jj}(:,kk),(1-FEVDband)/2);
            % then compute the median
            favar_fevd_estimates{ii,jj}(2,kk)=quantile(favar_fevd_record{ii,jj}(:,kk),0.5);
            % finally compute the upper bound
            favar_fevd_estimates{ii,jj}(3,kk)=quantile(favar_fevd_record{ii,jj}(:,kk),1-(1-FEVDband)/2);
        end
    end
end

%save output
favar.FEVD.favar_fevd_estimates=favar_fevd_estimates;


function [ElementRnCnPn]=FindPRC_3D_QPOTTS(ElementNo,state)

e=ElementNo;
planes=size(state,3);
columns=size(state,2);
rows=size(state,1);
r=rows;
c=columns;

for k=1:planes
    if e<=(k*r*c) & e>((k-1)*r*c)
        pn=k;break
    end
end

for j=1:columns
    if e<=((pn-1)*r*c+j*r) & e>((pn-1)*r*c+(j-1)*r)
        cn=j;break
    end
end

for i=1:rows
    if e==(pn-1)*r*c+(cn-1)*r+i
        rn=i;break
    end
end

ElementRnCnPn=[rn,cn,pn];

github-repos/MATLAB/Sable-mcbench-benchmarks/mcbench-benchmarks-ba13b2f0296ef49491b95e3f984c7c41fccdb6d8/34985-monte-carlo-simulation-of-three-dimensional-grain-growth-code-version-no-1-basic/Monte Carlo Simulation Q-state Potts model 3D square-lattice - microstructure/FindPRC_3D_QPOTTS.m


function [result] = sv_bval(params)
% function [params] = pf_bvalues(params)
% --------------------------------------
% Calculation of b-values for the probabilistic forecast test.
% Input parameters:
%   params.mCatalog           Earthquake catalog
%   params.mPolygon           Polygon (defined by ex_selectgrid)
%   params.vX                 X-vector (defined by ex_selectgrid)
%   params.vY                 Y-vector (defined by ex_selectgrid)
%   params.vUsedNodes         Used nodes vX * vY defining the mPolygon (defined by ex_selectgrid)
%   params.bMap               Calculate a map (=1) or a cross-section (=0)
%   params.bNumber            Use constant number (=1) or constant radius (=0)
%   params.nNumberEvents      Number of earthquakes if bNumber == 1
%   params.fRadius            Radius of gridnode if bNumber == 0
%   params.nMinimumNumber     Minimum number of earthquakes per node
%   params.fSplitTime         Time at which the catalog will be split
%   params.bLearningPeriod    Fix duration of the learning period (1 = fix, 0 = use catalog from start)
%   params.fLearningPeriod    Duration of the learning period
%   params.bForecastPeriod    Fix duration of the forecasting period (1 = fix, 0 = use catalog till end)
%   params.fForecastPeriod    Duration of the forecasting period
%
% Output parameters:
%   Same as input parameters including
%   result.mValueGrid         Matrix of calculated b-values
%   result.vcsGridNames       Strings describing the values in mValueGrid
%
% Danijel Schorlemmer
% June 4, 2001

global bDebug;
if bDebug
  report_this_filefun(mfilename('fullpath'));
end

% Init result matrix
result = params;
result.mValueGrid = [];

for nNode_ = 1:length(params.mPolygon(:,1))
  % Create node catalog
  mNodeCatalog_ = params.mCatalog(params.caNodeIndices{nNode_}, :);
  % Calculate the b-values
  [vDummy, fBValueObserved, fStdDevObserved, vDummy] =  bmemag(mNodeCatalog_);
  result.mValueGrid = [result.mValueGrid; fBValueObserved fStdDevObserved];
end; % for nNode
% Create the description-strings for the output-window
result.vcsGridNames = cellstr(char('b-value', 'Std. dev. of b-value'));