function computeAllPrediction_LGG(pathModels,pathResults,training,param,maxOrder,nBoot,imbalance,seed)
% -------------------------------------------------------------------------
% function computeAllPrediction_LGG(pathModels,pathResults,training,param,maxOrder,nBoot,imbalance,seed)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function computes prediction performance estimation for a given
% feature set type, and for all model orders of all experiments with
% different degrees of freedom. See ref. [1] for more details.
% -------------------------------------------------------------------------
% REFERENCE:
% [1] Vallieres, M. et al. (2015). A radiomics model from joint FDG-PET and
%     MRI texture features for the prediction of lung metastases in soft-tissue
%     sarcomas of the extremities. Physics in Medicine and Biology, 60(14),
%     5471-5496. doi:10.1088/0031-9155/60/14/5471
% -------------------------------------------------------------------------
% INPUTS:
% 1. pathModels: Full path to the Models folder of the corresponding experiment.
%                --> Ex: '/myProject/WORKSPACE/LOGISTIC_REGRESSION/MODELS'
% 2. pathResults: Full path to the Results folder of the corresponding experiment.
%                --> Ex: '/myProject/WORKSPACE/LOGISTIC_REGRESSION/RESULTS'
% 3. training: Structure defining all parameters for the given experiment
%              to perform. See organizeRadiomicsExp_LGG.m for more details.
%              --> IMPORTANT VARIABLE DEFINING ALL PARAMETERS IN TRAINING
% 4. param: Cell of two strings, defining 1) The feature set type/name; and
%           2) the outcome to model in the 'training' structure.
% 5. maxOrder: Integer specifying the maximal model order to construct.
%              --> Ex: 10
% 6. nBoot: Number of bootstrap samples to use.
%           --> Ex: 100
% 7. imbalance: String specifying the type of imbalance-adjustement strategy
%               employed. Either 'IABR' for imbalance-adjusted bootstrap
%               resampling (see ref.[1]), or 'IALR' for imbalance-adjusted
%               logistic regression (formal reference to come).
%               --> Ex: 'IALR'
% 7. seed: Random generator seed for reproducibility of experiments.
% -------------------------------------------------------------------------
% OUTPUTS: Prediction performance results are saved in a folder named 'RESULTS' in the
% corresponding folder of each experiment (e.g. 'Experiment1', 'Experiment2', etc.)
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: January 2017
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015-2017  Martin Vallieres
%
%    This package is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This package is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

startpath = pwd;
warning off

cd(pathModels)
fSetName = param{1};
outcomeName = param{2};
outcome = training.(outcomeName).outcome;
models = load(['MODELS_',fSetName,'_',outcomeName]); models = struct2cell(models); models = models{1};

tic
fprintf(['\n --> COMPUTING PREDICTION PERFORMANCE (MODEL ORDERS OF 1 to % u) FOR  "',fSetName,'" FEATURE SET AND "',outcomeName,'" OUTCOME ... '],maxOrder)
for j = 1:maxOrder
    orderName = ['Order',num2str(j)];
    data = models.(orderName).Data;
    [orderResults] = predictionPerformanceEstimation(data,outcome,nBoot,imbalance,seed);
    results.(orderName) = orderResults;
    results.(orderName).Data = models.(orderName).Data;
    results.(orderName).Name = models.(orderName).Name;
end
cd(pathResults), save(['RESULTS_',fSetName,'_',outcomeName],'results')
fprintf('DONE!\n'), toc

cd(startpath)
end


function value = function_2d_name ( ifunc )

%*****************************************************************************80
%
%% FUNCTION_2D_NAME returns the name of the current 2D function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 April 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer IFUNC, the index of the function.
%
%    Output, character FUNCTION_2D_NAME(7), the name of the function.
%
  if ( ifunc == 1 )
    value = '      1';
  elseif ( ifunc == 2 )
    value = '      X';
  elseif ( ifunc == 3 )
    value = '    X^2';
  elseif ( ifunc == 4 )
    value = '    X^3';
  elseif ( ifunc == 5 )
    value = '    X^4';
  elseif ( ifunc == 6 )
    value = '    X^5';
  elseif ( ifunc == 7 )
    value = '    X^6';
  elseif ( ifunc == 8 )
    value = '      R';
  elseif ( ifunc == 9 )
    value = ' SIN(X)';
  elseif ( ifunc == 10 )
    value = ' EXP(X)';
  elseif ( ifunc == 11 )
    value = '1/(1+R)';
  elseif ( ifunc == 12 )
    value = 'SQRT(R)';
  else
    value = '???????';
  end

  return
end


function [Intensity T1vector IntensityBeforeComb]=MP2RAGE_lookuptable(nimages,MPRAGE_tr,invtimesAB,flipangleABdegree,nZslices,FLASH_tr,sequence,varargin)
% first extra parameter is the inversion efficiency
% second extra parameter is the alldata
%   if ==1 all data is shown
%   if ==0 only the monotonic part is shown
alldata=0;
if nargin >=9
    if ~isempty(varargin{2})
        alldata=varargin{2};
    end
end

invtimesa=invtimesAB(1);
invtimesb=invtimesAB(2);

B1vector=1;
flipanglea=flipangleABdegree(1);
flipangleb=flipangleABdegree(2);

T1vector=0.05:0.05:5;

if length(nZslices)==2
    nZ_bef=nZslices(1);
    nZ_aft=nZslices(2);
    nZslices2=(nZslices);

    nZslices=sum(nZslices);
elseif     length(nZslices)==1
    nZ_bef=nZslices/2;
    nZ_aft=nZslices/2;
    nZslices2=(nZslices);
end;

j=0;
for T1=T1vector
    j=j+1;
    for MPRAGEtr=MPRAGE_tr
        for inversiontimesa=invtimesa
            for inversiontimesb=invtimesb
                m=0;
                for B1=B1vector
                    m=m+1;
                    %                 T1=1;%testline
                    inversiontimes2=[inversiontimesa inversiontimesb];
                    if and(and((diff(inversiontimes2))>=nZslices*FLASH_tr,inversiontimesa>=nZ_bef*FLASH_tr),inversiontimesb<=(MPRAGEtr-nZ_aft*FLASH_tr));
                        if nargin == 7
                            Signal(j,m,1:2)=1*MPRAGEfunc(nimages,MPRAGEtr,inversiontimes2,nZslices2,FLASH_tr,B1*[flipanglea flipangleb],sequence,T1);
                        else
                            if ~isempty(varargin{1})
                                Signal(j,m,1:2)=1*MPRAGEfunc(nimages,MPRAGEtr,inversiontimes2,nZslices2,FLASH_tr,B1*[flipanglea flipangleb],sequence,T1,varargin{1});
                            else
                                Signal(j,m,1:2)=1*MPRAGEfunc(nimages,MPRAGEtr,inversiontimes2,nZslices2,FLASH_tr,B1*[flipanglea flipangleb],sequence,T1);

                            end;
                        end;
                    else
                        Signal(j,m,1:2)=0;
                    end;
                end;
            end;
        end;
    end;
end;
Intensity=squeeze(real(Signal(:,:,1).*conj(Signal(:,:,2)))./(abs(Signal(:,:,1)).^2+abs(Signal(:,:,2)).^2));
T1vector=squeeze(T1vector);
if alldata==0
    [a minindex]=max(Intensity);
    [a maxindex]=min(Intensity);
    Intensity=Intensity(minindex:maxindex);
    T1vector=T1vector(minindex:maxindex);
    IntensityBeforeComb=squeeze(Signal(minindex:maxindex,1,:));
    Intensity([1 end])=[0.5 -0.5]; % pads the look up table to avoid points that fall out ot the lookuptable
else
    Intensity=squeeze(real(Signal(:,:,1).*conj(Signal(:,:,2)))./(abs(Signal(:,:,1)).^2+abs(Signal(:,:,2)).^2));
    T1vector=squeeze(T1vector);
    IntensityBeforeComb=squeeze(Signal(:,1,:));
end;


function f = constructor(f, op, varargin)
%CONSTRUCTOR   Main CHEBFUN3T constructor.
%   Classical full tensor approach for 3D functions. No low-rank technique
%   is involved here. This is experimental code, not for ordinary use.
%
% See also CHEBFUN3.

%   The 'trig' flag is NOT implemented.

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

% Parse the inputs:
[op, dom, pref, vectorize] = parseInputs(op, varargin{:});

% Set preferences:
tech        = pref.tech();
tpref       = tech.techPref;
grid = tpref.minSamples;
maxSample = 363;
% Since 363*363*363=(6916)^2, this is equivalent to working with a matrix
% of size 6916 * 6916 which needs 380MB of memory.
pseudoLevel = pref.cheb3Prefs.chebfun3eps;
prefStruct = pref.cheb2Prefs;
passSampleTest = prefStruct.sampleTest;

[xx, yy, zz] = ndgrid(dom(1:2), dom(3:4), dom(5:6));
A = op(xx, yy, zz);
if ( isscalar(A) )
    op = @(x,y,z) op(x,y,z) + 0*x + 0*y + 0*z;
end

%%
isHappy = 0;
m = grid; n = grid; p = grid;
for i=1:10
    %% Compute values at 3D chebpts
    out = tech.tensorGrid([m, n, p], dom);
    xx = out{1};
    yy = out{2};
    zz = out{3};
    F = op(xx,yy,zz);

    % Does the function blow up or evaluate to NaN?:
    vscale = max(abs(F(:)));
    if ( isinf(vscale) )
        error('CHEBFUN:CHEBFUN3T:constructor:inf', ...
            'Function returned INF when evaluated');
    elseif ( any(isnan(F(:)) ) )
        error('CHEBFUN:CHEBFUN3T:constructor:nan', ...
            'Function returned NaN when evaluated');
    end

    %% Call 3D vals2coeffs
    coeffs3D = chebfun3t.vals2coeffs(F);
    % happinessCheck
    [isHappyX, isHappyY, isHappyZ, cutoffX2, cutoffY2, cutoffZ2] = ...
        happinessCheck3D(coeffs3D, pref);
    isHappy = isHappyX & isHappyY & isHappyZ;

    %% PHASE II
    % This phase refines the grid ONLY in "unhappy" directions.
    % We don't refine here if ALL the directions are nonhappy (as mentioned
    % in the following). If, however, less than 3 directions are nonhappy,
    % we refine in those directions only.

    m2 = m; n2 = n; p2 = p;
    while (~isHappy)
        % We need to refine the grid. We refine in 2 different ways: If all
        % 3 directions are unhappy, the new grid is bigger in each
        % direction by a factor of sqrt(2). If 1 or 2 of the directions are
        % unhappy, we refine (only those unhappy directions) by a factor of
        % 2.

        if (~isHappyX && ~isHappyY && ~isHappyZ)
            % All directions are unhappy. To avoid getting an unncecessarily
            % big tensor, refine differently.
            break;
        end
        if (~isHappyX)
            m2 = gridRefinePhase2(m2, pref);
        end
        if (~isHappyY)
            n2 = gridRefinePhase2(n2, pref);
        end
        if (~isHappyZ)
            p2 = gridRefinePhase2(p2, pref);
        end
        out = tech.tensorGrid([m2, n2, p2], dom);
        xx = out{1};
        yy = out{2};
        zz = out{3};
        F = op(xx,yy,zz);
        coeffs3D = chebfun3t.vals2coeffs(F);
        [isHappyX, isHappyY, isHappyZ, cutoffX2, cutoffY2, cutoffZ2] = ...
            happinessCheck3D(coeffs3D,pref);
        isHappy = isHappyX & isHappyY & isHappyZ;
    end

     if ( isHappy )
         % Chop the tail:
         coeffs3D = coeffs3D(1:cutoffX2, 1:cutoffY2, 1:cutoffZ2);

         % Construct a CHEBFUN3T object:
         f.coeffs = coeffs3D;
         f.vscale = max(abs(F(:)));
         f.domain = dom;

         % Step 2: Apply a SAMPLETEST:
         [m2, n2, p2] = size(coeffs3D);
         if ( passSampleTest )
             tol2 = getTol3D(xx, yy, zz, F, length(xx), dom, pseudoLevel);
             pass = sampleTest(f, op, tol2, vectorize);
             if ( pass ) % :)
                 break
             end
         end
     end
    m = gridRefinePhase1(m);
    n = gridRefinePhase1(n);
    p = gridRefinePhase1(p);
end

% Reached maximum allowed tensor size and still unhappy?
if ( i == 10 && ~isHappy )
    % Throw a warning and construct from the latest unhappy approximation
    warning('CHEBFUN:CHEBFUN3T:constructor:notResolved', ...
                'Unresolved with maximum CHEBFUN3T length: %u.', maxSample);
    f.coeffs = coeffs3D;
    f.vscale = max(abs(F(:)));
    f.domain = dom;
end

end

%%
function [isHappyX, isHappyY, isHappyZ, cutoffX2, cutoffY2, cutoffZ2] = ...
    happinessCheck3D(simple_3D_coeffs, pref)
% An alternative technique: check whether all the rows, columns and tubes have been resolved.
% Somewhat similar to Chebfun2 constructor (but with all the rows, cols and tubes instead of the pivot ones)

% TODO: THIS DOES NOT PROPERLY WORK WITH TRIGs.

colChebtech = sum(chebfun3t.unfold(abs(simple_3D_coeffs), 1), 2);
fCol = chebtech2({[], colChebtech});
[isHappyX, cutoffX2] = happinessCheck(fCol, [], [], [], pref);

rowChebtech = sum(chebfun3t.unfold(abs(simple_3D_coeffs), 2), 2);
fRow = chebtech2({[], rowChebtech});
[isHappyY, cutoffY2] = happinessCheck(fRow, [], [], [], pref);

tubeChebtech = sum(chebfun3t.unfold(abs(simple_3D_coeffs), 3), 2);
fTube = chebtech2({[], tubeChebtech});
[isHappyZ, cutoffZ2] = happinessCheck(fTube, [], [], [], pref);
end
%%
function grid = gridRefinePhase1(grid)
% Grid refinement strategy in Phase 1. It does the same for all TECHS.
grid = floor(sqrt(2)^(floor(2*log2(grid)) + 1)) + 1;
end

%%
function grid = gridRefinePhase2(grid, pref)
% Grid refinement strategy for tech in Phase 2

% What tech am I based on?:
tech = pref.tech();

% What is the next grid size?
if ( isa(tech, 'chebtech2') )
    % Double sampling on tensor grid:
    grid = 2*grid-1;
elseif ( isa(tech, 'trigtech') )
    % Double sampling on tensor grid:
    grid = 2^(floor(log2(grid)+1));
elseif ( isa(tech, 'chebtech1') )
    grid = 3 * grid;
else
    error('CHEBFUN:CHEBFUN3:constructor:gridRefinePhase2:techType', ...
        'Technology is unrecognized.');
end

end
%%

function tol = getTol3D(xx, yy, zz, vals, grid, dom, pseudoLevel)
%See https://github.com/chebfun/chebfun/issues/1491
[m,n,p] = size(vals);
% Remove some edge values so that df_dx, df_dy and df_dz have the same size.
df_dx = diff(vals(:,1:n-1,1:p-1),1,1) ./ diff(xx(:,1:n-1,1:p-1),1,1); % xx changes in the first mode.
df_dy = diff(vals(1:m-1,:,1:p-1),1,2) ./ diff(yy(1:m-1,:,1:p-1),1,2); % yy changes row-wise (2nd mode).
df_dz = diff(vals(1:m-1,1:n-1,:),1,3) ./ diff(zz(1:m-1,1:n-1,:),1,3); % zz changes tube-wise (3rd mode).

J = max(max(abs(df_dx),abs(df_dy)), abs(df_dz));
Jac_norm = max(J(:)); % An approximation for the norm of the Jacobian over the whole domain.
vscale = max(abs(vals(:)));
tol = grid^(4/5) * max( abs(dom(:) ) ) * max(Jac_norm, vscale) * pseudoLevel;
end
%%
function [op, dom, pref, vectorize] = parseInputs(op, varargin)
vectorize = 0;
pref = chebfunpref();

if ( isa(op, 'char') )     % CHEBFUN3T( CHAR )
    op = str2op(op);
end

if nargin == 1
    dom = [-1 1 -1 1 -1 1];
elseif ( ( (nargin == 2) && ~any(strcmpi(varargin{1}, {'trig', 'periodic'})) ))
    % DOMAIN is specified
    dom = varargin{1};
elseif ( ( (nargin == 2) && any(strcmpi(varargin{1}, {'trig', 'periodic'})) ))
    % TECH is specified
    pref.tech = @trigtech;
    dom = [-1 1 -1 1 -1 1];
elseif ( ( (nargin == 3) && any(strcmpi(varargin{2}, {'trig', 'periodic'})) ))
    % DOMAIN and TECH are specified
    dom = varargin{1};
    pref.tech = @trigtech;
elseif ( ( (nargin == 3) && any(strcmpi(varargin{1}, {'trig', 'periodic'})) ))
    % TECH and DOMAIN are specified
    pref.tech = @trigtech;
    dom = varargin{3};
elseif ( (nargin == 3) && strcmpi(varargin{1}, 'eps') )
    % EPS is specified
    pref.chebfuneps = varargin{2};
    dom = [-1 1 -1 1 -1 1];
elseif ( (nargin == 4) && strcmpi(varargin{1}, 'eps') ...
        && any(strcmpi(varargin{3}, {'trig', 'periodic'})) )
    % EPS and TECH are specified
    pref.tech = @trigtech;
    pref.chebfuneps = varargin{3};
    dom = [-1 1 -1 1 -1 1];
elseif ( (nargin == 4) && strcmpi(varargin{2}, 'eps') && ...
        any(strcmpi(varargin{1}, {'trig', 'periodic'})) )
    % TECH and EPS are specified
    pref.tech = @trigtech;
    pref.chebfuneps = varargin{3};
    dom = [-1 1 -1 1 -1 1];
elseif ( (nargin == 4) && strcmpi(varargin{2}, 'eps') && ...
        ~any(strcmpi(varargin{1}, {'trig', 'periodic'})) )
    % DOMAIN and EPS are specified
    pref.chebfuneps = varargin{3};
    dom = varargin{1};
elseif ( (nargin == 4) && strcmpi(varargin{1}, 'eps') && ...
        ~any(strcmpi(varargin{3}, {'trig', 'periodic'})) )
    % EPS and DOMAIN are specified
    pref.chebfuneps = varargin{2};
    dom = varargin{3};
elseif ( (nargin == 5) && any(strcmpi(varargin{2}, {'trig', 'periodic'}))...
        &&  strcmpi(varargin{3}, 'eps') )
    % DOMAIN, TECH and EPS are specified
    dom = varargin{1};
    pref.tech = @trigtech;
    pref.chebfuneps = varargin{4};
elseif ( (nargin == 5) && strcmpi(varargin{2}, 'eps') ...
        && any(strcmpi(varargin{4}, {'trig', 'periodic'})) )
    % DOMAIN, EPS and TECH are specified
    dom = varargin{1};
    pref.chebfuneps = varargin{3};
    pref.tech = @trigtech;
elseif ( (nargin == 5) && any(strcmpi(varargin{1}, {'trig', 'periodic'}))...
        &&  strcmpi(varargin{2}, 'eps') )
    % TECH, EPS and DOMAIN are specified
    pref.tech = @trigtech;
    pref.chebfuneps = varargin{3};
    dom = varargin{4};
elseif ( (nargin == 5) && any(strcmpi(varargin{1}, {'trig', 'periodic'}))...
        &&  strcmpi(varargin{3}, 'eps') )
    % TECH, DOMAIN and EPS are specified
    pref.tech = @trigtech;
    dom = varargin{2};
    pref.chebfuneps = varargin{4};
elseif ( (nargin == 5) && any(strcmpi(varargin{4}, {'trig', 'periodic'}))...
        &&  strcmpi(varargin{1}, 'eps') )
    % EPS, DOMAIN and TECH are specified
    pref.chebfuneps = varargin{2};
    dom = varargin{3};
    pref.tech = @trigtech;
elseif ( (nargin == 5) && any(strcmpi(varargin{3}, {'trig', 'periodic'}))...
        &&  strcmpi(varargin{1}, 'eps') )
    % EPS, TECH and DOMAIN are specified
    pref.chebfuneps = varargin{2};
    pref.tech = @trigtech;
    dom = varargin{4};
else
    error('CHEBFUN:CHEBFUN3T:constructor', ...
                    'Domain not valid or fully determined.');
end
end
%%
function op = str2op( op )
% OP = STR2OP(OP), finds independent variables in a string and returns an op
% handle than can be evaluated.

vars = symvar(op); % Independent variables
if ( numel(vars) > 3)
    error('CHEBFUN:CHEBFUN3T:constructor:str2op:depvars', ...
        'Too many independent variables in string input.');
else
    op = eval(['@(' vars{1} ',' vars{2} ',' vars{3} ')' op]);
end

end


% Coupled nonlinear PDE's
% Buckley Leverett equation
% dependent variables: pressure and water saturation
% Prepared for educational purposes by ** AAE **
% For whatever reason, the code is very slow and does not converge
% DOES NOT WORK WELL
% Written by Ali A. Eftekhari
% Last checked: June 2021
clc; clear;
%% define the geometry
Nx = 50; % number of cells in x direction
Ny = 30; % number of cells in y direction
W = 50; % [m] length of the domain in x direction
H = 30; % [m] length of the domain in y direction
x1=linspace(0,W, Nx);
x2=x1+0.001;
x=zeros(2*Nx,1);
j=0;
for i=1:Nx
    j=j+1;
    x(j)=x1(i);
    j=j+1;
    x(j)=x2(i);
end
y1=linspace(0,H, Ny);
y2=y1+0.01;
y=zeros(2*Ny,1);
j=0;
for i=1:Ny
    j=j+1;
    y(j)=y1(i);
    j=j+1;
    y(j)=y2(i);
end
m = createMesh2D(x, y); % creates a 2D mesh
[X,Y]=ndgrid(m.cellsize.x, m.cellsize.y);
%% define the physical parametrs
p0 = 1e5; % [bar] pressure
pin = 50e5; % [bar] injection pressure at the left boundary
q_in=5e-5; % [m^3/s] water injection
sw0 = 0; % initial water saturation
swin = 1;
mu_oil = 1e-3; % [Pa.s] oil viscosity
mu_water = 1e-3; % [Pa.s] water viscosity
% reservoir
k0 = 2e-12; % [m^2] average reservoir permeability
k_frac=100e-12; % [m^2] fracture permeability
phi0 = 0.2; % average porosity
clx=0.05;
cly=0.05;
V_dp=0.1; % Dykstra-Parsons coef.
perm_val= field2d(2*Nx,2*Ny,k0,V_dp,clx,cly);
k=createCellVariable(m, k0);
for i=4:2:2*Nx
    k.value(i,3:end-2)=k_frac;
end
for j=4:2:2*Ny
    k.value(3:end-2,j)=k_frac;
end
k.value(1:2,:)=k_frac;
k.value(end-1:end,:)=k_frac;
k.value(:,1:2)=k_frac;
k.value(:,end-1:end)=k_frac;
%k.value(1:2,:)=k_frac;
phi=createCellVariable(m, phi0);
krw0 = 0.4;
kro0 = 0.8;
nw = 1;
no = 1;
krw = @(sw)(krw0*sw.^nw);
dkrwdsw = @(sw)(krw0*nw*sw.^(nw-1));
kro = @(sw)(kro0*(1-sw).^no);
dkrodsw = @(sw)(-kro0*no*(1-sw).^(no-1));
lw = geometricMean(k)/mu_water;
lo = geometricMean(k)/mu_oil;
Lw = @(sw)(krw(sw));
Lo = @(sw)(k/mu_oil*kro(sw));
dLwdsw = @(sw)(k/mu_water*dkrwdsw(sw));
dLodsw = @(sw)(k/mu_oil*dkrodsw(sw));
%% Define the boundaries
BCp = createBC(m); % Neumann BC for pressure
BCs = createBC(m); % Neumann BC for saturation
% change the right boandary to constant pressure (Dirichlet)
BCp.right.a(end-5:end)=0; BCp.right.b(end-5:end)=1; BCp.right.c(end-5:end)=p0;
% change the left boundary to constant flow
BCp.left.a(1:5)=-k_frac/mu_water; BCp.left.b(1:5)=0; BCp.left.c(1:5)=q_in;
% change the left boundary to constant saturation (Dirichlet)
BCs.left.a(1:5)=0; BCs.left.b(1:5)=1; BCs.left.c(1:5)=1;
%% define the time step and solver properties
dt = 10; % [s] time step
t_end = 1000*dt; % [s] final time
eps_p = 1e-5; % pressure accuracy
eps_sw = 1e-5; % saturation accuracy
%% define the variables
sw_old = createCellVariable(m, sw0, BCs);
p_old = createCellVariable(m, p0, BCp);
sw = sw_old;
p = p_old;
uw = -gradientTerm(p_old); % an estimation of the water velocity
%% start the main loop
% generate intial pressure profile (necessary to initialize the fully
% implicit solver)

t = 0;
while (t<t_end)
    error_p = 1e5;
    error_sw = 1e5;
    % estimation loop: sequential
%     for i = 1:2
%         pgrad = gradientTerm(m, p.value);
%         sw_face = upwindMean(m, -pgrad, sw.value); % average value of water saturation
%         labdao = lo.*funceval(kro, sw_face);
%         labdaw = lw.*funceval(krw, sw_face);
%         labda = labdao+labdaw;
%         Mdiffp1 = diffusionTerm(m, -labda);
%         [Mbcp, RHSbcp] = boundaryCondition(m, BCp);
%         p.value = reshapeCell(m, full((Mdiffp1+Mbcp)\RHSbcp));
%         for j = 1:2
%             pgrad = gradientTerm(m, p.value);
%             sw_face = upwindMean(m, -pgrad, sw.value);
%             labdaw = lw.*funceval(krw, sw_face);
%             dlabdawdsw = lw.*funceval(dkrwdsw, sw_face);
%             [Mbcsw, RHSbcsw] = boundaryCondition(m, BCs);
%             [Mtranssw2, RHStrans2] = transientTerm(m, phi, dt, sw);
%             Mconvsw2 = convectionUpwindTerm(m, -dlabdawdsw.*pgrad);
%             RHSs = RHSbcsw+RHStrans2+divergenceTerm(m, (labdaw-dlabdawdsw.*sw_face).*pgrad);
%             Ms = Mbcsw+Mconvsw2+Mtranssw2;
%             sw.value = reshapeCell(m, full(Ms\RHSs));
%         end
%     end
    % Implicit loop
    hold all
    while ((error_p>eps_p) || (error_sw>eps_sw))
        % calculate parameters
        pgrad = gradientTerm(p);
        sw_face = upwindMean(sw, -pgrad); % average value of water saturation
        labdao = lo.*funceval(kro, sw_face);
        labdaw = lw.*funceval(krw, sw_face);
        dlabdaodsw = lo.*funceval(dkrodsw, sw_face);
        dlabdawdsw = lw.*funceval(dkrwdsw, sw_face);
        labda = labdao+labdaw;
        dlabdadsw = dlabdaodsw+dlabdawdsw;
        % compute [Jacobian] matrices
        Mdiffp1 = diffusionTerm(-labda);
        Mdiffp2 = diffusionTerm(-labdaw);
        Mconvsw1 = convectionUpwindTerm(-dlabdadsw.*pgrad);
        Mconvsw2 = convectionUpwindTerm(-dlabdawdsw.*pgrad);
        [Mtranssw2, RHStrans2] = transientTerm(sw_old, dt, phi);
        % Compute RHS values
        RHS1 = divergenceTerm(-dlabdadsw.*sw_face.*pgrad);
        RHS2 = divergenceTerm(-dlabdawdsw.*sw_face.*pgrad);
        % include boundary conditions
        [Mbcp, RHSbcp] = boundaryCondition(BCp);
        [Mbcsw, RHSbcsw] = boundaryCondition(BCs);
        % Couple the equations; BC goes into the block on the main diagonal
        M = [Mdiffp1+Mbcp Mconvsw1; Mdiffp2 Mconvsw2+Mtranssw2+Mbcsw];
        RHS = [RHS1+RHSbcp; RHS2+RHStrans2+RHSbcsw];
        % solve the linear system of equations
        x = M\RHS;
        % x = agmg(M, RHS, [], 1e-10, 500, [], [p.value(:); sw.value(:)]);
        % separate the variables from the solution
        p_new = reshapeCell(m,full(x(1:(2*Nx+1)*(2*Ny+1))));
        sw_new = reshapeCell(m,full(x((2*Nx+1)*(2*Ny+1)+1:end)));
        % calculate error values
        error_p = max(abs((p_new(:)-p.value(:))./p_new(:)));
        error_sw = max(abs(sw_new(:)-sw.value(:)));
        % assign new values of p and sw
        p.value = p_new;
        sw.value = sw_new;
    end
    t=t+dt;
    p_old = p;
    sw_old = sw;
    figure(1);visualizeCells(sw);shading interp; drawnow;
    sw_tot=sw.value.*X.*Y/(W*H);
    oil_prod=(sum(sum(sw_tot(2:end-1,2:end-1))));
    figure(2);semilogx(t, p_new(2,2), 'o'); drawnow;
end


function plotIntCon(prob,data)
%PLOTINTCON Plot Integer Constraints on the current figure
%   plotIntCon(prob)

%   Copyright (C) 2011 Jonathan Currie (I2C2)

%Check we have integer variables in this plot
if(all(prob.int.str(data.idx) == 'C'))
    return; %nothing to do!
end

xl = round(xlim); yl = round(ylim);
hold on;

%Get Problem Components
if(~isempty(prob.rl))
    [A,b,Aeq,beq] = row2gen(prob.A,prob.rl,prob.ru);
else
    A = prob.A; b = prob.b;
    Aeq = prob.Aeq; beq = prob.beq;
end
Q = prob.Q; l = prob.l; qrl = prob.qrl; qru = prob.qru;
if(isempty(prob.lb)), lb = -Inf; else lb = prob.lb; end
if(isempty(prob.ub)), ub = Inf; else ub = prob.ub; end

%Check for 1D problem
if(prob.sizes.ndec == 1)
    if(prob.int.ind(1) == -1)
        X = 0:1; Y = [];
    else
        X = (floor(xl(1))+1):(ceil(xl(2))-1); Y = [];
    end
else
    %Generate Grid and check for binary constraints
    if(prob.int.ind(1) == -1)
        x = 0:1;
    else
        try
            x = (floor(xl(1))+1):(ceil(xl(2))-1);
        catch ME
            optiwarn('opti:plotint',['Could not plot integer constraints due to plotting error: ' ME.message]);
            return;
        end
    end
    if(prob.int.ind(2) == -1)
        y = 0:1;
    else
        try
            y = (floor(yl(1))+1):(ceil(yl(2))-1);
        catch ME
            optiwarn('opti:plotint',['Could not plot integer constraints due to plotting error: ' ME.message]);
            return;
        end
    end
    [X,Y] = meshgrid(x,y);
end

%Check for row nonlinear constraints
if(~isempty(prob.cl))
    prob = nrow2mix(prob,0,false);
end

%Work out feasible integer points
idx = zeros(numel(X),1); Xv = X(:); Yv = Y(:);
for i=1:numel(X)
    if(isempty(Yv))
        xy = Xv(i);
    else
        xy = data.fixval;
        xy(data.idx) = [Xv(i), Yv(i)]';
    end
    if(~isempty(prob.A))
        idx(i) = all(b >= A*xy) && all(xy >= lb) && all(xy <= ub);
    else
        idx(i) = all(xy >= lb) && all(xy <= ub);
    end
    if(~isempty(Aeq))
        idx(i) = idx(i) && (abs(Aeq*xy-beq) < 1e-6);
    end
    if(~isempty(Q))
        for n = 1:prob.sizes.nqc
            if(iscell(Q))
                nQ = Q{n}; nl = l(:,n); nrl = qrl(n); nru = qru(n);
            else
                nQ = Q; nl = l; nrl = qrl; nru = qru;
            end
            if(~isinf(nru))
                qu = all(xy'*nQ*xy + nl'*xy <= nru);
            else
                qu = true;
            end
            if(~isinf(nrl))
                ql = all(xy'*-nQ*xy - nl'*xy <= -nrl);
            else
                ql = true;
            end
            idx(i) = idx(i) && ql && qu;
        end
    end
    if(~isempty(prob.nle))
        vals = prob.nlcon(xy);
        leI = find(prob.nle == -1);
        geI = find(prob.nle == 1);
        eqI = find(prob.nle == 0);
        nlrhs = prob.nlrhs;
        idx(i) = idx(i) && all(vals(leI) <= nlrhs(leI)) && all(vals(geI) >= nlrhs(geI)) && all(abs(vals(eqI)-nlrhs(eqI)) < 1e-6);
    end
end
%Plot points
idx = logical(idx);
if(isempty(Y))
    Y = zeros(size(X));
    for i = 1:length(Y)
        Y(i) = prob.objective(X(i));
    end
end
plot(X(idx),Y(idx),'bo','markerface','b','markersize',5);
plot(X(~idx),Y(~idx),'bo','markersize',5);

hold off;

end


function bvanofit(mycat, seg1, seg2)
    % bvanofit  Calculates Freq-Mag functions (b-value) for two time-segments
    %   finds best fit to the foreground for a modified background
    %   assuming a change in time of the following types:
    %   Mnew = Mold + d     , i.e. Simple magnitude shift
    %   Mnew = c*Mold + d   , i.e. Mag stretch plus shift
    %   Nnew = fac*Nold     , i.e. Rate change (N = number of events)
    %
    % bvanofit(catalog)
    %                                      R. Zuniga IGF-UNAM/GI-UAF  6/94
    % turned into function by Celso G Reyes 2017

    % used to work from newt2 and set newcat

    report_this_filefun();
    ZG=ZmapGlobal.Data;
    ms3 = 5;
    t1p=seg1(1);
    t2p=seg1(2);
    t3p=seg2(1);
    t4p=seg2(2);
    % This is the info window text
    %
    ttlStr='Comparing Seismicity rates ';
    hlpStr1map= ...
        ['                                                '
        ' To be Implemented                              '
        '                                                '];
    % Find out if figure already exists
    %
    bvfig=findobj('Type','Figure','-and','Name','Compare two rates');

    % Set up the Seismicity Map window Enviroment
    %
    if isempty(bvfig)
        bvfig= figure_w_normalized_uicontrolunits( ...
            'Name','Compare two rates',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'Visible','on');%, ...
        %'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)+200));

        %{
        uicontrol('Units','normal',...
            'Position',[.0 .93 .08 .06],'String','Print ',...
            'callback',@callbackfun_001)

        uicontrol('Units','normal',...
            'Position',[.0 .75 .08 .06],'String','Close ',...
            'callback',@callbackfun_002)

        uicontrol('Units','normal',...
            'Position',[.0 .85 .08 .06],'String','Info ',...
            'callback',@callbackfun_003)
        %}
        axis off

    end % if figure exits

    figure(bvfig);
    clf
    %delete(findobj(bvfig,'Type','axes'));
    format short;

    if isempty(mycat),
        mycat = ZG.primeCatalog;  % points to same thing
    end
    [minmag2, maxmag] = bounds(mycat.Magnitude);
    n = mycat.Count;
    tdiff = round(days(mycat.DateSpan()));

    % number of mag units
    %nmagu = (maxmag*10)+1;

    %backg_beN = [ ];
    %backg_abN = [ ];
    td12 = t2p - t1p;
    td34 = t4p - t3p;

    magsteps_desc = (maxmag:-0.1:minmag2);
    xt3edges = fliplr([magsteps_desc+.05 magsteps_desc(end)-.05]);

    %bg_seg = segmentAnalytics(mycat,'background',t1p,t2p); %instead of first segment
    %fg_seg = segmentAnalytics(mycat,'foreground',t3p,t4p); %instead of second segment

    %% first segment
    l = mycat.Date > t1p & mycat.Date < t2p ;
    backg =  mycat.subset(l);
    [bval,~] = histcounts(backg.Magnitude,xt3edges);%hist
    xt2=magsteps_desc; % based off of magnitude centers, not edges
    bval = bval / days(td12);                      % normalization
    assert(size(bval,1)<=1,'expecting a long row');
    bvalsum = cumsum(bval);                        % N for M <=
    bvalsum_bkw = cumsum(fliplr(bval));    % N for M >= (counted backwards) (was valsum3)
    %[cumux, xt] = hist(mycat.Date(l),t1p:days(ZG.bin_dur):t2p);
    [cumux, xt] = histcounts(mycat.Date(l),'BinWidth',ZG.bin_dur);
    mean1 = mean(cumux);
    var1 = cov(cumux);

    %% second segment
    l = mycat.Date > t3p & mycat.Date < t4p ;
    foreg = mycat.subset(l);
    [bval2,xt3a] = histcounts(foreg.Magnitude,xt3edges); %was histogram
    bval2 = bval2/days(td34);
    bvalsum2 = cumsum(bval2);
    bvalsum2_bkw=cumsum(fliplr(bval2)); % was bvalsum4
    % [cumux2, xt] = hist(mycat.Date(l),t3p:days(ZG.bin_dur):t4p);
    [cumux2, xt] = histcounts(mycat.Date(l),'BinWidth',ZG.bin_dur);
    mean2 = mean(cumux2);
    var2 = cov(cumux2);
    zscore = (mean1 - mean2)/(sqrt(var1/length(cumux)+var2/length(cumux2)));

    %change in percent
    R1 = backg.Count/days(t2p-t1p);
    R2 = foreg.Count/days(t4p-t3p);
    change = -((R1-R2)/R1)*100;

    %{
    backg_be = log10(bvalsum);
    backg_ab = log10(bvalsum_bkw);
    foreg_be = log10(bvalsum2);
    foreg_ab = log10(bvalsum2_bkw);
    %}

    % plot b-value plot
    %
    orient tall
    set(gcf,'PaperPosition',[2 1 5.5 7.5])
    p1 = subplot(5,1,[1 2]);
    %rect = [0.20,  0.7, 0.70, 0.25];           % plot Freq-Mag curves
    %axes('position',rect)
    figure(bvfig);

    d2char=@(d)[char(d,'yyyy-') num2str(days(d-dateshift(d,'start','year')),'%06.2f') ];

    segA_linespec = 'xb-';
    segA_dispname = [ d2char(t3p) ' - '  d2char(t4p)];

    segB_linespec = 'om-.';
    segB_dispname = [d2char(t1p) ' - ' d2char(t2p)]

    semilogy(p1,magsteps_desc,bvalsum2_bkw,segA_linespec,'MarkerSize',ms3,'DisplayName',segA_dispname);
    set(gca,'NextPlot','add')
    semilogy(p1,magsteps_desc,bvalsum_bkw,segB_linespec,'MarkerSize',ms3,'DisplayName',segB_dispname);
    legend show

    te1 = max([bvalsum  bvalsum2 bvalsum2_bkw bvalsum_bkw]);
    te1 = te1 - 0.2*te1;

    ylabel(p1,'Cum. rate/year','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold')
    str = { 'Event rate comparison for 2 time periods',['Change in %: ' num2str(change,6) ]};

    title(p1,str,'FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold')

    %  find b-values;
    set(p1,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.s,'Linewidth',1.0)

    % Plot histogram
    %rect = [0.20,  0.40 0.70, 0.25];
    %axes('position',rect)
    p2=subplot(5,1,[3 4]);
    plot(p2,xt2,bval2,segA_linespec,'MarkerSize',ms3,'LineWidth',1.0)
    set(gca,'NextPlot','add')
    plot(p2,xt2,bval,segB_linespec,'MarkerSize',ms3,'LineWidth',1.0)
    disp([' Summation: ' num2str(sum(bval-bval2))])
    v = axis;
    xlabel(p2,'Magnitude ','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold')
    ylabel(p2,'rate/year','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold')
    set(p2,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.s,'Linewidth',1.0)

    uic = uicontrol('Units','normal','Position',[.35 .05 .30 .06],'String','Magnitude Signature? ', 'callback',@callbackfun_004,'enable','off');

    watchoff

    % Plot he b-value comparison
    ZG.hold_state=false;
    bdiff(backg)
    ZG.hold_state=true;
    bdiff(foreg)

    function callbackfun_004(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        delete(uic);
        synsig3;
    end

    function seg = segmentAnalytics(mycat, name, t1, t2)
        % alternate way of dong this for the functions
        seg=struct('name',name,'start',t1,'end',t2);
        seg.duration= seg.end - seg.start;
        index = mycat.Date > seg.start & mycat.Date < seg.end;
        seg.catalog = mycat.subset(index);
        seg.bvals = histcounts(seg.catalog.Magnitude, xt3edges);
        seg.scaledbvals = seg.bvals / days(seg.duration);
        seg.bvalcum = cumsum(seg.scaledbvals);
        seg.bvalcum_bkw = cumsum(fliplr(seg.scaledbvals));
        [seg.datecounts, seg.date_edges] = histcounts(seg.catalog.Date,'BinWidth',ZG.bin_dur);
        seg.meanEventsTime = mean(seg.datecounts);
        seg.covEventsTime = cov(seg.datecounts);
    end

end


classdef dat_wc_reader < handle
	properties
        sr
        min_index
        max_segments
        raw_filename
        sr_infile
        t0_segments
        max_index
        segmentLength
        spikes_file
    end
	methods
        function obj = dat_wc_reader(par, raw_filename)
            obj.sr = [];
            obj.max_segments = [];
            obj.raw_filename = raw_filename;
            obj.spikes_file = false;
            data = csvread(raw_filename);

            obj.sr_infile = false;
            if isfield(par,'sr')
                obj.sr = par.sr;
            end
            obj.min_index = floor(par.tmin * obj.sr);                   %min time to read (in micro-sec)

            if strcmp(par.tmax,'all')
                obj.max_index = max(size(data));
            else
                obj.max_index = ceil(par.tmax * obj.sr);
            end
            t0 = (obj.min_index-1)/obj.sr*1000;
            n = obj.max_index -  obj.min_index;

            %Segments the data in par.segments pieces
            obj.max_segments = ceil(n/ obj.sr / ...
                    (par.segments_length * 60));         %number of segments in which data is cutted

            obj.segmentLength = floor (n/obj.max_segments);

            obj.t0_segments = ones(1,obj.max_segments);
            obj.t0_segments(1) = t0;
            for i = 2:obj.max_segments
                obj.t0_segments(i) = obj.t0_segments(i-1) + obj.segmentLength/obj.sr*1000;
            end

        end

        function [sr,max_segments,with_raw,with_spikes] = get_info(obj)
            if isempty(obj.max_segments)
                with_raw = false;
                max_segments = 0;
            else
                with_raw = true;
                max_segments = obj.max_segments;
            end

            with_spikes = obj.spikes_file;
            if obj.sr_infile
                sr = obj.sr;
            else
                sr = [];
            end
        end

        function index_ts = index2ts(obj,index,i)
            index_ts = (index)/obj.sr*1000 + obj.t0_segments(i);
        end

        function x = get_segment(obj,i)

            if i ~= obj.max_segments
                lastsample = obj.min_index+obj.segmentLength*i;
            else
                lastsample = obj.max_index;
            end
            firstsample = obj.min_index+obj.segmentLength*(i-1)+1;

            x = csvread(obj.raw_filename); %it's sub optimal but the best way to handle inconsistent .dat files
            x = x(firstsample:lastsample);
        end
    end
end


% Author: Yong Yuan
% Homepage: yongyuan.name

clear all;close all;clc;

% version: matconvnet-1.0-beta17
%run ./matconvnet-1.0-beta17/matlab/vl_compilenn
run ./matconvnet-1.0-beta17/matlab/vl_setupnn

%% Step 1 lOADING PATHS
path_imgDB = './facesDataset/';
addpath(path_imgDB);
addpath tools;

% viesion: matconvnet-1.0-beta17
net = load('vgg-face.mat') ;

%% Step 2 LOADING IMAGE AND EXTRACTING FEATURE
imgFiles = dir(path_imgDB);
imgNamList = {imgFiles(~[imgFiles.isdir]).name};
clear imgFiles;
imgNamList = imgNamList';

numImg = length(imgNamList);
feat = [];
rgbImgList = {};

%parpool;

%parfor i = 1:numImg
for i = 1:numImg
   oriImg = imread(imgNamList{i, 1});
   featVec = extractCNN(oriImg, net);
   feat = [feat; featVec'];
   fprintf('extract %d image\n\n', i);
end

feat_norm = normalize1(feat);
save('feat4096Norml.mat','feat_norm', 'imgNamList', '-v7.3');


function Centers = NSGA2ESelection(tr_x, tr_y, models, str, Problem, Ke)
% NSGA-II based selection

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    nn=0;
    while (nn==100||nn==0)
        population = rand(Problem.N,Problem.D); %N*D
        population = population.*repmat(Problem.upper,Problem.N,1)+(1-population).*repmat(Problem.lower,Problem.N,1);%N*D
        population(:,Problem.D+1:Problem.D+Problem.M)=Estimate(population(:,1:Problem.D), tr_x, tr_y, models, str, Problem.M);%The value of objective by model

        [~,FrontNo,CrowdDis] = EnvironmentalSelection(population,Problem.N,Problem.D,Problem.M);%N*(D+M)

        %% Optimization of NSGA-II
        for i=1:floor(Problem.maxFE/Problem.N)
            MatingPool = TournamentSelection(2,Problem.N,FrontNo,-CrowdDis);
            parent     = population(MatingPool,:);
            offspring  = OperatorGA(Problem,parent(:,1:Problem.D),{1,20,1,20});
            offspring(:,Problem.D+1:Problem.D+Problem.M)=Estimate(offspring(:,1:Problem.D), tr_x, tr_y, models, str, Problem.M);%The value of objective by model
            [population,FrontNo,CrowdDis] = EnvironmentalSelection([population;offspring],Problem.N,Problem.D,Problem.M);
        end
        [Centers, nn]=Kmean([population,FrontNo',CrowdDis'], tr_x, Problem.N, Problem.D, Ke);
    end
end

function objv_LCB=Estimate(x, tr_x, tr_y, models, str,m)
    alpha=2;
    TestSamNum=size(x,1);n=length(models);
    sum=zeros(TestSamNum, size(tr_y,2));
    for i=1:n
        clear y;
        stri=str(i,:);
        M=models(i).M;p=models(i).p;
        if strcmp(stri(1), 'FE')%PCA
            x_pca=x*M;
            if strcmp(stri(2), 'RBF1')%RBF
                y= sim(p,x_pca');y=y';
            elseif strcmp(stri(2), 'SVM')
                y=SVMtest(x_pca, p, TestSamNum,m);
            elseif strcmp(stri(2), 'RBF2')%RBF
                y=RBF2test(x_pca, p, TestSamNum);
            end

        elseif strcmp(stri(1), 'NONE')%NONE
            if strcmp(stri(2), 'RBF1')%RBF
                y= sim(p,x');y=y';
            elseif strcmp(stri(2), 'SVM')
                y=SVMtest(x, p, TestSamNum, m);
            elseif strcmp(stri(2), 'RBF2')%RBF
                y=RBF2test(x, p, TestSamNum);
            end

        elseif strcmp(stri(1), 'FS')%CSO
            x_cso=x(:,M);
            if strcmp(stri(2), 'RBF1')%RBF
                y= sim(p,x_cso');y=y';
            elseif strcmp(stri(2), 'SVM')
                y=SVMtest(x_cso, p, TestSamNum,m);
            elseif strcmp(stri(2), 'RBF2')%RBF
                y=RBF2test(x_cso, p, TestSamNum);
            end
        end
        result(i).y=y;
        sum=sum+y;
    end
    me=sum/n;
    sum=zeros(TestSamNum, size(tr_y,2));
    for i=1:n
        y=result(i).y;
        sum=sum+(y-me).^2;
    end
    s2=sum/(n-1);
    %fmin=min(tr_y);
    %fmin_matrix=repmat(fmin,TestSamNum,1);
    objv_LCB=me-alpha*sqrt(s2);
end

function y=SVMtest(x, p, N, M)
    ps1=p{1};ps2=p{2};
    xtest0=mapminmax('apply',x',ps1);xtest0=xtest0';
%     py = zeros(N,M);
    for j=1:M
        for k=1:N
            py(k,j) = svmpredict(0,xtest0(k,:),p{j+2}, '-q');
        end
    end
    y=mapminmax('reverse',py',ps2);y=y';
end

function y=RBF2test(x, p, N)
    Centers=p.Centers;Spreads=p.Spreads;
    W2=p.W2;B2=p.B2;
    TestDistance = dist(Centers,x');
    TestSpreadsMat = repmat(Spreads,1,N);
    TestHiddenUnitOut = radbas(TestDistance./TestSpreadsMat);
    y= (W2*TestHiddenUnitOut+repmat(B2,1,N))';
end

function [population,FrontNo,CrowdDis] = EnvironmentalSelection(population,N,D,M)
% The environmental selection of NSGA-II

    %% Non-dominated sorting
    [FrontNo,MaxFNo] = NDSort(population(:,D+1:D+M),[],N);
    Next = FrontNo < MaxFNo;

    %% Calculate the crowding distance of each solution
    CrowdDis = CrowdingDistance(population(:,D+1:D+M),FrontNo);

    %% Select the solutions in the last front based on their crowding distances
    Last     = find(FrontNo==MaxFNo);
    [~,Rank] = sort(CrowdDis(Last),'descend');
    Next(Last(Rank(1:N-sum(Next)))) = true;

    %% Population for next generation
    population = population(Next,:);
    FrontNo    = FrontNo(Next);
    CrowdDis   = CrowdDis(Next);
end

function [Centers, nn]=Kmean(chromosome, tr_x, N, D, Ke)
    % Delete the multiple solutions between chromosome and the train data
    Q=[];P=[];
    for i=1:N
        PandQ=[tr_x;Q];
        matrix=dist(chromosome(i,1:D),PandQ');%1*size(PandQ,1) array
        if isempty(find(matrix<=10^-06))
            Q=[Q;chromosome(i,1:D)];
            P=[P;chromosome(i,:)];
        end
    end
    if size(Q,1)<Ke
        Centers=[];nn=100;
    else
        index=randperm(size(Q,1));
        Centers=Q(index(1:Ke),1:D);n=1;si=size(Q,1);
        % Cluster by the distance of the decision space
        while n<100

            NumberInClusters = zeros(Ke,1); % Number of samples in each class ,default is 0
            IndexInClusters = zeros(Ke,N); % Index of samples in each class
            % Classify all samples by the least distance principle
            for i = 1:si
                AllDistance = dist(Centers,Q(i,1:D)');% Calculate the distance between the i-th solution and each clustering center
                [~,Pos] = min(AllDistance);   % Minimum distance,training input is the index of clustering center
                NumberInClusters(Pos) = NumberInClusters(Pos) + 1;
                IndexInClusters(Pos,NumberInClusters(Pos)) = i;% Stores the training indexes belonging to this class in turn
            end
            % Store the old clustering centers
            OldCenters = Centers;
            % Recalculate the clustering centers
            for i = 1:Ke
                Index = IndexInClusters(i,1:NumberInClusters(i));% Extract the training input index belonging to this class
                Centers(i,:) = mean(Q(Index,1:D),1);    %Take the average of each class as the new clustering center
            end
            % Judge whether the old and new clustering centers are consistent
            EqualNum = sum(sum(Centers==OldCenters));% Centers and OldCenters are subtracted from each other to sum up all corresponding bits
            if EqualNum ==D*Ke % The old and new clustering centers are consistent
                break,
            end
            n=n+1;
        end
        nn=n;fprintf('k-means clustering %d\n',n);
    end
end


function L = noiseLikelihood(noise, mu, varsigma, y);

% NOISELIKELIHOOD Return the likelihood for each point under the noise model.
% FORMAT
% DESC returns the likelihoods for data points under the given noise model.
% ARG noise : the noise structure for which the likelihood is required.
% ARG mu : input mean locations for the likelihood.
% ARG varSigma : input variance locations for the likelihood.
% ARG y : target locations for the likelihood.
%
% SEEALSO : noiseParamInit, noiseLogLikelihood
%
% COPYRIGHT : Neil D. Lawrence, 2004, 2005

% NOISE

fhandle = str2func([noise.type 'NoiseLikelihood']);
L = fhandle(noise, mu, varsigma, y);


function [ past_tracks, future_tracks ] = get_tracks( curr_tracks, curr_tags, curr_date_index )
%GET_TRACKS Summary of this function goes here
%   Detailed explanation goes here

% Getting the current eddy indexes in tracks and track length
track_lengths = cellfun(@(x) size(x, 1), curr_tracks);

curr_eddy_indexes = zeros(size(track_lengths));
for i = 1:length(curr_tracks)
    curr_eddy_indexes(i) = find(curr_tracks{i}(:, 3) == curr_date_index, 1);
end

% Pre-allocate past_tracks and future_tracks
past_tracks = nan(sum(curr_eddy_indexes) + length(curr_tracks), 3);
future_tracks = nan(sum(track_lengths) - sum(curr_eddy_indexes) +  2 * length(curr_tracks), 3);

next_future_track_index = 1;
next_past_track_index = 1;
for i = 1:length(curr_tracks)
    curr_track = curr_tracks{i};
    curr_tag = curr_tags{i};
    curr_eddy_index = curr_eddy_indexes(i);

    past_tracks(next_past_track_index:(next_past_track_index + curr_eddy_index - 1), 1:2) = ...
        curr_track(1:curr_eddy_index, 1:2);
    past_tracks(next_past_track_index:(next_past_track_index + curr_eddy_index - 1), 3) = ...
        curr_tag(1:curr_eddy_index);
    next_past_track_index = next_past_track_index + curr_eddy_index + 1;

    future_tracks(next_future_track_index:(next_future_track_index + track_lengths(i) - curr_eddy_index), 1:2) = ...
        curr_track(curr_eddy_index:end, 1:2);

    future_tracks(next_future_track_index:(next_future_track_index + track_lengths(i) - curr_eddy_index), 3) = ...
        curr_tag(curr_eddy_index:end);
    next_future_track_index = next_future_track_index + track_lengths(i) - curr_eddy_index + 2;
end

end


close all
clear all

% r1 = importdata('C:\Users\hakki\Downloads\camera-pipeline-UI-master\camera-pipeline-UI-master\image\r.txt');
% g1 = importdata('C:\Users\hakki\Downloads\camera-pipeline-UI-master\camera-pipeline-UI-master\image\g.txt');
% b1 = importdata('C:\Users\hakki\Downloads\camera-pipeline-UI-master\camera-pipeline-UI-master\image\b.txt');
% [m,n] = size(r1);
% image1 = zeros(m,n,3);
% image1(:,:,1) = r1;
% image1(:,:,2) = g1;
% image1(:,:,3) = b1;

% save image as binary file
% fd = fopen('x.txt','w');
%     fwrite(fd,image1(:,:,1)','double');
%     fclose(fd);
%
% fd2 = fopen('y.txt','w');
%     fwrite(fd2,image1(:,:,2)','double');
%     fclose(fd2);
% fd3 = fopen('z.txt','w');
%     fwrite(fd3,image1(:,:,3)','double');
%     fclose(fd3);

% image = im2double(image)/65536;
% figure, imshow(image1)

    fd1 = fopen('r.txt','r');
    fd2 = fopen('g.txt','r');
    fd3 = fopen('b.txt','r');
    r = fread(fd1,[ 3008 2000], 'double');
    fclose(fd1);
    g = fread(fd2,[ 3008 2000], 'double');
    fclose(fd2);
    b = fread(fd3,[ 3008 2000], 'double');
    fclose(fd3);

image = zeros(2000, 3008, 3);
image(:,:,1) = r';
image(:,:,2) = g';
image(:,:,3) = b';
image = im2double(image);
figure, imshow(image)

%% proof that txt files and stage 4 size is not equal.
% prophoto2 = im2double(imread('..\current_result.tif'));
%center aligned
eucliudian_error1 = sqrt((image(:,:,1)-...
    image1(:,:,1)).^2 + ...
    (image(:,:,2)-...
    image1(:,:,2)).^2 + ...
    (image(:,:,3)-...
    image1(:,:,3)).^2);
sum(eucliudian_error1(:))
figure,
imagesc(eucliudian_error1, [0 0.01]);

% abs()


function SimpleWHPlotSpectrograms(W,H,Data, plotAll);
% plots seqNMF factors W and H
% Also plots Data if provided, and reconstruction if data is not provided
% plotAll=1 means plot all data
% plotAll=0 means crop data so it's on the same timescale as W's
% Emily Mackevicius 2/3/2018

clf

% set(gcf, 'color', 'w');
if nargin < 4
    plotAll = 1;
end
if nargin < 3 || size(Data,2)==0
    plotData = 0;
else
    plotData = 1;
end

[N,K,L] = size(W);
[~,T] = size(H);
color_palet = [[0 .6 .3]; [.7 0 .7]; [1 .6 0];  [.1 .3 .9];  [1 .1 .1];  [0 .9 .3]; [.4 .2 .7]; [.7 .2 .1]; [.1 .8 1 ]; [1 .3 .7]; [.2 .8 .2]; [.7 .4 1]; [.9 .6 .4]; [0 .6 1]; [1 .1 .3]];
% if K<7
%     color_palet = jet(K);
% else
%     color_palet = [jet(7); (jet(7)+1)/2];
%     color_palet = repmat(color_palet, ceil(K/size(color_palet,1)),1);
% end
kColors = color_palet(1:K,:);
%% set widths of subplots
m = .1; % margin
ww = .35; % width of W plot
wwflat = .05; % width of Wflat plot
hh = .45; % height of H plot
hdata = 1-hh-2*m;
wdata = 1-ww-wwflat-2*m;
sep = ceil(L*.1);

%% crop data, unless plotAll
if plotAll
    indplot = 1:T;
else
    indplot =(1:ceil((K*(L+sep))/ww*wdata)); % so that data and W's are on same scale
    indplot(indplot>T) = [];
end

%% plot W's
axW = subplot('Position', [m m ww hdata]);
hold on
set(gca, 'ColorOrder', kColors);

WsToPlot = zeros(N,K*(L+sep));
XsToPlot = zeros(3,K);
YsToPlot = [N*ones(1,K); zeros(2,K)]+.5;
for ki = 1:K
    WsToPlot(:,((L+sep)*(ki-1)+1):((L+sep)*(ki-1)+L)) = squeeze(W(:,ki,:));
    XsToPlot(:,ki) = [(L+sep)*(ki-1)+1 (L+sep)*(ki-1)+1 (L+sep)*(ki-1)+L];
end
clims = [0 prctile(WsToPlot(WsToPlot>0),99)]; % if all W's are empty this line will bug
imagesc(WsToPlot, clims);
cmap = 1/256*flipud([158,1,66;213,62,79;244,109,67;253,174,97;254,224,139;255,255,191;230,245,152;171,221,164;102,194,165;50,136,189;94,79,162;1 1 1]);
% cmap = flipud(gray);
colormap(cmap)
plot(XsToPlot,YsToPlot, 'linewidth', 2);
xlim([1 K*(L+sep)]);ylim([0 N+.1]+.5)
set(gca, 'ydir', 'reverse')
axis off

%% plot data
axIm = subplot('Position', [m+ww m wdata hdata]);
if plotData
    clims = [0 prctile(Data(Data>0),99)];
    Im = imagesc(Data(:,indplot), clims);
else
    toplot = helper.reconstruct(W,H(:,indplot));
    clims = [0 prctile(toplot(:),99.9)];
    Im = imagesc(toplot,clims);
end
set(gca,'ydir','reverse')
hold on; plot([0 0 length(indplot)+1], [N 0 0]+.5, 'k')
xlim([0 length(indplot)+1]);ylim([0 N+.1]+.5)
axis off
%% plot Wflat (collapse out L dimension of W)
axWflat = subplot('Position', [m+ww+wdata m wwflat hdata]);
hold on
set(gca, 'ColorOrder', kColors);
plot(squeeze(sum(W,3)), 1:N,'>', 'markersize', 2.5);
ylim([0 N+.1]+.5)
axis tight
xlims = xlim;
xlim([xlims(2)*.1 xlims(2)])
set(gca, 'ydir', 'reverse')
axis off
%% plot H's
axH = subplot('Position', [m+ww m+hdata wdata hh]);
Hrescaled = squeeze(max(sum(W,1),[],3))'.*H; % rescale by approximate loading
dn = prctile(Hrescaled(:),100)/2;
for ki = K:-1:1
    Xs = [1 1:length(indplot) length(indplot)];
    Ys = [dn*ki (dn*ki + Hrescaled(K-ki+1,indplot)) dn*ki]-dn/2;
    patch(Xs,Ys, kColors(K-ki+1,:), 'edgecolor', kColors(K-ki+1,:))
    hold on
end
ylim([0 dn*K+dn*3]);xlim([0 length(indplot)+1])
axis off
%%
if plotAll
      linkaxes([axIm axW axWflat], 'y'); linkaxes([axIm axH], 'x');
end


function x = ndmax(x,dim)
% NDMAX    Multi-dimensional maximization.
% NDMAX(X,DIM) takes the maximum element along the dimensions in DIM,
% and squeezes the result.

% Written by Thomas P Minka
% (c) Microsoft Corporation. All rights reserved.

sz = size(x);
for i=1:length(dim)
  x = max(x, [], dim(i));
end
x = mysqueeze(x);
addflops(2*(prod(sz)-prod(size(x))));


%%
% Test function to compare nn_bnorm and its GPU/CPU implementation with
% using VLFEAT
%%

gpu = false;
gpu = true ;

T = 1 ;
x = randn(64,64,32,32,'single') ;
g = randn(32,1,'single') ;
b = randn(32,1,'single') ;

if gpu
  x = gpuArray(x) ;
  g = gpuArray(g) ;
  b = gpuArray(b) ;
end

a=vl_nnbnorm(x,g,b);
a_=vl_nnbnorm_old(x,g,b);

vl_testsim(a,a_)


function x = evaluate_nonlinear(p,x,qq)

% FIX: We have to apply computations to make sure we are evaluating
% expressions such as log(1+sin(x.^2).^2) correctly

if ~isempty(p.bilinears) & all(p.variabletype <= 2) & length(p.evalMap)==0
    x(p.bilinears(:,1)) = x(p.bilinears(:,2)).*x(p.bilinears(:,3));
else
    oldx = 0*p.c;old(1:length(x))=x;
    %try
    x = process_polynomial(x,p);
    %catch
    %    1
    %end
    x = process_evaluations(x,p);
    while norm(x - oldx)>1e-8
        oldx = x;
        x = process_polynomial(x,p);
        x = process_evaluations(x,p);
    end
end

function x = process_evaluations(x,p)
for i = 1:length(p.evalMap)
    arguments = {p.evalMap{i}.fcn,x(p.evalMap{i}.variableIndex)};
    arguments = {arguments{:},p.evalMap{i}.arg{2:end-1}};
    x(p.evalVariables(i)) = feval(arguments{:});
    if ~isempty(p.bilinears)
        x = process_bilinear(x,p);
    end
end

function x = process_bilinear(x,p)
x(p.bilinears(:,1)) = x(p.bilinears(:,2)).*x(p.bilinears(:,3));

function x = process_polynomial(x,p)
x = x(1:length(p.c));
nonlinear = find(p.variabletype);
x(nonlinear) = prod(repmat(x(:)',length(nonlinear),1).^p.monomtable(nonlinear,:),2);


function x = p01_start ( option, nvar )

%*****************************************************************************80
%
%% P01_START returns a starting point for problem 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Output, real X(NVAR), the starting point.
%
  x = zeros ( nvar, 1 );

  if ( option == 1 | option == 2 | option == 3 )
    x(1:3) = [ 15.0, -2.0, 0.0 ]';
  elseif ( option == 4 | option == 5 | option == 6 )
    x(1:3) = [ 4.0, 3.0, 0.0 ]';
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P01_START - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized option  = %d\n', option );
    error ( 'P01_START - Fatal error!' );
  end

  return
end


function [periods,quiescence] = QuietPeriods(v,velocity,duration,brief)

%QuietPeriods - Find periods of immobility.
%
%  Find periods of immobility, i.e. periods of sufficient duration
%  where instantaneous linear velocity remains low. Brief movements
%  can be ignored.
%
%  USAGE
%
%    [periods,quiescence] = QuietPeriods(v,velocity,duration,brief)
%
%    v              linear velocity samples [t v]
%    velocity       maximum velocity of a quiet period
%    duration       minimum duration of a quiet period
%    brief          optional maximum duration of a 'brief' movement
%
%  OUTPUT
%
%    periods        list of [start stop] pairs
%    quiescence     list of [t s] pairs, where s is 1 if the animal
%                   is quiet at time t (and 0 otherwise)
%
%  SEE
%
%    See also BrainStates, PlotIntervals.

% Copyright (C) 2008-2011 by Michaël Zugaro
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 3 of the License, or
% (at your option) any later version.

if nargin < 3,
	error('Incorrect number of parameters (type ''help QuietPeriods'' for details).');
end
if nargin == 3,
	brief = 0;
end

% Determine beginning/end of quiet periods
below = v(:,2) < velocity;
crossings = diff(below); % yields -1 for upward crossings, and 1 for downward crossings
start = find(crossings == 1);
stop = find(crossings == -1);

% The previous code would ignore quiet periods beginning at the first sample, or ending at the last sample; correct for this
if below(1),
	start = [1;start];
end
if below(end),
	stop = [stop;length(below)];
end

% Determine durations of movements, and discard brief ones
durations = v(start(2:end),1) - v(stop(1:end-1),1);
ignore = find(durations <= brief);
start(ignore+1) = [];
stop(ignore) = [];

% Keep only long enough periods
durations = v(stop,1)-v(start,1);
discard = durations < duration;
start(discard) = [];
stop(discard) = [];

% Outputs
periods = [v(start,1) v(stop,1)];
quiescence = zeros(size(v,1),2);
quiescence(:,1) = v(:,1);
for i = 1:length(start),
	quiescence(start(i):stop(i),2) = 1;
end


function new_regions = split_regions(regions, bndinfo, sp_areas)

spLR = bndinfo.edges.spLR;

n_sps = bndinfo.nseg;

if(iscell(regions))
   % get overlapping regions
   overlapping = [];

   sp_map = zeros(numel(regions), n_sps);

   for prop = 1:length(regions)
      sp_map(prop,regions{prop}) = 1;
   end
else
   sp_map = regions;
end

inds = double([spLR(:,[1 2]); spLR(:, [2 1]); repmat([1:n_sps]', 1, 2)]);

%sp_map_sparse = sparse(sp_map);
%sparse_adjacency = sparse(inds(:,1), inds(:,2), ones(2*size(spLR,1), 1));
adjacency = (accumarray(inds, ones(size(inds,1), 1), [n_sps n_sps]));
%adjacency_s = sparse(accumarray(inds, ones(size(inds,1), 1), [n_sps n_sps]));

[adjacency_x adjacency_y adjacency_val] = find(adjacency);

new_regions = cell(size(sp_map,1), 1);
new_r_ind = 1;
tic;
for i = 1:size(sp_map,1)
   sp_inds = find(sp_map(i, :));
%   sub_graph = sparse(adjacency(sp_inds, sp_inds));

   ok = ismember_sorted(adjacency_x, sp_inds) & ismember_sorted(adjacency_y, sp_inds);
   ind = zeros(max(adjacency_x),1);
   ind(sp_inds) = 1:length(sp_inds);
   sub_graph = sparse(ind(adjacency_x(ok)), ind(adjacency_y(ok)), adjacency_val(ok), length(sp_inds), length(sp_inds));

   [conn1 comps1] = graphconncomp(sub_graph, 'Directed', true);

   if(conn1 > 1)
      if(toc>1)
         fprintf('%d (%d/%d)\n',new_r_ind, i, size(sp_map,1) );
         tic;
      end

      for j = 1:conn1
         if(new_r_ind>=numel(new_regions))
            fprintf('growing\n')
            new_regions{2*end}= [];
         end
         if(sum(sp_areas(sp_inds(comps1==j)))>(24*24))
            new_regions{new_r_ind} = sp_inds(comps1==j);
            new_r_ind = new_r_ind+1;
         end
      end
%      pause
   else
      if(new_r_ind>=numel(new_regions))
         fprintf('growing\n')
         new_regions{2*end}= [];
      end

      new_regions{new_r_ind} = sp_inds;
      new_r_ind = new_r_ind+1;
   %      pause(0.3)
   end

end

new_regions(new_r_ind+1:end) = [];


% Like a durational HMM, except we use soft evidence on the observed nodes.
% Should give the same results as HSMM/test_mgram2.

past = 1;
% If past=1, P(Yt|Qt=j,Dt=d) = P(y_{t-d+1:t}|j)
% If past=0, P(Yt|Qt=j,Dt=d) = P(y_{t:t+d-1}|j) - future evidence

words = {'the', 't', 'h', 'e'};
data = 'the';
nwords = length(words);
word_len = zeros(1, nwords);
word_prob = normalise(ones(1,nwords));
word_logprob = log(word_prob);
for wi=1:nwords
  word_len(wi)=length(words{wi});
end
D = max(word_len);

alphasize = 26*2;
data = letter2num(data);
T = length(data);

% node numbers
W = 1; % top level state = word id
L = 2; % bottom level state = letter position within word
F = 3;
O = 4;

ss = 4;
intra = zeros(ss,ss);
intra(W,[F L O])=1;
intra(L,[O F])=1;

inter = zeros(ss,ss);
inter(W,W)=1;
inter(L,L)=1;
inter(F,[W L O])=1;

% node sizes
ns = zeros(1,ss);
ns(W) = nwords;
ns(L) = D;
ns(F) = 2;
ns(O) = alphasize;
ns2 = [ns ns];

% Make the DBN
bnet = mk_dbn(intra, inter, ns, 'observed', O);
eclass = bnet.equiv_class;

% uniform start distrib over words, uniform trans mat
Wstart = normalise(ones(1,nwords));
Wtrans = mk_stochastic(ones(nwords,nwords));
%Wtrans = ones(nwords,nwords);

% always start in state d = length(word) for each bottom level HMM
Lstart = zeros(nwords, D);
for i=1:nwords
  l = length(words{i});
  Lstart(i,l)=1;
end

% make downcounters
RLtrans = mk_rightleft_transmat(D, 0); % 0 self loop prob
Ltrans = repmat(RLtrans, [1 1 nwords]);

% Finish when downcoutner = 1
Fprob = zeros(nwords, D, 2);
Fprob(:,1,2)=1;
Fprob(:,2:end,1)=1;

% Define CPDs for slice 1
bnet.CPD{eclass(W,1)} = tabular_CPD(bnet, W, 'CPT', Wstart);
bnet.CPD{eclass(L,1)} = tabular_CPD(bnet, L, 'CPT', Lstart);
bnet.CPD{eclass(F,1)} = tabular_CPD(bnet, F, 'CPT', Fprob);

% Define CPDs for slice 2
bnet.CPD{eclass(W,2)} = hhmmQ_CPD(bnet, W+ss, 'Fbelow', F, 'startprob', Wstart,  'transprob', Wtrans);
bnet.CPD{eclass(L,2)} = hhmmQ_CPD(bnet, L+ss, 'Fself', F, 'Qps', W+ss, 'startprob', Lstart, 'transprob', Ltrans);

if 0
% To test it is generating correctly, we create an artificial
% observation process that capitalizes at the start of a new segment
% Oprob(Ft-1,Qt,Dt,Yt)
Oprob = zeros(2,nwords,D,alphasize);
Oprob(1,1,3,letter2num('t'),1)=1;
Oprob(1,1,2,letter2num('h'),1)=1;
Oprob(1,1,1,letter2num('e'),1)=1;
Oprob(2,1,3,letter2num('T'),1)=1;
Oprob(2,1,2,letter2num('H'),1)=1;
Oprob(2,1,1,letter2num('E'),1)=1;
Oprob(1,2,1,letter2num('a'),1)=1;
Oprob(2,2,1,letter2num('A'),1)=1;
Oprob(1,3,1,letter2num('b'),1)=1;
Oprob(2,3,1,letter2num('B'),1)=1;
Oprob(1,4,1,letter2num('c'),1)=1;
Oprob(2,4,1,letter2num('C'),1)=1;

% Oprob1(Qt,Dt,Yt)
Oprob1 = zeros(nwords,D,alphasize);
Oprob1(1,3,letter2num('t'),1)=1;
Oprob1(1,2,letter2num('h'),1)=1;
Oprob1(1,1,letter2num('e'),1)=1;
Oprob1(2,1,letter2num('a'),1)=1;
Oprob1(3,1,letter2num('b'),1)=1;
Oprob1(4,1,letter2num('c'),1)=1;

bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', Oprob);
bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', Oprob1);

evidence = cell(ss,T);
%evidence{W,1}=1;
sample = cell2num(sample_dbn(bnet, 'length', T, 'evidence', evidence));
str = num2letter(sample(4,:))
end

if 1

[log_obslik, obslik, match] = mk_mgram_obslik(lower(data), words, word_len, word_prob);
% obslik(j,t,d)
softCPDpot = cell(ss,T);
ens = ns;
ens(O)=1;
ens2 = [ens ens];
for t=2:T
  dom = [F W+ss L+ss O+ss];
  % tab(Ft-1, Q2, Dt)
  tab = ones(2, nwords, D);
  if past
    tab(1,:,:)=1; % if haven't finished previous word, likelihood is 1
    %tab(2,:,:) = squeeze(obslik(:,t,:)); % otherwise likelihood of this segment
    for d=1:min(t,D)
      tab(2,:,d) = squeeze(obslik(:,t,d));
    end
  else
    for d=1:max(1,min(D,T+1-t))
      tab(2,:,d) = squeeze(obslik(:,t+d-1,d));
    end
  end
  softCPDpot{O,t} = dpot(dom, ens2(dom), tab);
end
t = 1;
dom = [W L O];
% tab(Q2, Dt)
tab = ones(nwords, D);
if past
  %tab = squeeze(obslik(:,t,:));
  tab(:,1) = squeeze(obslik(:,t,1));
else
  for d=1:min(D,T-t)
    tab(:,d) = squeeze(obslik(:,t+d-1,d));
  end
end
softCPDpot{O,t} = dpot(dom, ens(dom), tab);

%bnet.observed = [];
% uniformative observations
%bnet.CPD{eclass(O,2)} = tabular_CPD(bnet, O+ss, 'CPT', mk_stochastic(ones(2,nwords,D,alphasize)));
%bnet.CPD{eclass(O,1)} = tabular_CPD(bnet, O, 'CPT', mk_stochastic(ones(nwords,D,alphasize)));

engine = jtree_dbn_inf_engine(bnet);
evidence = cell(ss,T);
% we add dummy data to O to force its effective size to be 1.
% The actual values have already been incorporated into softCPDpot
evidence(O,:) = num2cell(ones(1,T));
[engine, ll_dbn] = enter_evidence(engine, evidence, 'softCPDpot', softCPDpot);

%evidence(F,:) = num2cell(2*ones(1,T));
%[engine, ll_dbn] = enter_evidence(engine, evidence);

gamma = zeros(nwords, T);
for t=1:T
  m = marginal_nodes(engine, [W F], t);
  gamma(:,t) = m.T(:,2);
end

gamma

xidbn = zeros(nwords, nwords);
for t=1:T-1
  m = marginal_nodes(engine, [W F W+ss], t);
  xidbn = xidbn + squeeze(m.T(:,2,:));
end

% thee
% xidbn(1,4)  = 0.9412  the->e
% (2,3)=0.0588 t->h
% (3,4)=0.0588 h-e
% (4,4)=0.0588 e-e

end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym zeros (@var{n})
%% @defmethodx @@sym zeros (@var{n}, @var{m})
%% Return a matrix whose elements are all 0.
%%
%% Example:
%% @example
%% @group
%% y = zeros (sym(3))
%%   @result{} y = (sym 3×3 matrix)
%%       ⎡0  0  0⎤
%%       ⎢       ⎥
%%       ⎢0  0  0⎥
%%       ⎢       ⎥
%%       ⎣0  0  0⎦
%% @end group
%% @end example
%%
%% @seealso{zeros, @@sym/ones, @@sym/eye}
%% @end defmethod

function y = zeros(varargin)

  % partial workaround for issue #13: delete when/if fixed properly
  if ((isa (varargin{nargin}, 'char')) && (strcmp (varargin{nargin}, 'sym')))
    varargin = varargin(1:(nargin-1));
  end

  if (isa (varargin{end}, 'char'))
    varargin = cell2nosyms (varargin);
    y = zeros (varargin{:});
    return
  end

  for i = 1:length(varargin)
    varargin{i} = sym(varargin{i});
  end
  if (length (varargin) == 1 && ~isscalar (varargin{1}))
    y = pycall_sympy__ ('return zeros(*_ins[0])', varargin{1});
  else
    y = pycall_sympy__ ('return zeros(*_ins)', varargin{:});
  end
end

%!test
%! y = zeros(sym(2));
%! x = [0 0; 0 0];
%! assert( isequal( y, sym(x)))

%!test
%! y = zeros(sym(2), 1);
%! x = [0; 0];
%! assert( isequal( y, sym(x)))

%!test
%! y = zeros(sym(1), 2);
%! x = [0 0];
%! assert( isequal( y, sym(x)))

%!test
%! y = zeros (sym([2 3]));
%! x = sym (zeros ([2 3]));
%! assert (isequal (y, x))

%% Check types:
%!assert( isa( zeros(sym(2), 'double'), 'double'))
%!assert( isa( zeros(3, sym(3), 'single') , 'single'))
%!assert( isa( zeros(3, sym(3)), 'sym'))
%!assert( isa( zeros(3, sym(3), 'sym'), 'sym'))

%!xtest
%! % Issue #13
%! assert( isa( zeros(3, 3, 'sym'), 'sym'))


%COPYMAKEBORDER  Forms a border around an image
%
%     dst = cv.copyMakeBorder(src, top, bottom, left, right)
%     dst = cv.copyMakeBorder(src, [top, bottom, left, right])
%     [...] = cv.copyMakeBorder(..., 'OptionName', optionValue, ...)
%
% ## Input
% * __src__ Source image.
% * __top__, __bottom__, __left__, __right__ Parameter specifying how many
%   pixels in each direction from the source image rectangle to extrapolate.
%   For example, `top=1`, `bottom=1`, `left=1`, `right=1` mean that 1
%   pixel-wide border needs to be built.
%
% ## Output
% * __dst__ Destination image of the same type as `src` and the size
%   `[size(src,1)+top+bottom, size(src,2)+left+right, size(src,3)]`.
%
% ## Options
% * __BorderType__ Border type, one of:
%   * __Constant__ `iiiiii|abcdefgh|iiiiiii` with some specified `i`
%   * __Replicate__ `aaaaaa|abcdefgh|hhhhhhh`
%   * __Reflect__ `fedcba|abcdefgh|hgfedcb`
%   * __Reflect101__ `gfedcb|abcdefgh|gfedcba`
%   * __Wrap__ `cdefgh|abcdefgh|abcdefg`
%   * __Default__ same as 'Reflect101' (default)
% * __Value__ Border value when `BorderType` is 'Constant'. default zeros
%
% The function copies the source image into the middle of the destination
% image. The areas to the left, to the right, above and below the copied
% source image will be filled with extrapolated pixels. This is not what
% filtering functions based on it do (they extrapolate pixels on-fly), but
% what other more complex functions, including your own, may do to simplify
% image boundary handling.
%
% See also: cv.borderInterpolate, padarray
%


% Sample codes for the task-related component analysis (TRCA)-based steady
% -state visual evoked potential (SSVEP) detection method [1]. The filter
% bank analysis [2] can also be combined to the TRCA-based algorithm.
%
% Dataset (sample.mat):
%   A 40-target SSVEP dataset recorded from a single subject. The stimuli
%   were generated by the joint frequency-phase modulation (JFPM) [3]
%     - Stimulus frequencies    : 8.0 - 15.8 Hz with an interval of 0.2 Hz
%     - Stimulus phases         : 0pi, 0.5pi, 1.0pi, and 1.5pi
%     - # of channels           : 9 (1: Pz, 2: PO5,3:  PO3, 4: POz, 5: PO4,
%                                    6: PO6, 7: O1, 8: Oz, and 9: O2)
%     - # of recording blocks   : 6
%     - Data length of epochs   : 5 [seconds]
%     - Sampling rate           : 250 [Hz]
%
% See also:
%   train_trca.m
%   test_trca.m
%   filterbank.m
%   itr.m
%
% Reference:
%   [1] M. Nakanishi, Y. Wang, X. Chen, Y.-T. Wang, X. Gao, and T.-P. Jung,
%       "Enhancing detection of SSVEPs for a high-speed brain speller using
%        task-related component analysis",
%       IEEE Trans. Biomed. Eng, 65(1): 104-112, 2018.
%   [2] X. Chen, Y. Wang, S. Gao, T. -P. Jung and X. Gao,
%       "Filter bank canonical correlation analysis for implementing a
%        high-speed SSVEP-based brain-computer interface",
%       J. Neural Eng., 12: 046008, 2015.
%   [3] X. Chen, Y. Wang, M. Nakanishi, X. Gao, T. -P. Jung, S. Gao,
%       "High-speed spelling with a noninvasive brain-computer interface",
%       Proc. Int. Natl. Acad. Sci. U. S. A, 112(44): E6058-6067, 2015.
%
% Masaki Nakanishi, 22-Dec-2017
% Swartz Center for Computational Neuroscience, Institute for Neural
% Computation, University of California San Diego
% E-mail: masaki@sccn.ucsd.edu

%% Clear workspace
clear all
close all
clc
help tutorial_trca

%% Set paths

addpath('../src');

%% Parameter for analysis (Modify according to your analysis)

% Filename
filename = '../data/sample.mat';

% Data length for target identification [s]
len_gaze_s = 0.5;

% Visual latency being considered in the analysis [s]
len_delay_s = 0.13;

% The number of sub-bands in filter bank analysis
num_fbs = 5;

% 1 -> The ensemble TRCA-based method, 0 -> The TRCA-based method
is_ensemble = 0;

% 100*(1-alpha_ci): confidence intervals
alpha_ci = 0.05;

%% Fixed parameter (Modify according to the experimental setting)

% Sampling rate [Hz]
fs = 250;

% Duration for gaze shifting [s]
len_shift_s = 0.5;

% List of stimulus frequencies
list_freqs = [8:1:15 8.2:1:15.2 8.4:1:15.4 8.6:1:15.6 8.8:1:15.8];

% The number of stimuli
num_targs = length(list_freqs);

% Labels of data
labels = [1:1:num_targs];

%% Preparing useful variables (DONT'T need to modify)

% Data length [samples]
len_gaze_smpl = round(len_gaze_s*fs);

% Visual latency [samples]
len_delay_smpl = round(len_delay_s*fs);

% Selection time [s]
len_sel_s = len_gaze_s + len_shift_s;

% Confidence interval
ci = 100*(1-alpha_ci);

%% Performing the TRCA-based SSVEP detection algorithm

fprintf('Results of the ensemble TRCA-based method.\n');

% Preparing data
load(filename);
[~, num_chans, ~, num_blocks] = size(eeg);
segment_data = len_delay_smpl+1:len_delay_smpl+len_gaze_smpl;
eeg = eeg(:, :, segment_data, :);

% Estimate classification performance
for loocv_i = 1:1:num_blocks

    % Training stage
    traindata = eeg;
    traindata(:, :, :, loocv_i) = [];
    model = train_trca(traindata, fs, num_fbs);

    % Test stage
    testdata = squeeze(eeg(:, :, :, loocv_i));
    estimated = test_trca(testdata, model, is_ensemble);

    % Evaluation
    is_correct = (estimated==labels);
    accs(loocv_i) = mean(is_correct)*100;
    itrs(loocv_i) = itr(num_targs, mean(is_correct), len_sel_s);
    fprintf('Trial %d: Accuracy = %2.2f%%, ITR = %2.2f bpm\n',...
        loocv_i, accs(loocv_i), itrs(loocv_i));

end % loocv_i

% Summarize
[mu, ~, muci, ~] = normfit(accs, alpha_ci);
fprintf('Mean accuracy = %2.2f %% (%2d%% CI: %2.2f - %2.2f %%)\n',...
    mu, ci, muci(1), muci(2));

[mu, ~, muci, ~] = normfit(itrs, alpha_ci);
fprintf('Mean ITR = %2.2f bpm (%2d%% CI: %2.2f - %2.2f bpm)\n\n',...
    mu, ci, muci(1), muci(2));


filename = 'CantileverSquareSmall';%'CantileverSquareNewFine';%'LshapeTriFine';%'CantileverSquareNew';'ArchTriFine';%'CantileverSquare';%'ArchTriFine';%'CantileverSquare';%'Lshape';%'LshapeTriFine';%'CantileverSquareSmall';%'';%'Lshape';'CantileverSquare';'Lshape';%'CantileverSquare';%'LshapeFine';%'Bridge_quad_coarse';%'Arch_quad_coarse';%'BridgeCool_Quadrilateral_Bilinear_Structured_Coarse';%'Bridge';%'CantileverSquareSmall';
ptype = 'MACRO';
initial_case = 'given';
m1 = 0.0101;
m2 = 0.0101;
%cost = {'compliance'};
cost = {'stressNorm'};
%cost = {'stressNorm','compliance'};
%weights = [0.55,0.45];
weights = 1;
constraint = {'volumeConstraint'};
filterType = 'P1';
constraint_case = 'EQUALITY';

Vfrac_initial = 0.3;
optimality_initial = 1e-5;
constr_initial = 1e-5;

Vfrac_final = 0.3;
optimality_final = 1e-5;
constr_final = 1e-5;

stressNormExponent_initial = 2;
stressNormExponent_final = 64;

optimizer = 'DualNestedInPrimal';
optimizerUnconstrained = 'PROJECTED GRADIENT';

designVariable = 'MicroParams';
ub = 0.989;
lb = 0.011;
homegenizedVariablesComputer = 'ByVademecum';
%
%vademecumFileName = 'SuperEllipseQMax';
%vademecumFileName = 'SuperEllipseQ2';
vademecumFileName = 'SuperEllipseQOptAnalytic';
%
% designVariable = 'Density';
% homegenizedVariablesComputer = 'ByInterpolation';
% method = 'SIMPALL';
% materialType = 'ISOTROPIC';

kfrac = 2;
nsteps = 250;

plotting = false;
printing = true;
monitoring = true;
monitoring_interval = 1;
maxiter = 5000;


function scale = GetScalingFactors(modelname)
%
% function scale = GetScalingFactors(modelname)
%
% Returns an array of scaling factors for the parameters of the model
% intended to rescale so that they all have value close to 1.
%
% Note that including the scaling factor for sigma increases the number
% of model variables by 1.
%
% Note that the scaling factor not set for theta and phi
%
% author: Gary Hui Zhang (gary.zhang@ucl.ac.uk)
%

parameterStrings = GetParameterStrings(modelname);

% here the scaling factors do not include the ones for theta and phi
% but include one for the sigma
scale = zeros(1, length(parameterStrings) - 1);

% the scaling factor for sigma is set to 1
scale(end) = 1;

for i=1:length(parameterStrings)
    if (strcmp(parameterStrings(i), 'di') ||...
            strcmp(parameterStrings(i), 'dh') ||...
            strcmp(parameterStrings(i), 'diso'))
        scale(i) = 1E9;
    elseif (strcmp(parameterStrings(i), 'rad'))
        scale(i) = 1E6;
    elseif (strcmp(parameterStrings(i), 'ficvf') ||...
            strcmp(parameterStrings(i), 'fiso') ||...
            strcmp(parameterStrings(i), 'irfrac') ||...
            strcmp(parameterStrings(i), 'psi') ||...
            strcmp(parameterStrings(i), 'b0') ||...
            strcmp(parameterStrings(i), 't1'))
        scale(i) = 1;
    elseif (strcmp(parameterStrings(i), 'kappa') ||...
            strcmp(parameterStrings(i), 'beta'))
        scale(i) = 0.1;
    end
end


% Gtomo2_wtfmex_test.m
% Test the Gtomo2_wtfmex object

if ~has_aspire
	return
end

% test new vewsion
if 1
	ig = image_geom('nx', 32, 'ny', 30, 'dx', 2);
	sg = sino_geom('par', 'nb', 40, 'na', 20, 'dr', 1.8);
	ig.mask = ig.circ(ig.fov/2) > 0;
	im(ig.mask)
	G = Gtomo2_wtmex(sg, ig, 'chat', 0, 'nthread', 2);
	Gtomo2_test(G, ig.mask) % put it through paces
	clear G
end

if ~isvar('G'),	printm 'setup Gtomo2_wtfmex_test'
	f.dir = test_dir;
	f.dsc = [f.dir 't.dsc'];
	f.wtf = strrep(f.dsc, 'dsc', 'wtf');

	os_run(sprintf('wt -chat 0 dsc 2 >! %s', f.dsc))
	os_run(sprintf('echo y | wt -chat 0 gen %s', f.dsc))

	G = Gtomo2_wtfmex(f.wtf);
	im(331, G.mask, 'mask')
prompt
end

if 1,	printm 'basic tests'
	x = G.mask;
	y = reshape(G * x(:), G.nb, G.na);
	im(332, y)

	y = ones(G.nb, G.na);
	x = reshape(G' * y(:), G.nx, G.ny);
	im(333, x, 'x'), cbar

	x2 = reshape((G.^2)' * y(:), G.nx, G.ny);
	im(337, x2, 'x2'), cbar

	t = reshape(G(:,2718), G.nb, G.na);
	im(334, t)

	t = reshape(G(:,[2718 2710]), [G.nb G.na 2]);
	im(335, t)

	t = reshape(G([202 210],:), [G.nx G.ny 2]);
	im(336, t)
prompt
end

if 1, printm 'adjoint test'

	os_run(sprintf('wt -chat 0 dsc 2 nx 12 ny 14 nb 16 na 10 >! %s', f.dsc))
	os_run(sprintf('echo y | wt -chat 0 gen %s', f.dsc))
	G = Gtomo2_wtfmex(f.wtf);
	test_adjoint(G);
	clear G
end


function [retransformed_irf_estimates]=favar_retransX_irf_estimates(irf_estimates,transformationindex,levels)
% number of variables and shocks, and iterations (It-Bu)
[n1,n2]=size(irf_estimates);
ItBu=1;
% initialise
retransformed_irf_estimates=cell(size(irf_estimates));
% different treatment for different cases
if levels==1 % only cum sum, also for second differences
    for oo=1:n1 % variables
        for ll=1:n2 % shocks
            for ii=1:3 %for up.,median,low.
                if transformationindex(oo)==1 %1: no transformation, Level
                    retransformed_irf_estimates{oo,ll}(ii,:)=irf_estimates{oo,ll}(ii,:);
                elseif transformationindex(oo)==2
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(irf_estimates{oo,ll}(ii,:),2); %2: First Difference
%                     retransformed_irf_estimates{oo,ll}(ii,:)=irf_estimates{oo,ll}(ii,:);
                elseif transformationindex(oo)==3
                    %retransformed_irf_record{oo,ll}(ii,:)=cumsum(irf_record{oo,ll}(ii,:),2);    %3: Second Difference
                    retransformed_irf_estimates{oo,ll}(ii,:)=irf_estimates{oo,ll}(ii,:);
                elseif transformationindex(oo)==4
                    %retransformed_irf_record{oo,ll}(ii,:)=irf_record{oo,ll}(ii,:);
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(irf_estimates{oo,ll}(ii,:))-ones(ItBu,1);       %4: Log-Level
                elseif transformationindex(oo)==5
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(irf_estimates{oo,ll}(ii,:),2); %5: Log-First-Difference
%                     retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(irf_estimates{oo,ll}(ii,:),2))-ones(ItBu,1); %5: Log-First-Difference
                elseif transformationindex(oo)==6
                    %retransformed_irf_record{oo,ll}(ii,:)=cumsum(irf_record{oo,ll}(ii,:),2); %6: Log-Second-Difference
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(irf_estimates{oo,ll}(ii,:),2))-ones(ItBu,1); %5: Log-First-Difference
                end
            end
        end
    end
elseif levels==2 % exp + cum sum
    for oo=1:n1 % variable
        for ll=1:n2 % shocks
            for ii=1:3 %for up.,median,low.
                if transformationindex(oo)==1 %1: no transformation, Level
                    retransformed_irf_estimates{oo,ll}(ii,:)=irf_estimates{oo,ll}(ii,:);
                elseif transformationindex(oo)==2
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(irf_estimates{oo,ll}(ii,:),2); %2: First Difference
                elseif transformationindex(oo)==3
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(irf_estimates{oo,ll}(ii,:),2);    % 6: Second Difference
                elseif transformationindex(oo)==4
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(irf_estimates{oo,ll}(ii,:))-ones(ItBu,1);       %4: Log-Level
                elseif transformationindex(oo)==5
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(irf_estimates{oo,ll}(ii,:),2))-ones(ItBu,1); %5: Log-First-Difference
                elseif transformationindex(oo)==6
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(irf_estimates{oo,ll}(ii,:),2))-ones(ItBu,1); %6: Log-Second-Difference
                end
            end
        end
    end
elseif levels==3 % exp + cum sum + cum sum for second differences types
    for oo=1:n1 % variables
        for ll=1:n2 % shocks
            for ii=1:3 %for up.,median,low.
                if transformationindex(oo)==1 %1: no transformation, Level
                    retransformed_irf_estimates{oo,ll}(ii,:)=irf_estimates{oo,ll}(ii,:);
                elseif transformationindex(oo)==2
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(irf_estimates{oo,ll}(ii,:),2); %2: First Difference
                elseif transformationindex(oo)==3
                    retransformed_irf_estimates{oo,ll}(ii,:)=cumsum(cumsum(irf_estimates{oo,ll}(ii,:),2),2);    % 6: Second Difference
                elseif transformationindex(oo)==4
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(irf_estimates{oo,ll}(ii,:))-ones(ItBu,1);       %4: Log-Level
                elseif transformationindex(oo)==5
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(irf_estimates{oo,ll}(ii,:),2))-ones(ItBu,1); %5: Log-First-Difference
                elseif transformationindex(oo)==6
                    retransformed_irf_estimates{oo,ll}(ii,:)=exp(cumsum(cumsum(irf_estimates{oo,ll}(ii,:),2),2))-ones(ItBu,1); %6: Log-Second-Difference
                end
            end
        end
    end

else % do nothing, e.g. levels=0
    retransformed_irf_estimates=irf_estimates;
end


function data = simulate_hinge(setup)

%This function simulates the hinge phase of the dynamics

%Set up the integration algorithm
Tspan = setup.Tspan;
IC = [setup.IC.th;
    setup.IC.dth];
eventFunc = @(t,z)events_hinge(t,z,setup.P);
options = odeset(...
    'RelTol',setup.tol,...
    'AbsTol',setup.tol,...
    'Vectorized','on',...
    'MaxStep',setup.odeMaxStep,...
    'Events',eventFunc);
userfun = @(t,z)dynamics_hinge(t,z,setup.P);

%Check that the event function is initially satisfied:
eventVal = feval(eventFunc,Tspan(1),IC);
if (sum(eventVal<0)>0) %IC violates constraints
    tspan = [Tspan(1), Tspan(1) + eps];
    nTime = 2;
    t = tspan;
    Z = IC*ones(1,2);
    [~, C, E] = dynamics_hinge(t,Z,setup.P);

    triggered = eventVal<0;
    index = 1:length(triggered);
    code = index(triggered);
    %Check that the number of possible transitions is one
    if length(code) >1
        disp('WARNING - multiple possible transitions!');
    end

else  %IC satisfied constraints

    %Run simulation
    sol = feval(setup.solver,userfun,Tspan,IC,options);

    %Format for post processing
    tspan = [sol.x(1),sol.x(end)];
    nTime = ceil(setup.dataFreq*diff(tspan));
    t = linspace(tspan(1),tspan(2),nTime);
    Z = deval(sol,t);
    [~, C, E] = dynamics_hinge(t,Z,setup.P);

    code = sol.ie;

end

%Store in a nice format for plotting
data.time = t;
data.state.th = Z(1,:);
data.state.dth = Z(2,:);
data.state.x = zeros(1,nTime) + setup.IC.x;
data.state.dx = zeros(1,nTime);
data.state.y = zeros(1,nTime) + setup.IC.y;
data.state.dy = zeros(1,nTime);
data.contact.h = C(1,:);
data.contact.v = C(2,:);
data.energy.potential = E(1,:);
data.energy.kinetic = E(2,:);
data.P = setup.P;

%Get transitions for finite state machine
data.phase = 'HINGE';
if isempty(code)
    data.exit = 'TIMEOUT';
else
    switch code(end)
        case 1
            data.exit = 'FALL_NEG';
        case 2
            data.exit = 'FALL_POS';
        case 3
            data.exit = 'LIFT';
        case 4
            data.exit = 'SLIP_NEG';
        case 5
            data.exit = 'SLIP_POS';
        otherwise
            error('Invalid exit condition in simulate hinge')
    end
end

end


function [KKTConstraints, details] = kkt(F,h,parametricVariables,ops);
%KKT Create KKT system
%
% [KKTConstraints, details] = kkt(Constraints,Objective,parameters)

if nargin == 2
    [KKTConstraints, details] = kkt(lmi(F),h);
elseif nargin==3
    [KKTConstraints, details] = kkt(lmi(F),h,parametricVariables);
else
    [KKTConstraints, details] = kkt(lmi(F),h,parametricVariables,ops);
end


load -ascii letter_A
load -ascii letter_T

[N, m] = size(letter_A)

class = N

app  = letter_A;size(app)
test = letter_T;size(test)

Napp = size(app,2);
Ntest = size(test,2);

unique(app(class,:))
unique(test(class,:))

ns1 = max(letter_A');
ns2 = max(letter_T');
ns = max(ns1,ns2)
clear letter_A letter_T ns1 ns2

% N, ns(class), Napp, Ntest, mean(ns),


function newBb = convertBb_X1Y1X2Y2_to_X1Y1WH( bb )
%convertBb_X1Y1X2Y2_to_X1Y1WH converts the bounding boxes from [X1,Y1,X2,Y2] format to [X1,Y1,W,H] format

numBb = size(bb, 1);

newBb = zeros(numBb, 4);

newBb(:, 1) = bb(:, 1);
newBb(:, 2) = bb(:, 2);
newBb(:, 3) = bb(:, 3) - bb(:, 1) + 1;
newBb(:, 4) = bb(:, 4) - bb(:, 2) + 1;

end


function [ X2 Y2 ] = LKTrackWrapper( imgseq,X1,Y1 )
% [ X2 Y2 ] = LKTrackWrapper( imgseq,X1,Y1 )
%	calls LKTrackPyr for each 2 neighboring frames in imgseq.
%	imgseq(M-by-N-by-F) are F grayscale images, it can be either from
%	a image sequence or a video(like from VideoReader).
%	if X1 and Y1 are not specified, function calls corner_ST to find
%	maxPtsNum corners. if X2 and Y2 are not required to output, function
%	will show these points in a figure. You should press a key to
%	start the show.

if nargin > 0 % image sequence or video
	[M N imgNum] = size(imgseq);
	maxPtsNum = 50;
	if ~exist('Y1','var')
		[Y1 X1] = corner_ST(imgseq(:,:,1),maxPtsNum);
		borderTh = 10;
		discard = Y1<borderTh | Y1>M-borderTh |...
			X1<borderTh | X1>N-borderTh; % discard points on the image border
		Y1 = Y1(~discard);
		X1 = X1(~discard);
	end

	X2 = zeros(length(X1),imgNum);
	Y2 = zeros(length(X1),imgNum);
	X2(:,1) = X1;
	Y2(:,1) = Y1;

	for p = 2:imgNum
		[X2(:,p) Y2(:,p)] = LKTrackPyr(imgseq(:,:,p-1),imgseq(:,:,p),...
			X2(:,p-1),Y2(:,p-1));
	end

	if nargout == 0
		figure,pause % show the points
		sc = min(M,N)/30; % scale of the line indicating the speed
		for p = 1:imgNum
			imshow(imgseq(:,:,p)),hold on
			X2p = X2(:,p); Y2p = Y2(:,p);
			plot(X2p,Y2p,'go');
			if p > 1 % draw speed lines
				plot([X2p,X2p+(X2p-X2pl)*sc]',...
					[Y2p,Y2p+(Y2p-Y2pl)*sc]','m-');
			end
			pause;
			X2pl = X2p; Y2pl = Y2p;
		end
	end

else % webcam, not finished

	vid = videoinput('winvideo',1); % specify your own name and index
	vid.TriggerRepeat = Inf;
	vid.FrameGrabInterval = 3;
	vid.ReturnedColorSpace='grayscale'; % 'rgb'
	figure
	while vid.FramesAcquired<=100
		data = getdata(vid,1);
		imshow(data);
		drawnow
	end
	stop(vid);
	delete(vid);

end