function [BVAR] = bvar(y,lags,options)

if nargin<3
    BVAR = bvar_(y,lags);
else
    BVAR = bvar_(y,lags,options);
end

end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % 'bvar' generates draws from the paramters of VAR model with error
% % distributed as a multivariate normal
%
% % Core Inputs:
% % - y, data columns variables
% % - lags, lag order of the VAR
%
% % Additonal Inputs collected options:
% % - options are not mandatory. if nothing is specified then a Jeffrey prior is
% %   assumed
% % - options.K, number of draws from the posterior distribution
% % - options.hor, horizon to compute the impulse response
% % - options.fhor, horizon to compute the out-of-sample forecast
% % - options.priors, a string with he priors for the autoregressive paramters and
% %   for the scaling matrix.
% % (...) see below
%
% % Output: Draws from the conditional distribution of Phi, Sigma and
% % Omega, impulse response with the cholesky decompotion and long run
% % restricions, forecast and marginal likelihood.
%
% % Filippo Ferroni, 6/1/2015
% % Revised, 2/15/2017
% % Revised, 3/21/2018
% % Revised, 9/11/2019
% % Revised, 27/02/2020
% % Revised, 27/04/2020
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% if nargin < 2
%     error('the BVAR toolbox needs at least two inputs: data and number of lags');
% end
% if lags < 1
%     error('lags cannot be zero or negative');
% end
% % number of observable variables
% ny                  = size(y, 2);
%
% %********************************************************
% %* DEFAULT SETTINGS
% %********************************************************
% % Control random number generator
% if isOctave == 0
%     isMatlab = 1;
%     rng('default');
%     rng(999);
% else
%     isMatlab = 0;
%     % pkg load optim
%     randn('state',999);
%     rand('state',999);
% end
%
%
% % Default Settings (they can all be changed in 'options' see below)
% K                   = 5000;         % number of draws from the posterior
% hor                 = 24;           % horizon for the IRF
% fhor                = 12;           % horizon for the forecasts
% firstobs            = lags+1;       % first observation
% presample           = 0;            % using a presample for setting the hyper-parameter of the Minnesosta prior
% noconstant          = 0;            % when 0, includes a constatn in the VAR
% timetrend           = 0;            % when 1, includes a time trend in the VAR
% minn_prior_tau      = 3;            % Minnesota prior Hyper-Param: Overall Tightness
% minn_prior_decay    = 0.5;          % Minnesota prior Hyper-Param: Tighness on lags>1
% minn_prior_lambda   = 5;            % Minnesota prior Hyper-Param: Sum-of-Coefficient
% minn_prior_mu       = 2;            % Minnesota prior Hyper-Param: Co-Persistence
% minn_prior_omega    = 2;            % Minnesota prior Hyper-Param: Shocks Variance
% long_run_irf        = 0;            % when 0, it does not compute long run IRF
% irf_1STD            = 1;            % when 1, IRF are computed as 1SD increase. Else, IRF are compued as unitary increase in the shock
% cfrcst_yes          = 0;            % no conditional forecast unless defined in options
% non_explosive_      = 0;            %
% heterosked          = 0;
%
% signs_irf           = 0;
% narrative_signs_irf = 0;
% zeros_signs_irf     = 0;
% proxy_irf           = 0;
% noprint             = 0;
% nexogenous          = 0;
% exogenous           = [];
%
% % for mixed frequecy / irregurerly sampled data.
% % Interpolate the missing values of each times series.
% if any(any(isnan(y)))==1
%     warning('Activating the Mixed Frequency BVAR')
%
%     mixed_freq_on = 1;
%     index_nan_var = find(sum(isnan(y),1) ~= 0);
%     yoriginal     = y;
%     % interporlate the variables that have nans
%     T = 1:1:length(y);
%     for kk  = 1 : length(index_nan_var)
%         v                       = y(isfinite(y(:,index_nan_var(kk))),index_nan_var(kk));
%         x                       = find(isfinite(y(:,index_nan_var(kk))));
%         if isMatlab == 1
%             y(:,index_nan_var(kk))  = interp1(x,v,T','spline');
%         else
%             y(:,index_nan_var(kk))  = spline(x,v,T');
%         end
%         yinterpol               = y;
%     end
% else
%     mixed_freq_on = 0;
% end
% if mixed_freq_on == 1 && nargin < 3
%     warning(['You did not specified the aggregation of the mixed freq. '...
%         'I will treat them as stocks.']);
%     index = zeros(size(y,2),1);
% end
%
% % Priors declaration: default Jeffrey prior
% dummy    = 0;
% flat     = 1;
% priors   = priors_( );
%
% % declaring the names for the observable variables
% for v = 1 : ny
%     eval(['varnames{'   num2str(v) '} =  ''Var' num2str(v) ''';'])
% end
%
%
% %********************************************************
% %* CUSTOMIZED SETTINGS
% %********************************************************
% if nargin > 2
%     if isfield(options,'vnames')==1
%         varnames = options.vnames;
%     end
%     %======================================================================
%     % Inference options
%     %======================================================================
%     if isfield(options,'K')==1
%         K = options.K;
%     end
%     if isfield(options,'firstobs')==1
%         firstobs = options.firstobs;
%         if firstobs < lags + 1
%             error('firstobs need to be larger than lags +1')
%         end
%     end
%     if isfield(options,'presample')==1
%         presample = options.presample;
%     end
%     if isfield(options,'noconstant')==1
%         noconstant = options.noconstant;
%     end
%     if isfield(options,'timetrend')==1
%         timetrend  = options.timetrend;
%         noconstant = 0;
%     end
%     if isfield(options,'non_explosive_')==1
%         non_explosive_  = options.non_explosive_;
%     end
%     if isfield(options,'heterosked_weights')==1
%         ww  = options.heterosked_weights;
%         heterosked = 1;
%     end
%     %======================================================================
%     % Exogenous Variables options
%     %======================================================================
%     if isfield(options,'exogenous')==1 || isfield(options,'controls')==1
%         if isfield(options,'controls')==1
%             exogenous = options.controls;
%         else
%             exogenous = options.exogenous;
%         end
%         nexogenous = size(exogenous,2);
%         if size(exogenous,1) ~= size(y,1)+ fhor && size(exogenous,1) ~= size(y,1)
%             error('Size Mismatch between endogenous and exogenos variables; exo must be either T or T+fhor');
%         end
%     end
%     %======================================================================
%     % Minnesota prior options
%     %======================================================================
%     if (isfield(options,'priors')==1 && strcmp(options.priors.name,'Minnesota')==1) || (isfield(options,'priors')==1 && strcmp(options.priors.name,'minnesota')==1) || ...
%        (isfield(options,'prior')==1 && strcmp(options.prior.name,'Minnesota')==1) || (isfield(options,'prior')==1 && strcmp(options.prior.name,'minnesota')==1)
%         %  MINNESOTA PRIOR
%         dummy = 1;
%         flat  = 0;
%         timetrend = 0;
%         priors.name= 'Minnesota';
%     end
%     if isfield(options,'minn_prior_tau')==1 || isfield(options,'bvar_prior_tau')==1
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         %  MINNESOTA PRIOR: tightness
%         if isfield(options,'bvar_prior_mu')==1
%             minn_prior_tau = options.bvar_prior_tau;
%         else
%             minn_prior_tau = options.minn_prior_tau;
%         end
%     end
%     if isfield(options,'minn_prior_decay')==1 || isfield(options,'bvar_prior_decay')==1
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         %  MINNESOTA PRIOR: decay
%         if isfield(options,'bvar_prior_mu')==1
%             minn_prior_decay = options.bvar_prior_decay;
%         else
%             minn_prior_decay = options.minn_prior_decay;
%         end
%     end
%     if isfield(options,'minn_prior_lambda')==1 || isfield(options,'bvar_prior_lambda')==1
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         %  MINNESOTA PRIOR: sum-of-coeff
%         if isfield(options,'bvar_prior_mu')==1
%             minn_prior_lambda = options.bvar_prior_lambda;
%         else
%             minn_prior_lambda = options.minn_prior_lambda;
%         end
%     end
%     if isfield(options,'minn_prior_mu')==1 || isfield(options,'bvar_prior_mu')==1
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         %  MINNESOTA PRIOR: co-persistence
%         if isfield(options,'bvar_prior_mu')==1
%             minn_prior_mu = options.bvar_prior_mu;
%         else
%             minn_prior_mu = options.minn_prior_mu;
%         end
%     end
%     if isfield(options,'minn_prior_omega')==1 || isfield(options,'bvar_prior_omega')==1
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         %  MINNESOTA PRIOR: variance
%         if isfield(options,'bvar_prior_omega')==1
%             minn_prior_omega = options.bvar_prior_omega;
%         else
%             minn_prior_omega = options.minn_prior_omega;
%         end
%     end
%     if isfield(options,'max_minn_hyper')==1 && options.max_minn_hyper ==1 && mixed_freq_on ==0
%         % maximize the hyper parameters of the minnesota prior
%         hyperpara(1) = minn_prior_tau;
%         hyperpara(2) = minn_prior_decay;
%         hyperpara(3) = minn_prior_lambda;
%         hyperpara(4) = minn_prior_mu;
%         hyperpara(5) = minn_prior_omega;
%
%         dummy = 1;
%         flat  = 0;
%         priors.name= 'Minnesota';
%         try
%             [postmode,lm,~] = bvar_max_hyper(hyperpara,y,lags,options);
%
%             minn_prior_tau      = postmode(1);
%             minn_prior_decay    = postmode(2);
%             minn_prior_lambda   = postmode(3);
%             minn_prior_mu       = postmode(4);
%             minn_prior_omega    = postmode(5);
%             disp('                       ')
%             disp('Maximization Successful: I will use the the mode values.')
%
%         catch
%             warning('Maximization NOT Successful')
%             disp('Using hyper parameter default values')
%         end
%     end
%     %======================================================================
%     % Conjugate/Hierachical prior options
%     %======================================================================
%     if (isfield(options,'priors')==1 && strcmp(options.priors.name,'Conjugate')==1) || (isfield(options,'priors')==1 && strcmp(options.priors.name,'conjugate')==1) || ...
%        (isfield(options,'prior')==1 && strcmp(options.prior.name,'Conjugate')==1) || (isfield(options,'prior')==1 && strcmp(options.prior.name,'conjugate')==1)
%
%         if isfield(options,'prior')==1
%             options.priors = options.prior;
%         end
%         if dummy == 1
%             warning('You have set both the Conjugate and Minnesota (perhaps via options.minn_prior_XX)');
%             warning('I will consider the Conjugate prior only');
%         end
%         dummy = 2;
%         %  warning('The Conjugate prior is still under construction ... ');
%         flat  = 0;
%         priors.name= 'Conjugate';
%         % Priors for the AR parameters
%         if isfield(options.priors,'Phi') == 1
%             % mean
%             if isfield(options.priors.Phi,'mean') == 1
%                 prior.Phi.mean  = options.priors.Phi.mean;
%                 if max(size(prior.Phi.mean) ~= [ny*lags+(1-noconstant)+timetrend+nexogenous   ny]) ~= 0
%                     error('Size mismatch')
%                 end
%             else
%                 warning(['You did not provide a prior mean for the AR coeff. ' ...
%                     'Assume zeros everywhere.'])
%                 prior.Phi.mean  = zeros(ny*lags+(1-noconstant)+timetrend+nexogenous , ny);
%             end
%             % variance
%             if isfield(options.priors.Phi,'cov') == 1
%                 prior.Phi.cov   = options.priors.Phi.cov;
% %                 if length(prior.Phi.cov) ~= (ny*lags+(1-noconstant) +timetrend ) * ny
%                 if length(prior.Phi.cov) ~= (ny*lags+(1-noconstant) +timetrend+nexogenous ) || size(prior.Phi.cov,1 )~=size(prior.Phi.cov,2)
%                     error('Size mismatch: Covariance Phi should be square, e.g. size(Phi.mean,1)x size(Phi.mean,1)x')
%                 end
%             else
%                 warning(['You did not provide a Covariance for the AR coeff. ' ...
%                     'Assume 10 times Identity Matrix.'])
% %                 prior.Phi.cov  = 10 * eye((ny*lags+(1-noconstant) + timetrend) * ny);
%                 prior.Phi.cov  = 10 * eye((ny*lags+(1-noconstant) + timetrend+nexogenous));
%             end
%         else
%             warning(['You did not provide prior mean and covariance for the AR coeff ' ...
%                 'Assume zeros everywhere with covariance 10 times Identity Matrix.'])
% %             prior.Phi.cov   = 10 * eye((ny*lags+(1-noconstant) +timetrend ) * ny);
%             prior.Phi.cov   = 10 * eye((ny*lags+(1-noconstant) + timetrend+nexogenous ));
%             prior.Phi.mean  = zeros(ny*lags+(1-noconstant) + timetrend+nexogenous ,  ny);
%         end
%         % Priors for the Residual Covariance
%         if isfield(options.priors,'Sigma') == 1
%             % scale
%             if isfield(options.priors.Sigma,'scale') == 1
%                 prior.Sigma.scale = options.priors.Sigma.scale;
%                 if size(prior.Sigma.scale) ~= [ny ny]
%                     error('Size mismatch')
%                 end
%             else
%                 warning(['You did not provide a prior mean for the Residual Covariance. ' ...
%                     'Assume identity matrix.'])
%                 prior.Sigma.scale = eye(ny);
%             end
%             % degrees of freedom
%             if isfield(options.priors.Sigma,'df') == 1
%                 prior.Sigma.df = options.priors.Sigma.df;
%                 if length(prior.Sigma.df) ~= 1
%                     error('Size mismatch')
%                 end
%                 if prior.Sigma.df/2 <= ny-1
%                     error('Too few degrees of freedom - Increase prior df')
%                 end
%             else
%                 warning(['You did not provide the degrees of freedom for the Residual Covariance. ' ...
%                     'Assume ny+1.'])
%                 prior.Sigma.df = ny + nexogenous + timetrend + 1;
%                 while prior.Sigma.df/2 <= ny-1 % too few df
%                     prior.Sigma.df =  prior.Sigma.df +1;
%                 end
%             end
%         else
%             warning(['You did not provide prior mean and variance for the Residual Covariance. ' ...
%                 'Assume an identity matrix matrix with N+1 degrees of freedom.'])
%             prior.Sigma.scale = eye(ny);
%             prior.Sigma.df    = ny + nexogenous + timetrend + 1;
%             while prior.Sigma.df/2 <= ny-1 % too few df
%                 prior.Sigma.df =  prior.Sigma.df +1;
%             end
%         end
%     end
%     %======================================================================
%     % IRF options
%     %======================================================================
%     if isfield(options,'hor') ==1
%         hor = options.hor;
%     end
%     if isfield(options,'long_run_irf')==1
%         % Activating Long run IRF
%         long_run_irf = options.long_run_irf;
%     end
%     if isfield(options,'signs')==1
%         % Activating IRF with sign restrictions (mulitple horizons allowed)
%         signs_irf       = 1;
%         signs           = options.signs;
%         if iscellstr(signs) == 0
%             error(['options.signs should be a cell array. Each cell must contain a string with the format'...
%                 '\n''y(a,b,c)<0'' or ''y(a,b,c)>0'' where a, b and c are integers.',...
%                 '\na = index of the variable',...
%                 '\nb = horizon',...
%                 '\nc = index of the shock'],class(zeros))
%         end
%     end
%     if isfield(options,'narrative')==1
%         if signs_irf  == 0
%             warning('You did not provide any sign restrictions.')
%             signs{1} = 'isempty(y(1,1,1))==0';
%         end
%         narrative_signs_irf = 1;
%         narrative           = options.narrative ;
%     end
%     if isfield(options,'zeros_signs')==1
%         if signs_irf  == 1
%             signs_irf       = 0;  % disactivating signs
%         end
%         if narrative_signs_irf  == 1
%             narrative_signs_irf       = 0;  % disactivating narrative
%         end
%         % Activating IRF with zeros and sign restrictions (mulitple horizons NOT allowed)
%         zeros_signs_irf  = 1;
%         zeros_signs      = options.zeros_signs;
%         if iscellstr(zeros_signs) == 0
%             error(['options.zeros_signs should be a cell array.'...
%                 '\nEach cell must contain a string with the following format'...
%                 '\nFor sign restrictions ''y(a,b)=1'' or ''y(a,b)=-1'',',...
%                 '\nFor short run zero restriction ''ys(a,b)=0'',',...
%                 '\nFor long run restriction ''yr(a,1,b)=0'' where a and b are integers.',...
%                 '\na = index of the variable',...
%                 '\nb = index of the shock'],class(zeros_signs))
%         end
%         [f,sr] = sign2matrix(zeros_signs,ny);
%         if isfield(options,'var_pos')==0
%             var_pos = ones(1,ny);
%         else
%             var_pos = options.var_pos;
%         end
%     end
%     if isfield(options,'proxy')==1
%         % Activating IRF with provy
%         proxy_irf   = 1;
%         in.proxies  = options.proxy;
%         in.vars     = y;
%         in.p        = lags;
%         if isfield(options,'proxy_end') == 1
%             in.T_m_end  = options.proxy_end;
%         else
%             in.T_m_end  = 0;  %if the times series of the instrument ends when VAR data ends
%         end
%         in.irhor    = hor;
%         if isnumeric(in.proxies) == 0
%             error(['options.proxy should be a numeric array (nans or inf not allowed)'],class(in.proxies))
%         end
%     end
%     if isfield(options,'irf_1STD')==1
%         % Activating of unitary IRF, i.e. a unitary increase in the shocks
%         % (instead of 1 STD)
%         irf_1STD = options.irf_1STD;
%     end
%     %======================================================================
%     % (Un)Conditional Forecasts options
%     %======================================================================
%     if isfield(options,'fhor')==1
%         fhor = options.fhor;
%         if fhor < 1
%             error('Forecast horizon must be positive')
%         end
%     end
%     if isfield(options,'endo_index')==1
%         % Forecast conditional on the path of an endogenous var
%         cfrcst_yes      = 1;
%         if isfield(options,'endo_path')== 0
%             error('You need to provide the p[ath for the endogenou variable')
%         end
%         % rows forecasts, column variables
%         endo_path       = options.endo_path;
%         endo_path_index = options.endo_index;
%         if length(endo_path_index) ~= size(endo_path)
%             error(['Mismatch beween the number of endogenous paths and the number of conditioned variables'...
%                 '\nE.g. the # of conditioned variables must coincide with the # of column in ''options.endo_path'''],class(endo_path_index));
%         end
%         if isfield(options,'exo_index')==1
%             % Forecast conditional on the path of an endo var using only a
%             % subset of shocks. notice that the # of endo and # exo must coincide
%             cfrcst_yes  = 2;
%             exo_index   = options.exo_index;
%             Omega       = eye(ny);
%             %             if isfield(options,'Omegaf')==1
%             %                 Omegaf = options.Omegaf;
%             %             end
%             if length(exo_index) ~= length(endo_path_index)
%                 error('the # of conditioned endogenous and # exogenous shocks used must coincide');
%             end
%         end
%
%     end
%     %======================================================================
%     % Missing Values options
%     %======================================================================
%     if mixed_freq_on == 1 && isfield(options,'mixed_freq_index')==1
%         index = options.mixed_freq_index;
%         if length(index) ~= size(y,2)
%             error(['You have to specify as many index as observables.'...'
%                 '\nIf no missing values for var j index(j)=0'...
%                 '\nIf missing values for var j, and var j is a stock index(j)=0'...
%                 '\nIf missing values for var j, and var j is a real flow index(j)=2'],class(index))
%         end
%     elseif mixed_freq_on == 1 && isfield(options,'mf_varindex')== 1
%         index = zeros(ny,1);
%         index(options.mf_varindex) = 2;
%     elseif (mixed_freq_on == 1 && isfield(options,'mixed_freq_index')== 0) || (mixed_freq_on == 1 && isfield(options,'mf_varindex')== 0)
%         warning(['You did not specified the aggregation of the mixed freq.'...
%             '\nI will treat them as stocks.']);
%         index = zeros(size(y,2),1);
%     end
%     if isfield(options,'noprint')==1
%         noprint = options.noprint;
%     end
% end
%
% %********************************************************
% %* Consistency Checks
% %********************************************************
% nobs = size(y,1)-firstobs+1;
% if (firstobs+ nobs-1)> size(y,1)
%     fprintf('Incorrect or missing specification of the number of observations. nobs can be at most %4u\n',size(y,1)-firstobs+1);
%     error('Inconsistent number of observations.')
% end
% if firstobs + presample + lags >= nobs
%     error('presample too large')
% end
% if firstobs + presample  <= lags
%     error('firstobs+presample should be > # lags (for initializating the VAR)')
% end
% if dummy == 1 && nexogenous > 0
%     warning('I will not use exogenous variables with Minnesota');
%     nexogenous = 0;
% end
% if mixed_freq_on == 1 && nexogenous > 0
%     warning('I will not use exogenous variables with missing observations');
%     nexogenous = 0;
% end
% if cfrcst_yes ~= 0 && nexogenous > 0
%     warning('I will not use exogenous variables with conditional forecasts');
%     nexogenous = 0;
% end
% if size(exogenous,1) == size(y,1) && nexogenous > 0
%     warning('For forecast purposes, I will assume that exo are zero out-of sample.')
%     fprintf('To change this, include the exogenous forecasts in options.exogenous.\n')
%     exogenous = [exogenous; zeros(fhor,nexogenous)];
% end
%
% %********************************************************
% %* Priors and Posterior Distributions
% %********************************************************
%
% idx = firstobs+presample-lags:firstobs+nobs-1;
% nx  = 1;
% if noconstant
%     nx = 0;
% end
%
% % organize data as  yy = XX B + E
% [yy,XX] = YXB_(y(idx, :),lags,[nx timetrend]);
%
% ydum    = [];
% xdum    = [];
% pbreaks = 0;
% lambda  = 0;
% mu      = 0;
%
% ydata   = y(idx, :);
% T       = size(ydata, 1);
% if T-lags < lags*ny + nx %+ flat*(ny+1)
%     error('Less observations than regressors: increase the # of obs or decrease the # of lags.')
% end
% xdata   = ones(T,nx);
% if timetrend == 1
%     % xdata = [xdata [1:T]'];
%     xdata = [xdata [1-lags : T-lags]'];
% end
% if nexogenous > 0
%     xdata = [xdata exogenous(idx,:)];
%     XX    = [XX exogenous(idx(1)+lags : idx(end),:)];
% end
%
% % OLS estimate [NO DUMMY]:
% if heterosked == 0
%     varols  = rfvar3(ydata, lags, xdata, [T; T], 0, 0);
% else
%     varols  = rfvar3(ydata, lags, xdata, [T; T], 0, 0, ww);
% end
%
%
% % specify the prior
% if dummy == 1
%     % MINNESOTA PRIOR:
%     mnprior.tight         = minn_prior_tau;
%     mnprior.decay         = minn_prior_decay;
%     % Use only initializations lags for the variance prior
%     % vprior.sig            = std(y(firstobs+presample-lags : firstobs+presample,:))';
%     vprior.sig            = std(y(firstobs-lags : firstobs+presample-1,:))';
%     vprior.w              = minn_prior_omega;
%     lambda                = minn_prior_lambda;
%     mu                    = minn_prior_mu;
%     [ydum, xdum, pbreaks] = varprior(ny, nx, lags, mnprior, vprior);
%     % Prior density
%     Tp = presample + lags;
%     if nx
%         xdata = xdata(1:Tp, :);
%     else
%         xdata = [];
%     end
% %     varp            = rfvar3([ydata(1:Tp, :); ydum], lags, [xdata; xdum], [Tp; Tp + pbreaks], lambda, mu);
%     varp           = rfvar3([y(firstobs-lags : firstobs+presample-1, :); ydum], lags, [xdata; xdum], [Tp; Tp + pbreaks], lambda, mu);
%     Tup            = size(varp.u, 1);
%     prior.df       = Tup - ny*lags - nx - flat*(ny+1);
%     prior.S        = varp.u' * varp.u;
%     prior.XXi      = varp.xxi;
%     prior.PhiHat   = varp.B;
%     prior.YYdum    = varp.y;
%     prior.XXdum    = varp.X;
%     if prior.df < ny
%         error('Too few degrees of freedom in the Inverse-Wishart part of prior distribution. You should increase training sample size.')
%     end
%     prior.minn_prior_tau    = minn_prior_tau;
%     prior.minn_prior_decay  = minn_prior_decay;
%     prior.minn_prior_lambda = minn_prior_lambda;
%     prior.minn_prior_mu     = minn_prior_mu;
%     prior.minn_prior_omega  = minn_prior_omega;
% elseif dummy == 0
%     % JEFFREY OR UNIFORMATIVE PRIOR:
%     % [priors] = jeffrey(y,lags);
%     prior.name  = 'Jeffrey';
%
% end
%
% % specify the posterior (the varols agin on actual+dummy)
% [posterior,var] = posterior_(y);
%
%
% %*********************************************************
% %* Compute the log marginal data density for the VAR model
% %*********************************************************
%
% try
%     posterior_int = matrictint(posterior.S, posterior.df, posterior.XXi);
% catch
%     warning('I could not compute the likelihood');
%     posterior_int = nan;
% end
%
% if dummy == 1 % only for minnesota dummy
%     prior_int = matrictint(prior.S, prior.df, prior.XXi);
%     lik_nobs  = posterior.df - prior.df;
%     log_dnsty = posterior_int - prior_int - 0.5*ny*lik_nobs*log(2*pi);
%
% elseif dummy == 0 % jeffrey prior
%     lik_nobs  = posterior.df;
%     log_dnsty = posterior_int - 0.5*ny*lik_nobs*log(2*pi);
%
% elseif dummy == 2 % conjugate MN-IW prior
%     log_dnsty = mniw_log_dnsty(prior,posterior,varols);
%
% end
%
%
% %**************************************************
% %* Generating draws form the Posterior Distribution
% %**************************************************
%
% % Preallocation of memory
% % Matrices for collecting draws from Posterior Density
% % Last dimension corresponds to a specific draw
% Phi_draws     = zeros(ny*lags+nx+timetrend + nexogenous, ny, K);   % Autoregressive Parameters
% Sigma_draws   = zeros(ny,ny,K);                     % Shocks Covariance
% ir_draws      = zeros(ny,hor,ny,K);                 % variable, horizon, shock and draws - Cholesky IRF
% irlr_draws    = zeros(ny,hor,ny,K);                 % variable, horizon, shock and draws - Long Run IRF
% Qlr_draws     = zeros(ny,ny,K);                     % long run impact matrix
% e_draws       = zeros(size(yy,1), ny,K);                  % residuals
% yhatfut_no_shocks         = NaN(fhor, ny, K);   % forecasts with shocks
% yhatfut_with_shocks       = NaN(fhor, ny, K);   % forecast without the shocks
% yhatfut_cfrcst            = NaN(fhor, ny, K);   % forecast conditional on endogenous path
% logL                      = NaN(K,1);
%
% if signs_irf == 1
%     irsign_draws = ir_draws;
%     Omega_draws    = Sigma_draws;
% end
% if nexogenous > 0
%     irx_draws = zeros(ny,hor,nexogenous,K);
%     % Ox_draws  = Sigma_draws;
% end
% if narrative_signs_irf == 1
%     irnarrsign_draws = ir_draws;
%     Omegan_draws     = Sigma_draws;
% end
% if zeros_signs_irf == 1
%     irzerosign_draws   = ir_draws;
%     Omegaz_draws       = Sigma_draws;
% end
% if proxy_irf == 1
%     irproxy_draws = ir_draws;
% end
%
% % Settings for the forecasts
% forecast_data.xdata       = ones(fhor, nx);
% if timetrend
%     forecast_data.xdata = [forecast_data.xdata (T-lags+1 : T-lags+fhor)'];
% end
% if nexogenous>0
%     forecast_data.xdata = [forecast_data.xdata exogenous(T-lags+1 : T-lags+fhor,:)];
% end
% forecast_data.initval     = ydata(end-lags+1:end, :);
%
% try
%     S_inv_upper_chol    = chol(inv(posterior.S));
% catch
%     warning('POSTERIOR MEAN of SIGMA IS ILL-BEHAVED (NON-POSITIVE DEFINITE)')
%     try
%         warning('I will try with the LDL decomposition')
%         iS               = inv(posterior.S);
%         [L, D, P]        = ldl(iS);
%         S_inv_upper_chol = sqrt(D) * L' * P';%chol()
%     catch
%         warning('I will add +1e-05 to the diagonal')
%         S_inv_upper_chol    = chol(inv(posterior.S + 1e-05*eye(ny)));
%     end
% end
%
%
% XXi_lower_chol      = chol(posterior.XXi)';
%
% nk                  = ny*lags+nx+timetrend + nexogenous;
%
% % Declaration of the companion matrix
% Companion_matrix = diag(ones(ny*(lags-1),1),-ny);
% p  = 0;
% dd = 0;
%
% waitbar_yes = 0;
% if K > 99
%     waitbar_yes = 1;
%     wb = waitbar(0, 'Generating draws from the Posterior Distribution');
% end
%
% for  d =  1 : K
%
%     while dd == 0
%         %======================================================================
%         % Inferece: Drawing from the posterior distribution
%         % Step 1: draw from the Covariance
%         Sigma = rand_inverse_wishart(ny, posterior.df, S_inv_upper_chol);
%
%         % Step 2: given the Covariance Matrix, draw from the AR parameters
%         Sigma_lower_chol = chol(Sigma)';
%         Phi1 = randn(nk * ny, 1);
%         Phi2 = kron(Sigma_lower_chol , XXi_lower_chol) * Phi1;
%         Phi3 = reshape(Phi2, nk, ny);
%         Phi  = Phi3 + posterior.PhiHat;
%
%         Companion_matrix(1:ny,:) = Phi(1:ny*lags,:)';
%         test = (abs(eig(Companion_matrix)));
%         if non_explosive_ == 1
%             % Checking the eigenvalues of the companion matrix (on or inside the
%             % unit circle)
%             if any(test>1.01) %any(test>1.0000000000001)
%                 p = p+1;
%             else
%                 dd = 1;
%             end
%         else
%             dd = 1;
%         end
%     end
%
%     % store the draws
%     Phi_draws(:,:,d)   = Phi;
%     Sigma_draws(:,:,d) = Sigma;
%     errors             = yy - XX * Phi;
%     e_draws(:,:,d)     = errors;
%
%
%     %======================================================================
%     % IRF
%     % Compute the impulse response functions
%     % with cholesky
%     if irf_1STD == 1
%         % one STD increase
%         ir_draws(:,:,:,d)      = iresponse(Phi,Sigma,hor,eye(ny));
%     else
%         % one percent increase
%         ir_draws(:,:,:,d)      = iresponse(Phi,Sigma,hor,eye(ny),0);
%     end
%     if nexogenous > 0
%         Phi1         = Phi(1 : ny*lags + nx + timetrend, 1 : ny);
%         Exo1         = zeros(ny,nexogenous);
%         Exo1(:,1:nx) = Phi(ny*lags + nx + timetrend +1 ....
%                             : ny*lags + nx + timetrend + nexogenous, 1 : ny)';
%         Sig1         = eye(ny);
%         % unitary increase
%         irx_draws(:,:,:,d) = iresponse(Phi1,Sig1,hor,Exo1);
%     end
%
%     % with long run restrictions
%     if long_run_irf == 1
%         [irlr,Qlr]             = iresponse_longrun(Phi,Sigma,hor,lags);
%         irlr_draws(:,:,:,d)    = irlr;
%         Qlr_draws(:,:,d)       = Qlr;
%     end
%     % with sign restrictions
%     if signs_irf == 1
%         [irsign,Omega]         = iresponse_sign(Phi,Sigma,hor,signs);
%         irsign_draws(:,:,:,d)  = irsign;
%         Omega_draws(:,:,d)     = Omega;
%     end
%     % with narrative and sign restrictions
%     if narrative_signs_irf == 1
%         [irnarrsign,Omega]         = iresponse_sign_narrative(errors,Phi,Sigma,hor,signs,narrative);
%         irnarrsign_draws(:,:,:,d)  = irnarrsign;
%         Omegan_draws(:,:,d)        = Omega;
%     end
%     % with zeros and sign restrictions
%     if zeros_signs_irf == 1         %= iresponse_zeros_signs( Phi,Sigma,bvar1.hor,lags,var_pos,f,sr);
%         [irzerosign,Omega]          = iresponse_zeros_signs(Phi,Sigma,hor,lags,var_pos,f,sr);
%         irzerosign_draws(:,:,:,d)   = irzerosign;
%         Omegaz_draws(:,:,d)         = Omega;
%     end
%     % with proxy
%     if proxy_irf == 1
%         in.res                  = e_draws(:,:,d);
%         in.Phi                  = Phi_draws(:,:,d)  ;
%         in.Sigma                = Sigma;
%         tmp_                    = iresponse_proxy(in);
%         irproxy_draws(:,:,1,d)  = tmp_.irs';
%         clear tmp_
%     end
%
%     %======================================================================
%     % Forecasts
%     % compute the out of sample forecast (unconditional)
%     [frcst_no_shock,frcsts_with_shocks] = forecasts(forecast_data,Phi,Sigma,fhor,lags);
%     yhatfut_no_shocks(:,:,d)            = frcst_no_shock;
%     yhatfut_with_shocks(:,:,d)          = frcsts_with_shocks;
%
%     if cfrcst_yes == 1
%         % Forecast conditional on the path of an endo var using all shocks
%         [sims_with_endopath,EPS(:,:,d)] = ...
%             cforecasts(endo_path,endo_path_index,forecast_data,Phi,Sigma);
%         yhatfut_cfrcst(:,:,d) = sims_with_endopath;
%
%     elseif cfrcst_yes == 2
%         % Forecast conditional on the path of an endo var using only a
%         % subset of shocks. notice that the # of endo and # exo must coincide
%         % Omega is the structural orthonormal matrix
%         [sims_with_endopath,EPS(:,:,d)] = ...
%             cforecasts2(endo_path,endo_path_index,exo_index,forecast_data,Phi,Sigma,Omega);
%         yhatfut_cfrcst(:,:,d) = sims_with_endopath;
%     end
%
%
%     %======================================================================
%     % Mixed Frequency
%     if mixed_freq_on
%         % Checking the eigenvalues of the companion matrix (on or inside the
%         % unit circle). Needed for the initial of KF
%         Companion_matrix(1:ny,:) = Phi(1:ny*lags,:)';
%         %test = (abs(eig(Companion_matrix)));
%         if any(test>1.0000000000001)
%             KFoptions.initialCond = 1;
%         end
%         KFoptions.index   = index;
%         KFoptions.noprint = noprint;
%         % Forward Kalman Filter and Smoother
%         [logL,KFout]          = kfilternan(Phi,Sigma,yoriginal,KFoptions);
%         yfill(:,:,d)     = KFout.smoothSt_plus_ss(:,KFout.index_var);
%         yfilt(:,:,d)     = KFout.filteredSt_plus_ss(:,KFout.index_var);
%         % recompute the posterior with smoothed data
%         [posterior1]     = posterior_(yfill(:,:,d));
%         S_inv_upper_chol = chol(inv(posterior1.S));
%         XXi_lower_chol   = chol(posterior1.XXi)';
%         posterior.PhiHat = posterior1.PhiHat;
%         forecast_data.initval = yfill(end-lags+1:end, :, d);
%         logL(d) = KFout.logL;
%     end
%     if waitbar_yes, waitbar(d/K, wb); end
%     dd = 0; % reset
% end
% if waitbar_yes, close(wb); end
%
%
% %********************************************************
% %* Storing the resutls
% %*******************************************************
%
% % classical inference: OLS estimator
% BVAR.Phi_ols    = varols.B;
% BVAR.e_ols      = varols.u;
% BVAR.Sigma_ols  = 1/(nobs-nk)*varols.u'*varols.u;
% [BVAR.InfoCrit.AIC, BVAR.InfoCrit.HQIC, BVAR.InfoCrit.BIC] = IC(BVAR, nobs, nk);
% % the model with the lowest IC is preferred
%
% % OLS irf
% BVAR.ir_ols      = iresponse(BVAR.Phi_ols,BVAR.Sigma_ols,hor,eye(ny));
% if long_run_irf == 1
%     [irlr,Qlr]              = iresponse_longrun(BVAR.Phi_ols,BVAR.Sigma_ols,hor,lags);
%     BVAR.irlr_ols           = irlr;
%     BVAR.Qlr_ols(:,:)       = Qlr;
% end
%
% % test the normality of the ols VAR residuals (matlab stat toolbox needed)
% if  exist('kstest') ==2
%     for gg = 1 : ny
%         [H,Pv] = kstest(BVAR.e_ols(:,gg)/sqrt(BVAR.Sigma_ols(gg,gg)));
%         BVAR.HP(gg,:) = [H,Pv];
%     end
% else
%     BVAR.HP = [];
% end
%
% % bayesian inference:
% % the last dimension of these objects corresponds to a draw from the posterior
%
% % inference and IRFs
% BVAR.Phi_draws    = Phi_draws;          % draws from the autoregressive part
% BVAR.Sigma_draws  = Sigma_draws;        % draws from the covarance matrix
% BVAR.alpha_draws  = Phi_draws;          % Older name: draws from the autoregressive part
% BVAR.sigma_draws  = Sigma_draws;        % Older name: draws from the covarance matrix
%
% BVAR.ir_draws     = ir_draws;           % draws from the IRF with cholesky
% BVAR.irlr_draws   = irlr_draws;         % draws from the IRF with Long Run
% BVAR.Qlr_draws    = Qlr_draws;          % Long Run Rotation matrix
% BVAR.lags         = lags;               % lags
% BVAR.N            = ny;                 % number of variables
% BVAR.e_draws      = e_draws;            % residuals
% BVAR.e            = e_draws;            % backward compatible with earlier versions
%
% BVAR.posterior    = posterior;
% BVAR.prior        = prior;             % priors used
% BVAR.logmlike     = log_dnsty;
% BVAR.X            = var.X;              % regressors (including dummy if Minnesota)
% BVAR.y            = var.y;              % dependent  (including dummy if Minnesota)
% BVAR.XX           = XX;                 % regressors (no dummy)
% BVAR.yy           = yy;                 % dependent  (no dummy)
%
% % prediction
% BVAR.fhor         = fhor;               % forecast horizon
% BVAR.hor          = hor;                % IRF horizon
% BVAR.forecasts.no_shocks      = yhatfut_no_shocks;         % trajectories of forecasts without shocks
% BVAR.forecasts.with_shocks    = yhatfut_with_shocks;       % trajectories of forecasts with shocks
% BVAR.forecasts.conditional    = [];            % trajectories of conditional forecasts
% BVAR.forecasts.EPScond        = [];            % shocks of conditional forecasts
% if cfrcst_yes ~= 0
%     BVAR.forecasts.conditional    = yhatfut_cfrcst;            % trajectories of forecasts
%     BVAR.forecasts.EPScond        = EPS;                       % shocks of forecasts
% end
% BVAR.forecast_data            = forecast_data;
%
% %
% BVAR.varnames     = varnames;
% BVAR.ndraws       = K;
%
% if signs_irf == 1 && narrative_signs_irf == 0
%     BVAR.irsign_draws = irsign_draws;
%     BVAR.Omegas       = Omega_draws;
% else
%     BVAR.irsign_draws = [];
%     BVAR.Omegas       = [];
% end
% if narrative_signs_irf == 1
%     BVAR.irnarrsign_draws = irnarrsign_draws;
%     BVAR.Omegan           = Omegan_draws;
% else
%     BVAR.irnarrsign_draws = [];
%     BVAR.Omegan           = [];
% end
% if zeros_signs_irf == 1
%     BVAR.irzerosign_draws   = irzerosign_draws;
%     BVAR.Omegaz             = Omegaz_draws;
% else
%     BVAR.irzerosign_draws = [];
%     BVAR.Omegaz           = [];
% end
% if proxy_irf == 1
%     BVAR.irproxy_draws = irproxy_draws;
% else
%     BVAR.irproxy_draws= [];
% end
% if nexogenous > 0
%     BVAR.irx_draws = irx_draws;
% else
%     BVAR.irx_draws = [];
% end
%
% % missing observations
% BVAR.data         = y;                  % raw data
% if mixed_freq_on
%     BVAR.yfill = yfill;
%     BVAR.yfilt = yfilt;
%     BVAR.yinterpol = yinterpol;
%     BVAR.logL  = logL;
% end
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % end of bvar.m
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% %********************************************************
% %********************************************************
%     function [posterior,var] = posterior_(y)
%
%         % This part is needed in the case of missing values. The posterior
%         % needs to be revaluated given a new value of the Kalman smoothed
%         % observables
%         %===========================================
%         ydata = y(idx, :);
%         %===========================================
%         T     =  size(ydata, 1);
%         xdata = ones(T,nx);
%         if timetrend ==1
%             xdata = [xdata [1-lags:T-lags]'];
%             % xdata = [xdata [1:T]'];
%         end
%         if nexogenous >0
%             xdata = [xdata exogenous(idx,:)];
%         end
%         % posterior density
%         if heterosked == 0
%             var = rfvar3([ydata; ydum], lags, [xdata; xdum], [T; T+pbreaks], lambda, mu);
%         else
%             var = rfvar3([ydata; ydum], lags, [xdata; xdum], [T; T+pbreaks], lambda, mu, ww);
%         end
%         Tu = size(var.u, 1);
%
%         if dummy ==  1
%             %********************************************************
%             % Minnesota Prior
%             %********************************************************
%             % Prior density
%             Tp = presample + lags;
%             if nx
%                 xdata = xdata(1:Tp, :);
%             else
%                 xdata = [];
%             end
%             % varp            = rfvar3([ydata(1:Tp, :); ydum], lags, [xdata; xdum], [Tp; Tp + pbreaks], lambda, mu);
%             varp            = rfvar3([y(firstobs-lags : firstobs+presample-1, :); ydum], lags, [xdata; xdum], [Tp; Tp + pbreaks], lambda, mu);
%             Tup             = size(varp.u, 1);
%             prior.df        = Tup - ny*lags - nx - flat*(ny+1);
%             prior.S         = varp.u' * varp.u;
%             prior.XXi       = varp.xxi;
%             prior.PhiHat    = varp.B;
%             priors.YYdum    = varp.y;
%             priors.XXdum    = varp.X;
%             if prior.df < ny
%                 error('Too few degrees of freedom in the Inverse-Wishart part of prior distribution. You should increase training sample size.')
%             end
%             posterior.df    = Tu - ny*lags - nx - flat*(ny+1);
%             posterior.S     = var.u' * var.u;
%             posterior.XXi   = var.xxi;
%             posterior.PhiHat = var.B;
%
%         elseif dummy == 2
%             %********************************************************
%             % Conjugate Prior
%             %********************************************************
%             Ai              = inv(prior.Phi.cov);
%             posterior.df    = Tu - ny*lags - nx - nexogenous - prior.Sigma.df;
%             posterior.XXi   = inv(var.X'*var.X + Ai);
%             posterior.PhiHat = posterior.XXi * (var.X' * var.y + Ai * prior.Phi.mean);
%             %posterior.S     = var.u' * var.u + prior.Sigma.scale ;
%             %posterior.S     = var.u' * var.u + prior.Sigma.scale  + (var.B - prior.Phi.mean)' * Ai * (var.B - prior.Phi.mean);
%             %posterior.S     = var.u' * var.u + prior.Sigma.scale  + ...
%             %    (posterior.PhiHat - prior.Phi.mean)' * Ai * (var.B - prior.Phi.mean);
%             % check
%             posterior.S = var.u' * var.u + prior.Sigma.scale + ...
%                 prior.Phi.mean' * Ai * prior.Phi.mean + ...
%                 var.B' * (var.X'*var.X) * var.B ...
%                 - posterior.PhiHat' * (var.X'*var.X + Ai) * posterior.PhiHat;
%
%         else
%             %********************************************************
%             % Flat Jeffrey Prior
%             %********************************************************
%             posterior.df    = Tu - ny*lags - nx + flat*(ny+1) - nexogenous;
%             posterior.S     = var.u' * var.u;
%             posterior.XXi   = var.xxi;
%             posterior.PhiHat = var.B;
%         end
%
%     end
% %********************************************************
% %********************************************************
%     function [priors] = priors_( )
%
%         priors.name  = 'N/A';
%
%     end
% %********************************************************
% %********************************************************
%
% end


function p = fixOperatorProperties(p)

for i = 1:length(p.evalMap)
    % y = f(x)
    y = p.evalVariables(i);
    x = p.evalMap{i}.variableIndex;
    xL = p.lb(x);
    xU = p.ub(x);

    properties = p.evalMap{i}.properties;
    % Can convexity be fixed for xL <= x <= xL?
    if any(xL<xU) && (isa(properties.convexity,'function_handle') || ~isempty(properties.inflection) || strcmp(properties.convexity,'none'))
        vexity = 'none';
        % User-supplied code to derive convexity
        if isa(properties.convexity,'function_handle')
            vexity = properties.convexity(xL,xU);
        end
        % No such code, or code does not work as expected? Check inflection
        if isequal(vexity,'none') && ~isempty(properties.inflection)
            vexity = DeriveVexityFromInflection(properties,xL,xU);
        end
        if ~isequal(vexity,'none')
            % We have managed to fix convexity
            properties.convexity = vexity;
            % Since convexity is known, we can append a convex hull method
            if isempty(properties.convexhull) && ~isempty(properties.derivative)
                if isequal(vexity,'convex')
                    %f0 = @(x)real(eval([p.evalMap{i}.fcn '(x)']));
                    f0 = p.evalMap{i}.properties.function;
                    f = @(xL,xU)createConvexHullMethodConvex(xL,xU,f0,properties.derivative);
                elseif isequal(vexity,'concave')
                    %f0 = @(x)real(eval([p.evalMap{i}.fcn '(x)']));
                    f0 = p.evalMap{i}.properties.function;
                    f = @(xL,xU)createConvexHullMethodConcave(xL,xU,f0,properties.derivative);
                else
                    f = [];
                end
                properties.convexhull = f;
            end
        end
    end
    if any(xL<xU)
        if isa(properties.monotonicity,'function_handle')
            mono = properties.monotonicity(xL,xU);
            if ~isequal(mono,'none')
                properties.monotonicity = mono;
            end
        elseif ~isempty(properties.stationary) && (isequal(properties.shape,'bell-shape') || isequal(properties.shape,'v-shape'))
            mono = DeriveMonotonicityFromShape(properties,xL,xU);
            if ~isequal(mono,'none')
                properties.monotonicity = mono;
            end
        end
    end
    % Save possibly updated properties
    p.evalMap{i}.properties = properties;

    if isempty(p.evalMap{i}.properties.f_upper)
        if isequal(p.evalMap{i}.properties.convexity,'convex')
            %f = makefunction(p.evalMap{i}.fcn);
            f = p.evalMap{i}.properties.function;
            f_upper = @(z,xL,xU)(f(xL) + (z-xL)*(f(xU)-f(xL))/(xU-xL));
            df_upper = @(z,xL,xU)((f(xU)-f(xL))/(xU-xL));
            p.evalMap{i}.properties.f_upper = f_upper;
            p.evalMap{i}.properties.df_upper = df_upper;
        end
    end
    if isempty(p.evalMap{i}.properties.f_lower)
         if isequal(p.evalMap{i}.properties.convexity,'concave')
            %f = makefunction(p.evalMap{i}.fcn);
            f = p.evalMap{i}.properties.function;
            f_lower = @(z,xL,xU)(f(xL) + (z-xL)*(f(xU)-f(xL))/(xU-xL));
            df_lower = @(z,xL,xU)((f(xU)-f(xL))/(xU-xL));
            p.evalMap{i}.properties.f_lower = f_lower;
            p.evalMap{i}.properties.df_lower = df_lower;
        end
    end
end


% GAINSANDREFERENCES initializes the controller parameters: gains,
%                    regularization parameters and references.
%

%% --- Initialization ---

% References for the demo with joints movements
if Config.MOVE_JOINTS

    % Postural task gains
    KP = 20*diag(ones(1,ROBOT_DOF));
    KD = 2*sqrt(KP)*0;

    Ref.Amplitude = 7.5*ones(1,ROBOT_DOF);
    Ref.Frequency = 0.5*ones(1,ROBOT_DOF);
else
    % Postural task gains
    KP = 0*diag(ones(1,ROBOT_DOF));
    KD = 0*2*sqrt(KP);

    Ref.Amplitude = 0*ones(1,ROBOT_DOF);
    Ref.Frequency = 0*ones(1,ROBOT_DOF);
end

if size(KP,1) ~= ROBOT_DOF

    error('Dimension of KP different from ROBOT_DOF')
end


function ye = pbd(t, x, y, side)
%PBD	Prescribes pressure p at outflow boundaries
% Possible values for side: 'lower', 'upper',  'left', 'right'

global geval Re

ye = 0;
if geval == 1|geval == 7		% Horizontal Poiseuille flow
  if strcmp(side, 'right') == 1		% Outflow
    ye = 0;
  else
    ye = 0;
  end
elseif geval == 2	% Vertical Poiseuille flow
  if strcmp(side, 'upper') == 1		% Outflow
    ye = 0;
  else
    ye = 0;
  end
elseif geval == 3	% Backward facing step
    ye = 0;
elseif geval == 4	% Driven cavity
    ye = 0;
elseif geval == 5|geval == 6	% Uniform flow under angle alpha
  ye = 1;
else
  error('Wrong value in input for parameter geval')
end


function g = translateKernGradient(kern, varargin)

% TRANSLATEKERNGRADIENT Gradient of TRANSLATE kernel's parameters.
% FORMAT
% DESC computes the gradient of functions with respect to the
% input space translation
% kernel's parameters. As well as the kernel structure and the
% input positions, the user provides a matrix PARTIAL which gives
% the partial derivatives of the function with respect to the
% relevant elements of the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x : the input locations for which the gradients are being
% computed.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The argument takes
% the form of a square matrix of dimension  numData, where numData is
% the number of rows in X.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters. The ordering of the vector should match
% that provided by the function kernExtractParam.
%
% FORMAT
% DESC computes the derivatives as above, but input locations are
% now provided in two matrices associated with rows and columns of
% the kernel matrix.
% ARG kern : the kernel structure for which the gradients are being
% computed.
% ARG x1 : the input locations associated with the rows of the
% kernel matrix.
% ARG x2 : the input locations associated with the columns of the
% kernel matrix.
% ARG partial : matrix of partial derivatives of the function of
% interest with respect to the kernel matrix. The matrix should
% have the same number of rows as X1 and the same number of columns
% as X2 has rows.
% RETURN g : gradients of the function of interest with respect to
% the kernel parameters.
%
% SEEALSO translateKernParamInit, kernGradient,
% translateKernDiagGradient, cmpndKernGradient, cmpndKernGradX, kernGradX
%
% COPYRIGHT : Neil D. Lawrence, 2007

% KERN

for i = 1:length(varargin)-1
  varargin{i} = varargin{i} - repmat(kern.centre, size(varargin{i}, 1), 1);
end
g = cmpndKernGradient(kern, varargin{:});

% Gradients with respect to X.
if length(varargin) == 2
  gKX = cmpndKernGradX(kern, varargin{1}, varargin{1});
  gKX = gKX*2;
  dgKX = cmpndKernDiagGradX(kern, varargin{1});
  for i = 1:size(gKX, 1)
    gKX(i, :, i) = dgKX(i, :);
  end
else
  gKX_12 = cmpndKernGradX(kern, varargin{1}, varargin{2});
  gKX_21 = cmpndKernGradX(kern, varargin{2}, varargin{1});
end

gcentre = zeros(1, kern.inputDimension);
if length(varargin) == 2
  for i = 1:size(varargin{1}, 1);
    for j = 1:kern.inputDimension
      gcentre(1, j) = gcentre(1, j) - gKX(:, j, i)'*varargin{end}(:, i);
    end
  end
else
  for i = 1:size(varargin{1}, 1)
    for j = 1:kern.inputDimension
      gcentre(1, j) = gcentre(1, j) - sum(gKX_12(:, j, i).*varargin{end}(i, :)');
    end
  end
  for i = 1:size(varargin{2}, 1)
    for j = 1:kern.inputDimension
      gcentre(1, j) = gcentre(1, j) - sum(gKX_21(:, j, i).*varargin{end}(:, i));
    end
  end
end
g = [g gcentre];


function faces = compute_voronoi_triangulation(Q, vertex)

% compute_voronoi_triangulation - compute a triangulation
%
%   face = compute_voronoi_triangulation(Q);
%
%   Q is a Voronoi partition function, computed using
%       perform_fast_marching.
%   face(:,i) is the ith face.
%
%   Works in 2D and in 3D.
%
%   Copyright (c) 2008 Gabriel Peyre

d = nb_dims(Q);

if d==2
    faces = compute_voronoi_triangulation_2d(Q, vertex);
elseif d==3
    faces = compute_voronoi_triangulation_3d(Q, vertex);
else
    error('Works only for 2D or 3D data.');
end

return;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function faces = compute_voronoi_triangulation_3d(Q, vertex)

[dx dy dz] = meshgrid(0:1,0:1,0:1);
V = [];
for i=1:8
    v = Q(1+dx(i):end-1+dx(i),1+dy(i):end-1+dy(i),1+dz(i):end-1+dz(i));
    V = [V v(:)];
end

V = sort(V,2);
V = unique(V, 'rows');
V = V( prod(V,2)>0 ,:);

d = V(:,1)*0;
for i=1:7
   d = d+(V(:,i)~=V(:,i+1));
end
if sum(d==4)>1
%    warning('Problem with triangulation.');
end

% split 5 folds into 2
I = find(d==4);
faces = [];
for i=1:length(I)
    v = unique(V(I(i),:));
    x = vertex(:,v); % points
    % barycenter
    a = sum( x, 2 ) / 5;
    x = x-repmat(a, [1 size(x,2)]);
    t = atan2(x(2,:),x(1,:));
    [tmp,s] = sort(t);
    faces = [faces v( s([1 2 3 5]))'];
    faces = [faces v( s([3 4 1 5]))'];

end
%    faces = [V(I,1:3);V(I,[3 4 1])];

% remaining triangles
V = V( d==3 ,:);
for i=1:size(V,1)
    V(i,1:4) = unique(V(i,:));
end
faces = [faces, V(:,1:4)'];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function faces = compute_voronoi_triangulation_2d(Q, vertex)

V = [];
v = Q(1:end-1,1:end-1); V = [V v(:)];
v = Q(2:end,1:end-1); V = [V v(:)];
v = Q(1:end-1,2:end); V = [V v(:)];
v = Q(2:end,2:end); V = [V v(:)];

V = sort(V,2);
V = unique(V, 'rows');
V = V( prod(V,2)>0 ,:);

d = (V(:,1)~=V(:,2)) + (V(:,2)~=V(:,3)) + (V(:,3)~=V(:,4));
if sum(d==3)>1
    warning('Problem with triangulation.');
end

% split squares into 2 triangles
I = find(d==3);
faces = [];
for i=1:length(I)
    v = V(I(i),:);
    x = vertex(:,v); % points
    % barycenter
    a = sum( x, 2 ) / 4;
    x = x-repmat(a, [1 size(x,2)]);
    t = atan2(x(2,:),x(1,:));
    [tmp,s] = sort(t);
    faces = [faces; v( s([1 2 3]))];
    faces = [faces; v( s([3 4 1]))];

end
%    faces = [V(I,1:3);V(I,[3 4 1])];

% remaining triangles
V = V( d==2 ,:);
for i=1:size(V,1)
    V(i,1:3) = unique(V(i,:));
end
faces = [faces; V(:,1:3)];

% return in correct format
faces = faces';


function [eparams, errors] = calibrateEdgeClassifier(efeatures, adjlist, imsegs, eclassifier, ncv)
% [eparams, errors] = calibrateEdgeClassifier(efeatures, adjlist, imsegs,
% eclassifier, ncv)

nimages = numel(imsegs);
for k = 1:ncv
    testind = [(k-1)*nimages/ncv+1:k*nimages/ncv];
    trainind = setdiff([1:nimages], testind);
    [edata{k}, elab{k}] = formatData(efeatures(trainind), adjlist(trainind), {imsegs(trainind).labels});
    econf{k} = test_boosted_dt_mc(eclassifier, edata{k});
%    econf{k} = 1 ./ (1+exp(-econf{k}));
end

for k = 1:ncv
    disp(['iter: ' num2str(k)])
    traink = setdiff([1:ncv], k);
    eparams{k} = fminunc(@(x) objective(x, cat(1, econf{traink}), cat(1, elab{traink})), [-1 0], optimset('TolFun', 0.001));
end

for k = 1:ncv
    econf{k} = 1 ./ (1+exp(eparams{k}(1)*econf{k}+eparams{k}(2)));
end

elab = cat(1, elab{:});
econf = cat(1, econf{:});

eerror = mean((econf>0.5)~=elab);

econf2 = 1-abs(elab-econf);

ind1 = find(elab==0);
ind2 = find(elab==1);
px = [0.025:0.05:0.975];
f1 = ksdensity(econf(ind1), px, 'support', [0 1]);
f2 = ksdensity(econf(ind2), px, 'support', [0 1]);
fc = ksdensity(econf2, px, 'support', [0 1]);
%fc = fc;

errors.err = eerror;
errors.pneg = f1;
errors.ppos = f2;
errors.conf = fc;
errors.px = px;

medFS = 18;
bigFS = 20;

figure(1), hold on, plot(px, fc, 'y', 'LineWidth', 2);
%axis([0 1 0 1])
xlabel('Confidence in True Label', 'FontSize', medFS)
ylabel('Frequency', 'FontSize', medFS)
title('Same Label Confidence', 'FontSize', bigFS)
set(gca, 'FontSize', medFS)

figure(2), hold on, plot(px, f2 ./ (f1+f2), 'y', 'LineWidth', 2)
hold on, plot(px, px, '--k')
axis([0 1 0 1])
xlabel('Estimated Probability', 'FontSize', medFS)
ylabel('Empirical Probability', 'FontSize', medFS)
%title('Same Label Confidence', 'FontSize', bigFS)
set(gca, 'FontSize', medFS)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function err = objective(param, econf, elab)
econf = 1./(1+exp(param(1)*econf+param(2)));
px = [0.025:0.05:0.975];
f1 = ksdensity(econf(elab==0), px, 'support', [0 1])+1E-10;
f2 = ksdensity(econf(elab==1), px, 'support', [0 1])+1E-10;
f1 = f1 / sum(f1+f2);
f2 = f2 / sum(f1+f2);
err = sum((f1+f2).*(px - f2./(f1+f2)).^2);
disp(num2str([sum((f1+f2).*abs(px - f2./(f1+f2))) param]))

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [data, lab] = formatData(features, adjlist, labels)
% concatenate data and select ndata random datapoints

nimages = numel(features);

[tmp, nvars] = size(features{1});

% count edges
ne = 0;
for f = 1:nimages
    ne = ne + size(features{f}, 1);
end

data = zeros(ne, nvars);
lab = zeros(ne, 1);

% concatenate data
c = 0;
for f = 1:nimages
    cf = size(features{f}, 1);
    data(c+1:c+cf, :) = features{f};
    s1 = adjlist{f}(:, 1);
    s2 = adjlist{f}(:, 2);
    lab(c+1:c+cf) = (labels{f}(s1)==labels{f}(s2));
    c = c + cf;
end


%% Rectangle
% Concrete subclass of <ZeroVolShape.html |Shape|> representing a rectangular
% patch.

%%% Description
% |Rectangle| represents the shape of a rectangle on a plane.  It does not have
% a volume, but it is used to force a user-defined primary grid plane and four
% primary grid lines, which corresponds to the four sides of the rectangle, in
% <maxwell_run.html |maxwell_run|>.

%%% Construction
%  shape = Rectangle(normal_axis, intercept, rect)
%  shape = Rectangle(normal_axis, intercept, rect, dl_max)

% *Input Arguments*
%
% * |normal_axis|: axis normal to the plane of the rectangle.  It should be one
% of |Axis.x|, |Axis.y|, |Axis.z|.
% * |intercept|: location of the rectangle in the |normal_axis| direction.
% * |rect|: bounds of the rectangle in the plane.  If |normal_axis == Axis.y|,
% it should be in the format of |[zmin zmax; xmin xmax]|.
% * |dl_max|: maximum grid size allowed in the rectangle.  It can be either |[dx
% dy dz]| or a single real number |dl| for |dx = dy = dz|.  If unassigned,
% |dl_max = Inf| is used.  In the |normal_axis| direction, |dl_max| is
% meaningless.

%%% Example
%   % Create an instance of Rectangle.
%   shape = Rectangle(Axis.z, 100, [0 100; 0 100]);
%
%   % Use the constructed shape in maxwell_run().
%   [E, H] = maxwell_run({INITIAL ARGUMENTS}, 'OBJ', {'vacuum', 'none', 1.0}, shape, {REMAINING ARGUMENTS});

%%% See Also
% <Plane.html |Plane|>, <Line.html |Line|>, <Point.html |Point|>,
% <ZeroVolShape.html |ZeroVolShape|>, <maxwell_run.html |maxwell_run|>

classdef Rectangle < ZeroVolShape
	% Plane is a Shape for a plane.

	properties
		normal_axis
		intercept
		rect
	end

	methods
        function this = Rectangle(normal_axis, intercept, rect, dl_max)
			chkarg(istypesizeof(normal_axis, 'Axis'), '"normal_axis" should be instance of Axis.');
			chkarg(istypesizeof(intercept, 'real'), '"intercept" should be real.');
			chkarg(istypesizeof(rect, 'real', [Dir.count Sign.count]), ...
				'"rect" should be %d-by-%d array with real elements.', Dir.count, Sign.count);

			bound = NaN(Axis.count, Sign.count);
			bound(normal_axis, :) = [intercept intercept];
			[h, v] = cycle(normal_axis);
			bound([h v], :) = rect;

			box = Box(bound);
			plane = Plane(normal_axis, intercept);
			function level = lsf(x, y, z)
				chkarg(istypeof(x, 'real'), '"x" should be array with real elements.');
				chkarg(istypeof(y, 'real'), '"y" should be array with real elements.');
				chkarg(istypeof(z, 'real'), '"z" should be array with real elements.');
				chkarg(isequal(size(x), size(y), size(z)), '"x", "y", "z" should have same size.');

				% box.lsf(loc{:}) generates -Inf even for points slightly away
				% from the rectangle plane, because of the division by
				% s(normal_dir) == 0.  (Note: 1/0 = Inf.)  This is fine as a
				% behavior of lsf(), but then ZeroVolShape.lsf(loc{:}, true)
				% fails.  To solve this difficulty, modify lsf() not to divide
				% by zero.
				loc = {x, y, z};
				loc{normal_axis} = intercept(ones(size(x)));

				level = min(box.lsf(loc{:}), plane.lsf(x, y, z));  % intersection between box and plane
			end

			lprim = cell(1, Axis.count);
			for w = Axis.elems
				lprim{w} = box.bound(w,:);
			end

			if nargin < 4  % no dl_max
				super_args = {lprim, @lsf};
			else
				dl_max = expand2row(dl_max, Axis.count);
				dl_max(normal_axis) = Inf;  % dl_max is meaningless in normal direction
				super_args = {lprim, @lsf, dl_max};
			end

			this = this@ZeroVolShape(super_args{:});
			this.normal_axis = normal_axis;
			this.intercept = intercept;
			this.rect = rect;
		end
	end
end


% load camera results (for setting active images, n_ima,...)
load camera_results;

% Projection settings:

wintx = 12; %8;
winty = 12; %8;
nx = 1024;
ny = 768;
dX = 32;
dY = 32;
dXoff=511.5;
dYoff=383.5;

proj_name = 'proj'; %input('Basename projector calibration images (without number nor suffix): ','s');
camera_name = 'cam';

xr_list = NaN*ones(1,n_ima);
yr_list = NaN*ones(1,n_ima);

ind_proc = ind_active;

DEBUG = 1;
%ind_ima_proj = [18];

for i = ind_proc,

   projector_marker;

end;

fprintf(1,'\nExtraction of the grid corners on the image\n');

recompute_corner = 0;

if recompute_corner & ~exist(['xproj_' num2str(ind_proc(1))]),
   if exist('projector_data'),
      load projector_data;
   else
      recompute_corner = 0;
      disp('WARNING: Cannot recompute corners. Data need to be extracted at least once');
   end;
end;

if ~recompute_corner,
   disp('Manual extraction mode');
else
   disp('Automatic recomputation of the corners');
end;

% extract the projector corners:

for kk = ind_proc,

   projector_ima_corners

end;

string_save = 'save projector_data ';

for kk = ind_active,
   string_save = [string_save ' xproj_' num2str(kk) ' x_proj_' num2str(kk)];
end;
eval(string_save);

return;

i = 18;

figure(4)
image(I_29);
colormap(gray(256));
hold on;
plot(x_29(1,:)+1,x_29(2,:)+1,'r+','markersize',13,'linewidth',3)
hold off;
axis image
axis off;


clear
savethis = 1;
ncomp = [4];
niter=1; %number of evaluation of each dataset

for ncompindex = 1:length(ncomp);
    for iterindex=1:niter
        ca;
        data_core = 'D3ptBMrand_N3_offset50_delta10';
        if savethis
            [peval.logfile, peval.fid] = initlogfile;
        end

        paramsVAR %reads the parameters
        datasource = [peval.home '/' peval.data_path '/' peval.data_dir '/' peval.data_file];

        readdata

        % Estimating / subtracting background:
        %         [dpixc, peval]=backgroundestimation(dpixc, peval, p.offset);

        peval.bg=p.offset;
        %         dpixc=bgsubtractbyhand(dpixc,peval);
        peval.ncomp=ncomp(ncompindex);

        % Initialization of W:
        %             winit = init_wmap('rand',peval,double(array2im(dpixc_ind)));
        winit = init_w_general(peval.init_w_method,peval,[p.x_vec, p.y_vec]);
        hinit = init_h_general(peval.init_h_method,peval,[],dpixc);

        dvec=reshape(dpixc,peval.nx*peval.ny,peval.nt);

        % Main computation:
        [res, peval]=peval.fun(peval, dvec,winit, hinit);

        if savethis
            peval = createresname(peval,iterindex);
            saveresults(res, peval, p, [peval.res_path peval.res_dir '/' peval.res_name])
            fclose(peval.fid(2));
        end
    end
    if savethis
        % Saving parametes and logfile into the directory with resuls
        saveparameters(peval,p)
    end
end
% plottingmulti
% plotscattehvsblinkmat


% Rolls NN params vector into the matrix.
function nn_params_rolled = nn_params_roll(nn_params_unrolled, layers)
    % Calculate the total number of layers.
    L = length(layers);

    nn_params_rolled = {};
    unrolled_shift = 0;

    for layer_number=1:(L-1)
        L_in = layers(layer_number);
        L_out = layers(layer_number + 1);

        params_width = L_in + 1;  % We need to remember about bias unit.
        params_height = L_out;
        params_volume = params_height * params_width;

        % We need to remember about bias units when rolling up params.
        layer_params_unrolled = nn_params_unrolled((unrolled_shift + 1):(unrolled_shift + params_volume), 1);
        nn_params_rolled{layer_number} = reshape(layer_params_unrolled, params_height, params_width);

        unrolled_shift = unrolled_shift + params_volume;
    end
end


function test_suite = test_distancePointMesh
%TEST_DISTANCEPOINTTRIMESH  One-line description here, please.
%
%   output = test_distancePointMesh(input)
%
%   Example
%   test_distancePointMesh
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2018-03-08,    using Matlab 9.3.0.713579 (R2017b)
% Copyright 2018 INRA - Cepia Software Platform.

% corps du fichier contenant la suite de tests

% testSuite = buildFunctionHandleTestSuite(localfunctions);
test_suite = functiontests(localfunctions);

function testTetraedron(testCase) %#ok<*DEFNU>

[v, f] = createOctahedron;

testCase.assertEqual(1, distancePointMesh([2 0 0], v, f), .0001);
testCase.assertEqual(1, distancePointMesh([0 2 0], v, f), .0001);
testCase.assertEqual(1, distancePointMesh([0 0 2], v, f), .0001);
testCase.assertEqual(1, distancePointMesh([-2 0 0], v, f), .0001);
testCase.assertEqual(1, distancePointMesh([0 -2 0], v, f), .0001);
testCase.assertEqual(1, distancePointMesh([0 0 -2], v, f), .0001);

exp = sqrt(2) / 2;
testCase.assertEqual(exp, distancePointMesh([1 1 0], v, f), .0001);
testCase.assertEqual(exp, distancePointMesh([1 0 1], v, f), .0001);
testCase.assertEqual(exp, distancePointMesh([0 1 1], v, f), .0001);

function testSingleTriangle(testCase)

v = [10 10 10 ; 20 10 10 ; 10 20 10];
f = [1 2 3];

% around lower left corner
testCase.assertEqual(2, distancePointMesh([ 10  8 10 ], v, f), .0001);
testCase.assertEqual(2, distancePointMesh([  8 10 10 ], v, f), .0001);
testCase.assertEqual(2, distancePointMesh([ 12  8 10 ], v, f), .0001);
testCase.assertEqual(2, distancePointMesh([  8 12 10 ], v, f), .0001);
testCase.assertEqual(2*sqrt(2), distancePointMesh([  8  8 10 ], v, f), .0001);
% more around lower left corner
testCase.assertEqual(sqrt(5), distancePointMesh([  8  9 10 ], v, f), .0001);
testCase.assertEqual(sqrt(5), distancePointMesh([  9  8 10 ], v, f), .0001);

% around right corner
testCase.assertEqual(2, distancePointMesh([ 20  8 10 ], v, f), .0001);
testCase.assertEqual(2, distancePointMesh([ 18  8 10 ], v, f), .0001);
testCase.assertEqual(2, distancePointMesh([ 22 10 10 ], v, f), .0001);
testCase.assertEqual(2*sqrt(2), distancePointMesh([ 22  8 10 ], v, f), .0001);
testCase.assertEqual(sqrt(5), distancePointMesh([ 22  9 10 ], v, f), .0001);

% around top left corner
testCase.assertEqual(sqrt(5), distancePointMesh([  9 22 10 ], v, f), .0001);

function test_ortho_diag(testCase)
% bug found when updating distancePointMesh function
%
% mesh is a single face, query point is above the largest side of the
% triangle.
v = [0 0 0; 10 0 0; 0 10 0];
f = [1 2 3];
point111 = [11 1 0];
d = distancePointMesh(point111, v, f, 'algorithm', 'vectorized');
testCase.assertEqual(sqrt(2), d, 0.0001);

function testSingleTriangleAllSubregions(testCase)
% The algorithm described in "David Eberly, 'Distance Between Point and
% Triangle in 3D', Geometric Tools, LLC, (1999)" splits the plane of the
% triangle into region 0 to 6. The regions here are not numbered as in the
% original paper of D. Eberly but as in distancePointTrimesh_vectorized.
%
%        /\ t
%        |
%   \ R5 |
%    \   |
%     \  |
%      \ |
%       \| P3
%        *
%        |\
%        | \
%   R1   |  \   R4
%        |   \
%        | R0 \
%        |     \
%        | P1   \ P2
%  ------*-------*------> s
%        |        \
%   R3   |   R2    \   R6
%
% In the code the regions split into subregions. The regions over the
% vertices into 5, some of which only occur if the vertex has an abuse
% angle. The regions over edges split into 3 subregions, some of which
% only occur if the neighbouring vertices have acute angles.
% The following code uses triangle and one set of test points and
% switches the vertex numbers, so that every subcase is tested.

v = [36 20 10; 40 20 10; 30 30 10];

% The regions for the testPoints in the comment apply for faces = [1 2 3].
% For faces = [2 3 1] R3 becomes R5 and R4 becomes R2.
% For faces = [3 1 2] R3 becomes R6 and R4 becomes R1.
% Also the terms for the subcases change, but still all subcases are
% tested.
testPoints = [36 22 10; %R0
    42 5 10; %R3 (d<0 & a<=d)
    38 5 10; %R3 (d<0 & a>d)
    30 5 10; %R3 (d>=0 & e>=0)
    5 18 10; %R3 (d>=0 & c<=-e)
    13 13 10; %R3 (c>-e & e<0)
    30 40 10; %R4 ((c+e)-(b+d)<=0)
    50 25 10; %R4 ((c+e)-(b+d)>=a-2*b+c)
    40 30 10]; %R4 ((c+e)-(b+d)>0 & (c+e)-(b+d)<a-2*b+c)

projResults = [36 22 10;
    40 20 10;
    38 20 10;
    36 20 10;
    30 30 10;
    33 25 10;
    30 30 10;
    40 20 10;
    35 25 10];

f = [1 2 3];

[dist_s, proj_s] = distancePointMesh(testPoints, v, f, 'algorithm', 'sequential');
testCase.assertEqual(proj_s, projResults, 'AbsTol', 1e-6)
[dist_v, proj_v] = distancePointMesh(testPoints, v, f, 'algorithm', 'vectorized');
testCase.assertEqual(proj_v, projResults, 'AbsTol', 1e-6)

f = [2 3 1];

[dist_s, proj_s] = distancePointMesh(testPoints, v, f, 'algorithm', 'sequential');
testCase.assertEqual(proj_s, projResults, 'AbsTol', 1e-6)
[dist_v, proj_v] = distancePointMesh(testPoints, v, f, 'algorithm', 'vectorized');
testCase.assertEqual(proj_v, projResults, 'AbsTol', 1e-6)

f = [3 1 2];

[dist_s, proj_s] = distancePointMesh(testPoints, v, f, 'algorithm', 'sequential');
testCase.assertEqual(proj_s, projResults, 'AbsTol', 1e-6)
[dist_v, proj_v] = distancePointMesh(testPoints, v, f, 'algorithm', 'vectorized');
testCase.assertEqual(proj_v, projResults, 'AbsTol', 1e-6)


lw=2;
fz=20;

data_fb_real =load('longer_fb_real.log');
data_fac_real=load('longer_fac_real.log');
data_ola_real=load('longer_ola_real.log');

% Columns in data, fb : a M L W gl time
% Columns in data, fac: a M L W time
Ls=data_fac_real(:,3);
t_fb_real =data_fb_real(:,6);
t_fac_real=data_fac_real(:,5);
t_ola_real=data_ola_real(:,7);

if 0
  % Color legend
  l1='b';
  l2='b--';
  l3='r';
  l4='r--';
else
  % bw legend
  l1='b';
  l2='b--';
  l3='b-.';
  l4='b:';
end;

figure(1);

a=data_fac_real(1,1);
M=data_fac_real(1,2);
L=data_fac_real(:,3);

plot(Ls,t_fb_real,l1,...
     Ls,t_fac_real,l2,...
     Ls,t_ola_real,l3,'LineWidth',lw);
set(gca,'Fontsize',fz);

h=legend('Portnoff, real','Fac, real','Fac-OLA, real',...
       'Location','NorthWest');
% Grow the box a little, otherwise the export to .eps is messed up.
q=get(h,'Position');
set(h,'Position',[q(1)*0.90 q(2)*.95 q(3)*1.8 q(4)]);

xlabel('Signal length / samples','Fontsize',fz);
ylabel('Running time / seconds','Fontsize',fz);

print -deps plot_longer_1.eps


function newTree = expandTree(tree, maxOrder)
%EXPANDTREE   Convert expressions like 5*(diff(u) + u) to 5*diff(u) + 5*u.
%   The role of the EXPANDTREE method is to split up syntax trees, so that
%   expressions involving the highest derivative appearing in the equation stand
%   alone, that is, not inside parenthesis. For example, EXPANDTREE will convert
%   expressions like 5*(diff(u) + u) to 5*diff(u) + 5*u. This is necessary in
%   order to be able to put the correct expression on the right-hand side when
%   calling MATLAB's built-in solvers.
%
%   Calling sequence:
%      NEWTREE = EXPANDTREE(TREE, MAXORDER)
%   where the inputs are:
%      TREE:       The syntax tree we want to split.
%      MAXORDER:   A vector containing the maximum differential order of each
%                  variable that appear in the problem under consideration.
%   and the output is:
%      NEWTREE:    A syntax tree where the highest order deriative has been
%                  taken out of any parenthesis where other variables with lower
%                  differential order appear.

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

if ( ~isstruct(tree) || tree.height <= 1 || all(tree.diffOrder < maxOrder) ||...
    ( ~tree.hasTerms && sum(tree.ID) <= 1) )
    % We don't need to worry about expanding the tree any of the following
    % conditions apply:
    %   * The input is not a tree
    %   * It is a very short tree
    %   * Its diffOrder is less than the maxOrder we consider
    %   * It doesn't any operators that split it up in terms (that is, + or -),
    %     and it doesn't include more than one variable (which would imply
    %     nonlinearity, such as u.*w).
    newTree = tree;

elseif ( tree.numArgs == 1 )
    % If we have a unary operator, we expand the center node recursively.
    newTree = expandTree(tree.center, maxOrder);

elseif ( any(strcmp(tree.method, {'plus', 'minus'})) )
    % We're at a + or a -, so expand the syntax tree recursively:
    tree.left = treeVar.expandTree(tree.left, maxOrder);
    tree.right = treeVar.expandTree(tree.right, maxOrder);
    newTree = tree;

else
    % Must be at .*, ./ or .^.

    % If both left and right arguments to the operator are syntax trees, and the
    % highest order derivative appear in any, we know that we must have
    % nonlinearities in the highest order derivative, e.g. in the case of a
    % first order IVP, u.*diff(u). This is not supported, so throw an error:
    if ( isstruct(tree.left) && isstruct(tree.right) && ...
            ( any(tree.diffOrder == maxOrder) ) )
        error('CHEBFUN:TREEVAR:expandTree:nonlinearity', ...
            ['Nonlinearity in highest order derivative detected.\n' ...
            'Unable to convert to first order format.']);
    end

    % Find out what kind of argument we're dealing with for the left argument
    % of the operator
    if ( ~isstruct(tree.left) )
        % Left argument is not a syntax tree, must be either a CHEBFUN or a
        % scalar. In either case, the left tree has zero children.
        leftNumArgs = 0;
    else
        % Left tree is indeed a syntax tree, store its number of children.
        leftNumArgs = tree.left.numArgs;
    end

    % Find out what kind of argument we're dealing with for the right argument
    % of the operator:
    if ( ~isstruct(tree.right) )
        % Right argument is not a syntax tree, must be either a CHEBFUN or a
        % scalar. In either case, the right tree has zero children.
        rightDiffOrder = 0;
        rightNumArgs = 0;
    else
        % Left tree is indeed a syntax tree, store its number of children.
        rightNumArgs = tree.right.numArgs;
    end

    % Split up the left tree depending on how many children it has. In case we
    % don't need to split at the current level, we store the differential
    % order and the height of the left tree in the variables LEFTDIFFORDER
    % and LEFTHEIGHT. Finally, we introduce the Boolean variables SPLITLEFT
    % which indicates whether the left tree had to be split:
    if ( leftNumArgs == 0 || ...
            (strcmp(tree.left.method,'diff') && tree.left.height <= 1 )  )
        % We're either dealing with a CHEBFUN/scalar left tree, or it's
        % differentiating one of the basis variables directly (as that's the
        % only case that tree.left.height <= 1). In this case, no splitting is
        % needed.
        leftTree = tree.left;
        leftDiffOrder = 0*tree.diffOrder;
        leftHeight = 0;
        splitLeft = false;
    elseif ( leftNumArgs == 1 )
        % Here we're dealing with the unary operator case. In this case, we
        % don't need to split at the current level, however, we recursively
        % split up the child tree.
        leftTree = treeVar.expandTree(tree.left, maxOrder);
        leftDiffOrder = leftTree.diffOrder;
        leftHeight = leftTree.height;
        splitLeft = false;
    else
        % Here we're dealing with the binary operator case. In this case, we do
        % need to split at the current level, as well as recursively splitting
        % up both the child trees. LEFTLEFT and LEFTRIGHT will be the syntax
        % trees stored in the left child of the current level, once we've split
        % up the child trees of the current level.
        leftLeft = treeVar.expandTree(tree.left.left, maxOrder);
        leftRight = treeVar.expandTree(tree.left.right, maxOrder);
        splitLeft = true;
    end

    % Split up the right tree depending on how many children it has. In case we
    % don't need to split at the current level, we store the differential order
    % and the height of the right tree in the variables RIGHTDIFFORDER and
    % RIGHTHEIGHT. Finally, we introduce the Boolean variables SPLITRIGHT which
    % indicates whether the right tree had to be split:
    if ( rightNumArgs == 0 || ...
            (strcmp(tree.right.method,'diff') && tree.right.height <= 1 )  )
        % We're either dealing with a CHEBFUN/scalar right tree, or it's
        % differentiating one of the basis variables directly (as that's the
        % only case that tree.right.height <= 1). In this case, no splitting is
        % needed.
        rightTree = tree.right;
        rightDiffOrder = 0*tree.diffOrder;
        rightHeight = 0;
        splitRight = false;
    elseif ( rightNumArgs == 1 )
        % He're we're dealing with the unary operator case. In this case, we
        % don't need to split at the current level, however, we recursively
        % split up the child tree.
        rightTree = treeVar.expandTree(tree.right, maxOrder);
        rightDiffOrder = rightTree.diffOrder;
        rightHeight = 0;
        splitRight = false;
    else
        % He're we're dealing with the binary operator case. In this case, we do
        % need to split at the current level, as well as recursively splitting
        % up both the child trees. RIGHTLEFT and RIGHTRIGHT will be the syntax
        % trees stored in the right child of the current level, once we've split
        % up the child trees of the current level.
        rightLeft  = treeVar.expandTree(tree.right.left, maxOrder);
        rightRight = treeVar.expandTree(tree.right.right, maxOrder);
        % Only need to worry about splitting if both left and right trees are
        % syntax trees, not if we have CHEBFUN/scalars
        splitRight = true;
    end

    % If we had to split either the left tree or the right tree, construct new
    % syntax trees which we'll then glue together below. Note that we should
    % never expect to split both the left and right trees, as that indicates
    % nonlinearities in the highest order derivative.
    if ( ~splitLeft && ~splitRight )
        % The simple case, no splitting required, so the new left and right
        % syntax trees will be the current ones:
        newLeft = leftTree;
        newRight = rightTree;

    elseif ( splitLeft && ~splitRight )
        % Had to split on the left, not the right.

        % Multiply together the new left factor of the left tree, and the
        % current right tree:
        newLeft = struct('method','times', 'numArgs', 2, ...
            'left', leftLeft, ...
            'right', rightTree,...
            'diffOrder', max(getDifforder(leftLeft), rightDiffOrder), ...
            'height', max(getHeight(leftLeft), rightHeight) + 1, ...
            'hasTerms', getHasTerms(leftLeft) || getHasTerms(rightTree) );

        % Multiply together the new right factor of the left tree, and the
        % current right tree:
        newRight = struct('method','times', 'numArgs', 2, ...
            'left', leftRight, ...
            'right', rightTree, ...
            'diffOrder', max(getDifforder(leftRight), rightDiffOrder) + 1, ...
            'height', max(getHeight(leftRight), rightHeight) + 1, ...
            'hasTerms', getHasTerms(leftRight) || getHasTerms(rightTree) );

    elseif ( ~splitLeft && splitRight )
        % Had to split on the right, not the left.

        % Multiply together the current left tree, and the new left factor of
        % the right tree:
        newLeft = struct('method','times', 'numArgs', 2, ...
            'left', leftTree, ...
            'right', rightLeft,...
            'diffOrder', max(leftDiffOrder, getDifforder(rightLeft)), ...
            'height', max(leftHeight, getHeight(rightLeft)) + 1, ...
            'hasTerms', getHasTerms(leftTree) || getHasTerms(rightLeft) );

        % Multiply together the current left tree, and the new right factor of
        % the right tree:
        newRight = struct('method','times', 'numArgs', 2, ...
            'left', leftTree, ...
            'right', rightRight,...
            'diffOrder', max(leftDiffOrder, getDifforder(rightRight)), ...
            'height', max(leftHeight, getHeight(rightRight) + 1), ...
            'hasTerms', getHasTerms(leftTree) || getHasTerms(rightRight) );

    end

    % If the left or right trees still have multiple terms left in them, we need
    % to split them up recursively:
    if ( newLeft.hasTerms )
        newLeft = treeVar.expandTree(newLeft, maxOrder);
    end
    if ( newRight.hasTerms )
        newRight = treeVar.expandTree(newRight, maxOrder);
    end

    % Add together the new left and right trees, splitting complete!
    newTree = struct('method', 'plus', 'numArgs', 2, ...
        'left', newLeft, 'right', newRight, ...
        'diffOrder', max(newLeft.diffOrder, newRight.diffOrder), ...
        'height',max(newLeft.height, newRight.height) + 1, ...
        'hasTerms', newLeft.hasTerms || newRight.hasTerms);
end
end

function out = getDifforder(treeIn)
%GETDIFFORDER   The diffOrder of a TREEVAR.
%   We often encounter child nodes that may or may not be a syntax tree, as
%   opposed to chebfuns or scalars. We are usually interested in the heights
%   and diffOrders of the syntax trees, however, if the tree is actually a
%   CHEBFUN/scalar, they won't have the necessary fields. This method takes
%   care of checking the class of the argument, and return the correct
%   information.
if ( isstruct(treeIn) )
    out = treeIn.diffOrder;
else
    out = 0;
end

end

function out = getHeight(treeIn)
%GETHEIGHT   The height of a TREEVAR.
%   Same as GETDIFFORDER() method but for the height of a syntax tree.
if ( isstruct(treeIn) )
    out = treeIn.height;
else
    out = 0;
end

end

function out = getHasTerms(treeIn)
%GETHASTERMS   Test if a TREEVAR contains a 'plus' or 'minus' node.
%   Same as GETDIFFORDER() method but for whether the syntax tree consists of
%   multiple terms.
if ( isstruct(treeIn) )
    out = treeIn.hasTerms;
else
    out = 0;
end

end


%% Import data from spreadsheet
% Script for importing data from the following spreadsheet:
%
%    Workbook: /Users/gt/Dropbox/KSC_rocket_launches_2016_onwards_v3.xlsx
%    Worksheet: Sheet1
%
% To extend the code for use with different selected data or a different
% spreadsheet, generate a function instead of a script.

% Auto-generated by MATLAB on 2017/11/27 16:46:08

%% Import the data
[~, ~, raw] = xlsread('/Users/gt/Dropbox/KSC_rocket_launches_2016_onwards_v3.xlsx','Sheet1');
raw = raw(2:end,:);
raw(cellfun(@(x) ~isempty(x) && isnumeric(x) && isnan(x),raw)) = {''};
stringVectors = string(raw(:,[3,4,5,8,13]));
stringVectors(ismissing(stringVectors)) = '';
raw = raw(:,[1,2,6,7,10,11,12,13]);

%% Replace non-numeric cells with NaN
R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),raw); % Find non-numeric cells
raw(R) = {NaN}; % Replace non-numeric cells

%% Create output variable
data = reshape([raw{:}],size(raw));

%% Create table
cols = table;

%% Allocate imported array to column variable names
cols.DATE = data(:,1);
cols.TIME = data(:,2);
cols.COMPANY = categorical(stringVectors(:,1));
cols.ROCKETTYPE = categorical(stringVectors(:,2));
cols.PAYLOAD = stringVectors(:,3);
cols.MASSt = data(:,3);
cols.SLC = data(:,4);
cols.ORBIT = categorical(stringVectors(:,4));
cols.RECORDED = data(:,5);
cols.SPACEX = data(:,6);
cols.ALL = data(:,7);
cols.OTHER = data(:,8);

%% Clear temporary variables
clearvars data raw stringVectors R;

%% plot
dnum=cols.DATE-1 + datenum(1899,12,31) + cols.TIME;
figure
plot(dnum,cols.ALL,'b^-',dnum,cols.SPACEX,'g^-',dnum,cols.RECORDED,'r^-',dnum,cols.OTHER,'r*-');
datetick('x','keeplimits')
ylabel('Cumulative number')
xlabel('Date')
legend('Launches - any', 'Launches - SpaceX', 'Launches recorded', 'Other events recorded')


function prediction = predict(model,Xt,n, simfct, args)
% Iterative prediction of a trained LS-SVM NARX model (in recurrent mode)
%
% >> Yp = predict({Xw,Yw,type,gam,sig2}, Xt, nb)
% >> Yp = predict(model,                 Xt, nb)
%
% The model needs to be trained using Xw, Yw which is the result of
% windowize or windowizeNARX. The number of time lags for the model
% is determined by the dimension of the input, or if not
% appropriate, by the number of given starting values.
%
% By default, the model is evaluated on the past points using
% simlssvm. However, if one wants to use this procedure for other
% models, this default can be overwritten by your favorite training
% function. This function (denoted by simfct) has to follow the following syntax:
%
% >> simfct(model,inputs,arguments)
%
% thus:
%
% >> Yp = predict(model, Xt, nb, simfct)
% >> Yp = predict(model, Xt, nb, simfct, arguments)
%
%
% Full syntax
%
%     1. Using the functional interface for the LS-SVMs:
%
% >> Yp = predict({Xw,Yw,type,gam,sig2,kernel,preprocess}, Xt, nb)
%
%       Outputs
%         Yp            : nb x m matrix with the predictions
%       Inputs
%         Xw            : N x d matrix with the inputs of the training data
%         Yw            : N x w matrix with the outputs of the training data
%         type          : 'function estimation' ('f') or 'classifier' ('c')
%         gam           : Regularization parameter
%         sig2          : Kernel parameter (bandwidth in the case of the 'RBF_kernel')
%         kernel(*)     : Kernel type (by default 'RBF_kernel')
%         preprocess(*) : 'preprocess' or 'original' (by default)
%         Xt            : nb*d matrix of the starting points for the prediction
%         nb(*)         : Number of outputs to predict
%
%
%     2. Using the object oriented interface with LS-SVMs:
%
% >> Yp = predict(model, Xt, nb)
%
%       Outputs
%         Yp    : nb x m matrix with the predictions
%       Inputs
%         Xt    : nb x d matrix of the starting points for the prediction
%         nb(*) : Number of outputs to predict
%
%
%     3. Using another model:
%
% >> Yp = predict(model, Xt, nb, simfct, arguments)
%
%       Outputs
%         Yp           : nb x m matrix with the predictions
%       Inputs
%         Xt           : nb x d matrix of the starting points for the prediction
%         nb           : Number of outputs to predict
%         simfct       : Function used to evaluate a test point
%         arguments(*) : Cell with the extra arguments passed to simfct
%
% See also:
%   windowize, trainlssvm, simlssvm.

% Copyright (c) 2011,  KULeuven-ESAT-SCD, License & help @ http://www.esat.kuleuven.be/sista/lssvmlab

if size(Xt,2)~=1 & size(Xt,1)~=1,
  error('prediction only implemented for the one-dimensional autonomous case');
end
eval('model = initlssvm(model{:});',' ');
eval('xdim = model.x_dim;','xdim = max(size(Xt)); ');
eval('n; alle=0;','n=length(Xt)-xdim; alle=1;');
Xt = Xt(1:xdim);
Xt = reshape(Xt,length(Xt),1);
eval('simfct;','simfct=''simlssvm'';');
eval('model = trainlssvm(model);');

xdelays = length(Xt);
prediction = zeros(xdelays+n,1);
prediction(1:xdelays) = Xt;

% closed loop
eval('for i=1:n,  prediction(xdelays+i) = feval(simfct,model, prediction(i-1+(1:xdelays))'',args); end',...
     'for i=1:n,  prediction(xdelays+i) = feval(simfct,model,prediction(i-1+(1:xdelays))''); end');

if ~alle,
  prediction = prediction(xdelays+1:end);
end


scale1=[16,32,64,128,256,512,1024];
X1=cumsum(multifractal-mean(multifractal));
for ns=1:length(scale1),
    segments1(ns)=floor(length(X1)/scale1(ns));
    for v=1:segments1(ns),
        Index1=((((v-1)*scale1(ns))+1):(v*scale1(ns)));
        RMS_scale2{ns}(Index1)=RMS{ns}(v).*ones(size(Index1));
    end
end
clear X1 Index1 scale1 segments1
X1=1:length(RMS_scale2{7});
X2=1:8000;
X3=1:length(RMS_scale2{6});
X4=1:length(RMS_scale2{5});
Y1=RMS_scale2{7};
Y2=F(7).*ones(8000,1);
Y3=RMS_scale2{6};
Y4=F(6).*ones(8000,1);
Y5=RMS_scale2{5};
Y6=F(5).*ones(8000,1);
Y7=RMS_scale2{4};
Y8=F(4).*ones(8000,1);
YMatrix1=[RMS_scale2{3};F(3).*ones(1,8000)];
YMatrix2=[RMS_scale2{2};F(2).*ones(1,8000)];
YMatrix3=[RMS_scale2{1};F(1).*ones(1,8000)];
clear RMS_scale2

% Create figure
figure1 = figure('PaperSize',[20.98 29.68],'Color',[1 1 1]);

% Create axes
axes1 = axes('Parent',figure1,'YTick',[0 20],'XTick',zeros(1,0),...
    'Position',[0.09852 0.8515 0.775 0.1274],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes1,[0 45]);
hold(axes1,'all');

% Create plot
plot(X1,Y1,'Parent',axes1,'LineWidth',2,'Color',[0 0 1],...
    'DisplayName','Local fluctuation: RMS in Matlab code 5');

% Create plot
plot(X2,Y2,'Parent',axes1,'LineWidth',2,'Color',[1 0 0],...
    'DisplayName','RMS of local fluctuation: F in Matlab code 5');

% Create axes
axes2 = axes('Parent',figure1,'YTick',[0 20],'XTick',zeros(1,0),...
    'Position',[0.09852 0.7242 0.775 0.1272],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes2,[0 45]);
hold(axes2,'all');

% Create plot
plot(X3,Y3,'Parent',axes2,'LineWidth',2,'Color',[0 0 1]);

% Create plot
plot(X2,Y4,'Parent',axes2,'LineWidth',2,'Color',[1 0 0]);

% Create axes
axes3 = axes('Parent',figure1,'YTick',[0 20],'XTick',zeros(1,0),...
    'Position',[0.09852 0.5968 0.775 0.1271],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes3,[0 44]);
hold(axes3,'all');

% Create plot
plot(X4,Y5,'Parent',axes3,'LineWidth',2,'Color',[0 0 1]);

% Create plot
plot(X2,Y6,'Parent',axes3,'LineWidth',2,'Color',[1 0 0]);

% Create axes
axes4 = axes('Parent',figure1,'YTick',[0 20],'XTick',zeros(1,0),...
    'Position',[0.09852 0.4694 0.775 0.127],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes4,[0 40]);
hold(axes4,'all');

% Create plot
plot(X4,Y7,'Parent',axes4,'LineWidth',2,'Color',[0 0 1]);

% Create plot
plot(X2,Y8,'Parent',axes4,'LineWidth',2,'Color',[1 0 0]);

% Create ylabel
ylabel('RMS in Matlab code 5 (measurement units)','FontSize',14);

% Create axes
axes5 = axes('Parent',figure1,'YTick',[0 10],'XTick',zeros(1,0),...
    'Position',[0.09852 0.3435 0.775 0.1269],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes5,[-0.5 30]);
hold(axes5,'all');

% Create multiple lines using matrix input to plot
pplot1 = plot(X2,YMatrix1,'Parent',axes5,'LineWidth',2);
set(pplot1(1),'Color',[0 0 1]);
set(pplot1(2),'Color',[1 0 0]);

% Create axes
axes6 = axes('Parent',figure1,'YTick',[0 10],'XTick',zeros(1,0),...
    'Position',[0.09852 0.2162 0.775 0.1267],...
    'LineWidth',2,...
    'FontSize',14);
xlim(axes6,[0 8000]);
ylim(axes6,[-0.5 20]);
hold(axes6,'all');

% Create multiple lines using matrix input to plot
pplot2 = plot(X2,YMatrix2,'Parent',axes6,'LineWidth',2);
set(pplot2(1),'Color',[0 0 1]);
set(pplot2(2),'Color',[1 0 0]);

% Create axes
axes7 = axes('Parent',figure1,'YTick',[0 5],...
    'Position',[0.09852 0.09048 0.775 0.1266],...
    'LineWidth',2,...
    'FontSize',14);
ylim(axes7,[0 15]);
hold(axes7,'all');

% Create multiple lines using matrix input to plot
pplot3 = plot(X2,YMatrix3,'Parent',axes7,'LineWidth',2);
set(pplot3(1),'Color',[0 0 1]);
set(pplot3(2),'Color',[1 0 0]);

% Create xlabel
xlabel('time (sample number)','FontSize',14);

% Create legend
legend1 = legend(axes1,'show');
set(legend1,'Position',[0.5252 0.8089 0.3681 0.07268],'LineWidth',2);

% Create textbox
annotation(figure1,'textbox',[0.8714 0.3324 0.0981 0.05573],...
    'String',{'Scale = 64'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8711 0.08541 0.0981 0.05573],...
    'String',{'Scale = 16'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8716 0.2025 0.0981 0.05573],...
    'String',{'Scale = 32'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8711 0.4607 0.102 0.05573],...
    'String',{'Scale = 128'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8716 0.6065 0.1049 0.05573],...
    'String',{'Scale = 256'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8721 0.7507 0.1036 0.05573],...
    'String',{'Scale = 512'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');

% Create textbox
annotation(figure1,'textbox',[0.8719 0.8997 0.1125 0.05573],...
    'String',{'Scale = 1024'},...
    'FontSize',14,...
    'FitBoxToText','off',...
    'LineStyle','none');
clear ans pplot1 pplot2 pplot3 axes1 axes2 axes3 axes4 axes5 axes6 axes7 legend1 figure1 X1 X2 X3 X4 Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 YMatrix1 YMatrix2 YMatrix3
v=1;ns=1;


function grid = reshapeGrid(~, grid)
%RESHAPEGRID   Add the repeated endpoints to a 2D periodic grid.

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

% Note: We use periodic discretizations in 1D/2D/3D. These discretizatioins
% do not include the repeated endpoints. Before plotting data with
% SPINOPERATOR/INITIALIZEMOVIE, we add these repeated endpoints to the grid.

% Get the points:
xx = grid{1};
yy = grid{2};

% Add the endpoints:
xx = [xx, 2*xx(:,end) - xx(:,end-1)];
xx = [xx; xx(1,:)];
yy = [yy; 2*yy(end,:) - yy(end-1,:)];
yy = [yy, yy(:,1)];

% Output the new grid:
grid{1} = xx;
grid{2} = yy;

end


function h = min(f, g, dim)
%MIN   Minimum value of a CHEBFUN3 in one direction.
%   MIN(F) returns a CHEBFUN2 representing the minimum of the CHEBFUN3
%   object F along the x direction, i.e, MIN(F) = @(y,z) min(F(:, y, z)).
%
%   MIN(F, [], DIM) returns a CHEBFUN2 representing the minimum of F along
%   the dimension DIM. DIM should be 1, 2 or 3 to minimize over X, Y or Z,
%   respectively.
%
%   WARNING: This function is not always accurate to the expected precision.
%
% See also CHEBFUN3/MIN2 and CHEBFUN3/MIN3.

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

% Empty check:
if ( isempty(f) )
    error('CHEBFUN:CHEBFUN3:min:input', 'CHEBFUN3 is empty');
end

% Default to min of one chebfun3:
if ( nargin < 2 )
    g = [];
end

% Default to minimum along the x direction:
if ( nargin < 3 )
    dim = 1;
end

% Do not allow min(F, G):
if ( nargin > 1 && ~isempty(g) )
    error('CHEBFUN:CHEBFUN3:min:twoCHEBFUN3Inputs', ...
        'Unable to minimize two CHEBFUN3 objects.');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% We have no idea how to achieve this in an efficient way. This
% is an attempt to return a result, but typically it won't be accurate to
% more than 4-5 digits.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

dom = f.domain;
n = 129;
if ( dim == 1 )
    vals = sample(f, n, n, n);
    h = chebfun2(squeeze(min(vals, [], 1)), dom(3:6));
    h = simplify(h);

elseif ( dim == 2 )
    vals = sample(f, n, n, n);
    h = chebfun2(squeeze(min(vals, [], 2)), [dom(1:2), dom(5:6)]);
    h = simplify(h);

elseif ( dim == 3 )
    vals = sample(f, n, n, n);
    h = chebfun2(min(vals, [], 3), dom(1:4));
    h = simplify(h);

elseif ( dim == 0 )
    error('CHEBFUN:CHEBFUN3:min:dim', 'dim must be 1, 2, or 3.')
else
   % Return the CHEBFUN3 object. This is analogous to that MIN() command in
   % MATLAB.
   h = f;
end

end