function res = vl_simplenn_globalModel(net, x, dzdy, res, varargin)
% VL_SIMPLENN  Evaluates a simple CNN
%   RES = VL_SIMPLENN(NET, X) evaluates the convnet NET on data X.
%   RES = VL_SIMPLENN(NET, X, DZDY) evaluates the convnent NET and its
%   derivative on data X and output derivative DZDY.
%
%   The network has a simple (linear) topology, i.e. the computational
%   blocks are arranged in a sequence of layers. Please note that
%   there is no need to use this wrapper, which is provided for
%   convenience. Instead, the individual CNN computational blocks can
%   be evaluated directly, making it possible to create significantly
%   more complex topologies, and in general allowing greater
%   flexibility.
%
%   The NET structure contains two fields:
%
%   - net.layers: the CNN layers.
%   - net.normalization: information on how to normalize input data.
%
%   The network expects the data X to be already normalized. This
%   usually involves rescaling the input image(s) and subtracting a
%   mean.
%
%   RES is a structure array with one element per network layer plus
%   one representing the input. So RES(1) refers to the zeroth-layer
%   (input), RES(2) refers to the first layer, etc. Each entry has
%   fields:
%
%   - res(i+1).x: the output of layer i. Hence res(1).x is the network
%     input.
%
%   - res(i+1).aux: auxiliary output data of layer i. For example,
%     dropout uses this field to store the dropout mask.
%
%   - res(i+1).dzdx: the derivative of the network output relative to
%     variable res(i+1).x, i.e. the output of layer i. In particular
%     res(1).dzdx is the derivative of the network output with respect
%     to the network input.
%
%   - res(i+1).dzdw: the derivative of the network output relative to
%     the parameters of layer i. It can be a cell array for multiple
%     parameters.
%
%   net.layers is a cell array of network layers. The following
%   layers, encapsulating corresponding functions in the toolbox, are
%   supported:
%
%   Convolutional layer::
%     The convolutional layer wraps VL_NNCONV(). It has fields:
%
%     - layer.type = 'conv'
%     - layer.weights = {filters, biases}
%     - layer.stride: the sampling stride (usually 1).
%     - layer.padding: the padding (usually 0).
%
%   Max pooling layer::
%     The max pooling layer wraps VL_NNPOOL(). It has fields:
%
%     - layer.type = 'pool'
%     - layer.method: pooling method ('max' or 'avg').
%     - layer.pool: the pooling size.
%     - layer.stride: the sampling stride (usually 1).
%     - layer.padding: the padding (usually 0).
%
%   Normalization layer::
%     The normalization layer wraps VL_NNNORMALIZE(). It has fields
%
%     - layer.type = 'normalize'
%     - layer.param: the normalization parameters.
%
%   Spatial normalization layer:
%     This is similar to the layer above, but wraps VL_NNSPNORM():
%
%     - layer.type = 'spnorm'
%     - layer.param: the normalization parameters.
%
%   Batch normalization layer:
%     This layer wraps VL_NNBNORM(). It has fields:
%
%     - layer.type = 'bnorm'
%     - layer.weights = {multipliers, biases}.
%
%   ReLU and Sigmoid layers::
%     The ReLU layer wraps VL_NNRELU(). It has fields:
%
%     - layer.type = 'relu'
%
%     The sigmoid layer is the same, but for the sigmoid function, with
%     `relu` replaced by `sigmoid`.
%
%   Dropout layer::
%     The dropout layer wraps VL_NNDROPOUT(). It has fields:
%
%     - layer.type = 'dropout'
%     - layer.rate: the dropout rate.
%
%   Softmax layer::
%     The softmax layer wraps VL_NNSOFTMAX(). It has fields
%
%     - layer.type = 'softmax'
%
%   Log-loss layer::
%     The log-loss layer wraps VL_NNLOSS(). It has fields:
%
%     - layer.type = 'loss'
%     - layer.class: the ground-truth class.
%
%   Softmax-log-loss layer::
%     The softmax-log-loss layer wraps VL_NNSOFTMAXLOSS(). It has
%     fields:
%
%     - layer.type = 'softmaxloss'
%     - layer.class: the ground-truth class.
%
%   P-dist layer:
%     The pdist layer wraps VL_NNPDIST(). It has fields:
%
%     - layer.type = 'pdist'
%     - layer.p = P parameter of the P-distance
%     - layer.noRoot = whether to raise the distance to the P-th power
%     - layer.epsilon = regularization parameter for the derivatives
%
%   Custom layer::
%     This can be used to specify custom layers.
%
%     - layer.type = 'custom'
%     - layer.forward: a function handle computing the block.
%     - layer.backward: a function handle computing the block derivative.
%
%     The first function is called as res(i+1) = forward(layer, res(i), res(i+1))
%     where res() is the struct array specified before. The second function is
%     called as res(i) = backward(layer, res(i), res(i+1)). Note that the
%     `layer` structure can contain additional fields if needed.

% Copyright (C) 2014 Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

opts.res = [] ;
opts.conserveMemory = false ;
opts.sync = false ;
opts.disableDropout = false ;
opts.freezeDropout = false ;
opts.accumulate = false;
opts.backPropDepth = +inf ;

opts = vl_argparse(opts, varargin);

n = numel(net.layers) ;

if (nargin <= 2) || isempty(dzdy)
    doder = false ;
else
    doder = true ;
end

gpuMode = isa(x, 'gpuArray') ;

if nargin <= 3 || isempty(res)
    res = struct(...
        'x', cell(1,n+1), ...
        'dzdx', cell(1,n+1), ...
        'dzdw', cell(1,n+1), ...
        'aux', cell(1,n+1), ...
        'time', num2cell(zeros(1,n+1)), ...
        'backwardTime', num2cell(zeros(1,n+1))) ;
end
res(1).x = x ;

for i=1:n
    l = net.layers{i} ;
    res(i).time = tic ;
    switch l.type
        case 'conv'
            res(i+1).x = vl_nnconv(res(i).x, l.weights{1}, l.weights{2}, 'pad', l.pad, 'stride', l.stride) ;
        case 'pool'
            res(i+1).x = vl_nnpool(res(i).x, l.pool, 'pad', l.pad, 'stride', l.stride, 'method', l.method) ;
        case 'normalize'
            res(i+1).x = vl_nnnormalize(res(i).x, l.param) ;
        case 'softmax'
            res(i+1).x = vl_nnsoftmax(res(i).x) ;
        case 'loss'
            res(i+1).x = vl_nnloss(res(i).x, l.class) ;
        case 'softmaxloss'
            res(i+1).x = vl_nnsoftmaxloss(res(i).x, l.class) ;
        case 'svmloss_multiclass'
            res(i+1).x = vl_nnsvmloss(res(i).x, l.class) ;
        case 'relu'
            res(i+1).x = vl_nnrelu(res(i).x) ;
        case 'sigmoid'
            res(i+1).x = vl_nnsigmoid(res(i).x) ;
        case 'noffset'
            res(i+1).x = vl_nnnoffset(res(i).x, l.param) ;
        case 'spnorm'
            res(i+1).x = vl_nnspnorm(res(i).x, l.param) ;
        case 'reshape'
            res(i+1).x = vl_nnreshape(res(i).x, [l.numOutput l.numClasses]);
        case 'dropout'
            if opts.disableDropout
                res(i+1).x = res(i).x ;
            elseif opts.freezeDropout
                [res(i+1).x, res(i+1).aux] = vl_nndropout(res(i).x, 'rate', l.rate, 'mask', res(i+1).aux) ;
            else
                [res(i+1).x, res(i+1).aux] = vl_nndropout(res(i).x, 'rate', l.rate) ;
            end
        case 'bnorm'
            if isfield(l, 'weights')
                res(i+1).x = vl_nnbnorm(res(i).x, l.weights{1}, l.weights{2}) ;
            else
                res(i+1).x = vl_nnbnorm(res(i).x, l.filters, l.biases) ;
            end
        case 'pdist'
            res(i+1) = vl_nnpdist(res(i).x, l.p, 'noRoot', l.noRoot, 'epsilon', l.epsilon) ;
        case 'custom'
            res(i+1) = l.forward(l, res(i), res(i+1)) ;
        otherwise
            error('Unknown layer type %s', l.type) ;
    end
    % optionally forget intermediate results
    forget = opts.conserveMemory ;
    forget = forget & (~doder || strcmp(l.type, 'relu')) ;
    forget = forget & ~(strcmp(l.type, 'loss') || strcmp(l.type, 'softmaxloss')) ;
    forget = forget & (~isfield(l, 'rememberOutput') || ~l.rememberOutput) ;
    if forget
        res(i).x = [] ;
    end
    if gpuMode & opts.sync
        % This should make things slower, but on MATLAB 2014a it is necessary
        % for any decent performance.
        wait(gpuDevice) ;
    end
    res(i).time = toc(res(i).time) ;
end

if doder
    res(n+1).dzdx = dzdy ;
    for i=n:-1:max(1, n-opts.backPropDepth+1)
        l = net.layers{i} ;
        res(i).backwardTime = tic ;
        switch l.type
            case 'conv'
                if ~opts.accumulate
                    [res(i).dzdx, res(i).dzdw{1}, res(i).dzdw{2}] = ...
                        vl_nnconv(res(i).x, l.weights{1}, l.weights{2}, ...
                        res(i+1).dzdx, ...
                        'pad', l.pad, 'stride', l.stride) ;
                else
                    dzdw = cell(1,2) ;
                    [res(i).dzdx, dzdw{1}, dzdw{2}] = ...
                        vl_nnconv(res(i).x, l.weights{1}, l.weights{2}, ...
                        res(i+1).dzdx, ...
                        'pad', l.pad, 'stride', l.stride) ;
                    for j=1:2
                        res(i).dzdw{j} = res(i).dzdw{j} + dzdw{j} ;
                    end
                    clear dzdw ;
                end

            case 'pool'
                res(i).dzdx = vl_nnpool(res(i).x, l.pool, res(i+1).dzdx, ...
                    'pad', l.pad, 'stride', l.stride, 'method', l.method) ;
            case 'normalize'
                res(i).dzdx = vl_nnnormalize(res(i).x, l.param, res(i+1).dzdx) ;
            case 'softmax'
                res(i).dzdx = vl_nnsoftmax(res(i).x, res(i+1).dzdx) ;
            case 'loss'
                res(i).dzdx = vl_nnloss(res(i).x, l.class, res(i+1).dzdx) ;
            case 'softmaxloss'
                res(i).dzdx = vl_nnsoftmaxloss(res(i).x, l.class, res(i+1).dzdx) ;
            case 'reshape'
                res(i).dzdx = vl_nnreshape(res(i).x, [l.numOutput l.numClasses], res(i+1).dzdx);
            case 'svmloss_multiclass'
                res(i).dzdx = vl_nnsvmloss(res(i).x, l.class, res(i+1).dzdx) ;
            case 'relu'
                if ~isempty(res(i).x)
                    res(i).dzdx = vl_nnrelu(res(i).x, res(i+1).dzdx) ;
                else
                    % if res(i).x is empty, it has been optimized away, so we use this
                    % hack (which works only for ReLU):
                    res(i).dzdx = vl_nnrelu(res(i+1).x, res(i+1).dzdx) ;
                end
            case 'sigmoid'
                res(i).dzdx = vl_nnsigmoid(res(i).x, res(i+1).dzdx) ;
            case 'noffset'
                res(i).dzdx = vl_nnnoffset(res(i).x, l.param, res(i+1).dzdx) ;
            case 'spnorm'
                res(i).dzdx = vl_nnspnorm(res(i).x, l.param, res(i+1).dzdx) ;
            case 'dropout'
                if opts.disableDropout
                    res(i).dzdx = res(i+1).dzdx ;
                else
                    res(i).dzdx = vl_nndropout(res(i).x, res(i+1).dzdx, 'mask', res(i+1).aux) ;
                end
            case 'bnorm'
                if ~opts.accumulate
                    if isfield(l, 'weights')
                        [res(i).dzdx, res(i).dzdw{1}, res(i).dzdw{2}] = ...
                            vl_nnbnorm(res(i).x, l.weights{1}, l.weights{2}, ...
                            res(i+1).dzdx) ;
                    else
                        [res(i).dzdx, res(i).dzdw{1}, res(i).dzdw{2}] = ...
                            vl_nnbnorm(res(i).x, l.filters, l.biases, ...
                            res(i+1).dzdx) ;
                    end
                else
                    dzdw = cell(1,2) ;
                    if isfield(l, 'weights')
                        [res(i).dzdx, dzdw{1}, dzdw{2}] = ...
                            vl_nnbnorm(res(i).x, l.weights{1}, l.weights{2}, ...
                            res(i+1).dzdx) ;
                    else
                        [res(i).dzdx, dzdw{1}, dzdw{2}] = ...
                            vl_nnbnorm(res(i).x, l.filters, l.biases, ...
                            res(i+1).dzdx) ;
                    end
                    for j=1:2
                        res(i).dzdw{j} = res(i).dzdw{j} + dzdw{j} ;
                    end
                    clear dzdw ;
                end
            case 'pdist'
                res(i).dzdx = vl_nnpdist(res(i).x, l.p, res(i+1).dzdx, ...
                    'noRoot', l.noRoot, 'epsilon', l.epsilon) ;
            case 'custom'
                res(i) = l.backward(l, res(i), res(i+1)) ;
        end
        if opts.conserveMemory
            res(i+1).dzdx = [] ;
        end
        if gpuMode & opts.sync
            wait(gpuDevice) ;
        end
        res(i).backwardTime = toc(res(i).backwardTime) ;
    end
end


function B = biharm(f)
%BIHARM   Biharmonic operator applied to a CHEBFUN3.
%   B = BIHARM(F) returns a CHEBFUN3 object B representing the biharmonic
%   operator applied to a CHEBFUN3 object F.
%
%   This is shorthand for BIHARMONIC(F).
%
% See also CHEBFUN3/BIHARMONIC.

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

% Call Biharmonic:
B = biharmonic(f);

end


function gui_components(rval_space,rval_time,max_pr,sizeA,A,Cn,options)

        figure;CC = plot_contours(A,Cn,options,0); title('Selected components','fontweight','bold','fontsize',14); close all;

        plt_cont = @(x) plot_contours(A,Cn,options,0,[],CC,[],x);

        d1 = options.d1;
        d2 = options.d2;

        figure;
            screensize = get(0,'Screensize' );
            fac = min(min((screensize(3:4)-200)./[2*d2,1.2*d1]),10);
            fig_size = round([100 100 fac*2*d2 fac*1.2*d1]);
            set(gcf, 'Position', fig_size);

            imagesc(Cn); axis equal; axis tight; axis off;
                set(gca,'Position',[0.01,0.1,0.5,0.8]);

        thr_space = @(x,y,z,w,v) find((rval_space >= x) & (rval_time >= y) & (sizeA >= z) & (sizeA < w) & (log(1-max_pr) < v));

        hsl1 = uicontrol('Style','slider','Min',0,'Max',1,...
                        'SliderStep',[0.01,0.01],'Value',options.space_thresh,'Tag','space_corr',...
                        'Position',[round(0.55*fig_size(3)) 50 20 round(0.85*fig_size(4))]);
        txt1 = uicontrol('Style','text','Position',[round(0.55*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String','space threshold' );
        %ved1 = uicontrol('Style','edit','Position',[round(0.55*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String',['val=',num2str(x1)] );

        hsl2 = uicontrol('Style','slider','Min',0,'Max',1,...
                        'SliderStep',[0.01,0.01],'Value',options.time_thresh,'Tag','time_corr',...
                        'Position',[round(0.6*fig_size(3)) 50 20 round(0.85*fig_size(4))]);
        txt2 = uicontrol('Style','text','Position',[round(0.6*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String','time threshold' );

        hsl3 = uicontrol('Style','slider','Min',0,'Max',120,...
                        'SliderStep',[0.01,0.01],'Value',options.min_size_thr,'Tag','min_size',...
                        'Position',[round(0.65*fig_size(3)) 50 20 round(0.85*fig_size(4))]);
        txt3 = uicontrol('Style','text','Position',[round(0.65*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String','minimum size' );

        hsl4 = uicontrol('Style','slider','Min',0,'Max',500,...
                        'SliderStep',[.01,.05],'Value',options.max_size_thr,'Tag','max_size',...
                        'Position',[round(0.7*fig_size(3)) 50 20 round(0.85*fig_size(4))]);

        txt4 = uicontrol('Style','text','Position',[round(0.7*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String','maximum size' );

        hsl5 = uicontrol('Style','slider','Min',-10,'Max',0,...
                        'SliderStep',[0.01,0.01],'Value',log10(1-options.max_pr_thr),'Tag','max_pr',...
                        'Position',[round(0.75*fig_size(3)) 50 20 round(0.85*fig_size(4))]);

        txt5 = uicontrol('Style','text','Position',[round(0.75*fig_size(3))-50 50+round(0.85*fig_size(4)) 100 50],'String','log(1-max_pr)' );

        pb = uicontrol('Style','pushbutton','Callback',@close_Callback);

        set(hsl1,'Callback',@(hObject,eventdata) plt_cont(thr_space(get(hObject,'Value'),hsl2.Value,hsl3.Value,hsl4.Value,hsl5.Value)))
        set(hsl2,'Callback',@(hObject,eventdata) plt_cont(thr_space(hsl1.Value,get(hObject,'Value'),hsl3.Value,hsl4.Value,hsl5.Value)))
        set(hsl3,'Callback',@(hObject,eventdata) plt_cont(thr_space(hsl1.Value,hsl2.Value,get(hObject,'Value'),hsl4.Value,hsl5.Value)))
        set(hsl4,'Callback',@(hObject,eventdata) plt_cont(thr_space(hsl1.Value,hsl2.Value,hsl3.Value,get(hObject,'Value'),hsl5.Value)))
        set(hsl5,'Callback',@(hObject,eventdata) plt_cont(thr_space(hsl1.Value,hsl2.Value,hsl3.Value,hsl4.Value,get(hObject,'Value'))))

%     function close_Callback(hObject, eventdata)
%
%             close all;
%     end

end


function [h,s,v] = hsl2hsv(hh,ss,ll)

h = hh;
ll = ll*2;

ind = ll <= 1;
ss(ind) = ss(ind) .* ll(ind);
ss(~ind) = ss(~ind) .* (2 - ll(~ind));

v = (ll + ss) ./ 2;
s = (2 * ss) ./ (ll + ss);
s(isnan(s)) = 0;

end

% r = linspace(1,2,30);
% omega = linspace(0,2*pi);
% [r,omega] = meshgrid(r,omega);
% x = r .* cos(omega);
% y = r .* sin(omega);
% z = zeros(size(r));
% rgb = hsv2rgb(omega./2./pi,ones(size(omega)),ones(size(omega)));
% surf(x,y,z,rgb)
% axis equal


function Ctrans = transformCost(C,u,v,neg)
%%
% Ctrans = transformCost(C,u,v,neg)
%
% Compute Ctrans = C - (u1' + 1v)
%
% -----------------------------------------------------------
% author: Sebastien Bougleux
% institution: Normandie Univ, CNRS - ENSICAEN - UNICAEN, GREYC
% -----------------------------------------------------------
% This file is part of LSAPE.
% LSAPE is free software: you can redistribute it and/or modify
% it under the terms of the CeCILL-C License. See README file
% for more details.
% -----------------------------------------------------------

    [n,m] = size(C);
    Ctrans = C - (repmat(u,1,m) + repmat(v,n,1));

    if exist('neg','var') && neg
        idxs = C < 0;
        Ctrans(idxs) = C(idxs);
    end

end


function parPath = er_deconvolvedParfile(view, stim, params);
%
% parPath = er_deconvolvedParfile(view, <stim>, <params>);
%
% Create a parfile representing the deconvolved time courses
% from a GLM. The format the data are stored in is alternating
% beta values and residual variance from the GLM, each taking
% [nh] time points, where nh is the number of temporal frames in the
% estimated hemodynamic response. (This should correspond to the number of
% MR frames contained within the event-related 'timeWindow' parameter.
%
% stim: stim/'trials' struct loaded from er_concatParfiles for the
%       source scans from the deconvolution.
% params: event-related parameters from the source scans for the
%       deconvolution.
% <default: get stim / params from the view's current scan group.>
%
% ras, 02/2006.
if notDefined('view'),      view = getSelectedInplane;          end
if notDefined('stim'),      stim = er_concatParfiles(view);     end
if notDefined('params'),    params = er_getParams(view);        end

tr = params.framePeriod;
frameWindow = unique(round(params.timeWindow/tr));
nh = length(frameWindow);
nConds = sum(stim.condNums>=1);

% construct the par struct
par.cond = [1:nConds 0];
par.onset = 0:2*nh:2*nh*nConds;
par.label = stim.condNames([2:nConds+1 1]);
par.color = stim.condColors([2:nConds+1 1]);

% write out the parfile
mrGlobals
dt = existDataType('Deconvolved');
if dt==0,
    scan = 1;
else
    scan = length(dataTYPES(dt).scanParams); % assume last deconvolved scan
end
parFileName = sprintf('deconvolved_scan%i.par', scan);
parPath = fullfile(parfilesDir(view), parFileName);
writeParfile(par, parPath);

return


function [l,c]=count(a);
%
% function [l,c]=count(a);
%
% INPUT:
%
% a : sorted list of doubles
%
% OUTPUT:
%
% l : sorted list of doubles with only unique elements
% c : count how many times each element appears
%
% EXAMPLE:
%
% [l,c]=count([1 1 2 2 3 3 3 4 5 5]);
%
% l=1 2 3 4 5
% c=2 2 3 1 2
%
%
% copyright 2005 by Kilian Q. Weinberger
% University of Pennsylvania
% kilianw@seas.upenn.edu
% ********************************************

error('not yet implemented!\n\n\n');
[l,index]=unique(a(1,:));
l=a(:,index);
c=[index(1) diff(index)];


clear

[solversToUse] = prepareTest('requireOneSolverOf',{'gurobi','ibm_cplex'});

printLevel=1;
solverOK = changeCobraSolver('ibm_cplex','LP');
modelToLoad='Recon3DModel_301';
%modelToLoad='ecoli_core_model';

switch modelToLoad
    case 'ecoli_core_model'
        load('ecoli_core_model')
    case 'Recon3DModel_301'
        load('Recon3DModel_301.mat')

    case 'Recon3D'
        load('Recon3D_301.mat')
        model = Recon3D;
    case 'Recon2betaModel'
        %graphStoich/data/modelCollection/121114_Recon2betaModel.mat
        load 121114_Recon2betaModel.mat
        model=modelRecon2beta121114;
    case 'KEGGMatrix'
        load ~/work/modeling/projects/graphStoich/data/modelCollectionBig/KEGGMatrix.mat
        model=KEGG;
end

if 1
    %[SConsistentMetBool, SConsistentRxnBool, SInConsistentMetBool, SInConsistentRxnBool, unknownSConsistencyMetBool, unknownSConsistencyRxnBool, model, stoichConsistModel] = findStoichConsistentSubset(model, massBalanceCheck, printLevel, fileName, epsilon)
    [SConsistentMetBool, SConsistentRxnBool, SInConsistentMetBool, SInConsistentRxnBool, unknownSConsistencyMetBool, unknownSConsistencyRxnBool, model, stoichConsistModel] = findStoichConsistentSubset(model,0,1);
    if strcmp(modelToLoad,'Recon3DModel_301')
        % load('Recon3DModel_301.mat') should be fully stoichiometrically
        % consistent
        assert(nnz(SConsistentMetBool)==5835)
        assert(nnz(SConsistentRxnBool)==8791)
        assert(nnz(SInConsistentMetBool)==0)
        assert(nnz(SInConsistentRxnBool)==1809)
        assert(nnz(unknownSConsistencyMetBool)==0)
        assert(nnz(unknownSConsistencyRxnBool)==0)
    end
else

    %finds the exchange reactions
    model=findSExRxnInd(model);

    [nMet,nIntRxn]=size(model.S(:,model.SIntRxnBool));
    m=sparse(nMet,15);
    i=1;

    if 1
        if 1
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='gurobi5';
            method.param.Method=1;
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 1
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='gurobi5';
            method.param.Method=2;
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 1
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='gurobi5';
            method.param.Method=3;
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 1
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='gurobi5';
            method.param.Method=4;
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 0
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='mosek_linprog';
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 0
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='mosek';
            method.param.MSK_IPAR_OPTIMIZER='MSK_OPTIMIZER_PRIMAL_SIMPLEX';
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 0
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='mosek';
            method.param.MSK_IPAR_OPTIMIZER='MSK_OPTIMIZER_DUAL_SIMPLEX';
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
            i=i+1;
        end

        if 0 %still debugging this solve with Erling @ Mosek
            %by default, the check for stoichiometric consistency omits the columns
            %of S corresponding to exchange reactions
            clear method
            method.interface='solveCobraLP';
            method.solver='mosek';
            method.param.MSK_IPAR_OPTIMIZER='MSK_OPTIMIZER_INTPNT';
            printLevelZ=3;
            [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevelZ,method);
            i=i+1;
        end
    end

    if 1
        clear method
        method.interface='solveCobraLP';
        method.solver='ibm_cplex';
        [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel+1,method);
        i=i+1;
    end

    if 0
        clear method
        method.interface='solveCobraLP';
        method.solver='pdco';
        [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel+1,method);
        i=i+1;
    end

    if 0
        clear method
        method.interface='cvx';
        method.solver='gurobi';
        [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
        i=i+1;
    end

    if 0
        clear method
        method.interface='cvx';
        method.solver='mosek';
        [inform(i),m(:,i),models{i}]=checkStoichiometricConsistency(model,printLevel,method);
        i=i+1;
    end

    m=full(m);

end


function trueFalse = is2DData( Data )
%
% Purpose : Tests if the input argument represents valid 2D homogeneous
% coordinates.
%
% Uses (syntax) :
%   is2DData( Data )
%
% Input Parameters :
%   Data := the variable to be tested (should be 3xn, n greater than 0)
%
% Return Parameters :
%   trueFalse := 0 or 1 (false or true)
%
% Description and algorithms:
%   Tests the size of the input argument
%
% References :
%
% Cite this as :
%
% Author : Matthew Harker
% Date : July 13, 2005
% Version : 1.0
%--------------------------------------------------------------------------
% (c) 2005, O'Leary, Harker, University of Leoben, Leoben, Austria
% email: automation@unileoben.ac.at, url: automation.unileoben.ac.at
%--------------------------------------------------------------------------
% History:
%   Date:           Comment:
%   July 13, 2005   Original Version 1.0
%--------------------------------------------------------------------------
%
[m,n] = size( Data ) ;
%
if (m == 3) & (n > 0)
    %
    trueFalse = 1 ;
    %
else
    %
    trueFalse = 0 ;
    %
end


classdef SO3FunHandle < SO3Fun
% a class representing a function on the rotation group by an function
% handle
%
% Syntax
%   SO3F = SO3FunHandle(fun)
%
% Input
%  fun - @function_handle
%
% Output
%  SO3F - @SO3FunHandle
%
% Example
%
%   r = orientation.rand;
%   SO3F = SO3FunHandle(@(rot) angle(rot,r))
%
properties
  fun
  % TODO: antipodal wird weder erkannt noch gesetzt/verwendet
  antipodal = false
  SLeft  = specimenSymmetry
  SRight = specimenSymmetry
  bandwidth = 96
end

methods
  function SO3F = SO3FunHandle(fun,varargin)

    SO3F.fun = fun;

    [SRight,SLeft] = extractSym(varargin);
    SO3F.SRight = SRight;
    SO3F.SLeft = SLeft;

  end

  function f = eval(SO3F,rot,varargin)

%     if isa(rot,'orientation')
%       ensureCompatibleSymmetries(SO3F,rot)
%     end

    s = size(rot);
    rot = rot(:);
    f = SO3F.fun(rot);
    if numel(f)==length(rot)
      f = reshape(f,s);
    end
    if isalmostreal(f)
      f = real(f);
    end
  end

end

methods (Static = true)

  SO3F = example(varargin)

end

end


function [newFluenceMap rowLeafPositions] = mergeFluenceMap(inflMap, rowLeafPositions, resolution);
% JC Sept 18, 2007
% ALG: For each pixel, search the 8 neighbors, merge them, if the change of
% the intensity is less than the threshold.

% General flow:
% Step, group the inter-leaf leakage part, i.e.
%type A: interleaf leakage part, with width 1mm.
%type B: the full leaf width, eg. 0.5cm or 1cm

% How to distinguish them?
% At the first column, check the gradient.
%

% The first colume of inflMap
% Do not use, since the
% s = diff(inflMap(:,1));

% Why s = diff(inflMap(:,2)) is always zero?
% The second colume of inflMap
% s = diff(inflMap(:,2));
% Use first column. Worked for both "bar pattern" and the "complimental bar
% pattern"
s = diff(inflMap(:,1));

newFluenceMap = struct('width', [], 'intensity', []);

newRow = 1;
y=0;

widthLeaf = 5/resolution;       % The width of the MLC leaf is 5mm. (Should work for 10mm=1cm leaf width)
% Havent' tried on resolution = 0.5mm.
iStart = mod(size(inflMap,1), widthLeaf)+1;
newFluenceMap(newRow).width = iStart-1;    %mm
newFluenceMap(newRow).intensity = inflMap(1+1,:);  % second row.

for i = iStart: length(s),
    if (s(i) ~= 0)
        newRow = newRow + 1;
        newFluenceMap(newRow).width = resolution;
        newFluenceMap(newRow).intensity = inflMap(i+1,:);
    else
        if (i == iStart)
            newRow = newRow + 1;
            newFluenceMap(newRow).width = resolution;
        end
        newFluenceMap(newRow).width = newFluenceMap(newRow).width + resolution;
        newFluenceMap(newRow).intensity = inflMap(i+1,:);
    end
end

y = 0;
rowLeafPositions = zeros(size(newFluenceMap,2)+1,1);
rowLeafPositions(1) = y+1;
for i=1:length(newFluenceMap)
    % Following works for resolution == 1.
    % y =y+newFluenceMap(i).width;
    y =y+newFluenceMap(i).width/resolution;
    rowLeafPositions(i+1) = y+1;
end

[Ncol Nrow] = size(inflMap);

% for i = 1 : Nrow,
figure;hAxis1 = axes;imagesc(inflMap);
set(gcf, 'renderer', 'zbuffer')
figure;hAxis2 = axes;hold on;
set(gcf, 'renderer', 'zbuffer')
xL = get(hAxis1, 'xlim');
yL = get(hAxis1, 'ylim');
set(hAxis2, 'xlim', xL);
set(hAxis2, 'ylim', yL);
axis(hAxis2, 'manual');
%     w_colors = floor((w_field ./ max(w_field))*255)+1;
%set(gcf, 'doublebuffer', 'on');

%y=0.05; %(?)
y=0;
for i=1:length(newFluenceMap)
    % Following works for resolution == 1.
    % y =y+newFluenceMap(i).width;
    y =y+newFluenceMap(i).width/resolution;
    for j=1:length(newFluenceMap(i).intensity)
% The display scheme here is problematic. To be worked on.
        patch([xL(1) xL(1) xL(2) xL(2) xL(1)], [y-newFluenceMap(i).width/resolution y y y-newFluenceMap(i).width/resolution y-newFluenceMap(i).width/resolution], newFluenceMap(i).intensity(j));
    end
end
axis([hAxis1 hAxis2], 'ij');
kids = get(hAxis2, 'children');
%     set(kids, 'edgecolor', 'none');
cMap = colormap('jet');
set(hAxis2, 'color', cMap(1,:));

return;


function [ y, m, ierror ] = ym_check_islamic ( y, m )

%*****************************************************************************80
%
%% YM_CHECK_ISLAMIC checks an Islamic YM date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y, M, the YM date.
%
%    Output, integer IERROR, is 0 if no error was found in the date
%    and 1 otherwise.
%

%
%  Check the year.
%
  [ y, ierror ] = y_check_islamic ( y );

  if ( ierror ~= 0 )
    return
  end
%
%  Make sure the month isn't too small or too big.
%
  [ y, m ] = month_borrow_islamic ( y, m );

  [ y, m ] = month_carry_islamic ( y, m );

  return
end


% File Name: checkValidity.m
% Author: Heung-Il Suk
% Cite: H.-I. Suk and S.-W. Lee, "A Novel Bayesian Framework for Discriminative
% Feature Extraction in Brain-Computer Interfaces," IEEE Trans. on PAMI,
% 2012. (Accepted)

function sample = opt_checkValidity( sample )
% We enforce the samples to be within min_freq and max_freq

min_freq = 0.05;
max_freq = 40;

if sample(1) <= min_freq
    sample(1) = min_freq;
end

if sample(2) <= min_freq
    sample(2) = min_freq;
end

if sample(1) > max_freq
    sample(1) = max_freq;
end

if sample(2) > max_freq
    sample(2) = max_freq;
end

if sample(1) > sample(2)
    temp = sample(2);
    sample(2) = sample(1);
    sample(1) = temp;
end

if (sample(1) - sample(2)) < 1
    sample(1) = sample(1);
    sample(2) = sample(2) + 0.5;
end


% CONFIGSTATEMACHINE configures the state machine (type of demo, velocity
%                    of the demo, repeat movements, and so on).

%% --- Initialization ---

% If true, the robot CoM will follow a desired reference trajectory (COORDINATOR DEMO ONLY)
Config.LEFT_RIGHT_MOVEMENTS = false;

% If equal to one, the desired values of the center of mass are smoothed internally
Config.SMOOTH_COM_DES       = true;

% If equal to one, the desired values of the postural tasks are smoothed internally
Config.SMOOTH_JOINT_DES     = true;

% Joint torques saturation [Nm]
Sat.torque                  = 60;

% Joint torques rate of change saturation
Sat.uDotMax                 = 300;

% max unsigned difference between two consecutive (measured) joint positions,
% i.e. delta_qj = abs(qj(k) - qj(k-1))
Sat.maxJointsPositionDelta  = 15*pi/180; % [rad]

%% Regularization parameters
Reg.pinvDamp_baseVel        = 1e-7;
Reg.pinvDamp                = 1;
Reg.pinvTol                 = 1e-5;
Reg.KP_postural             = 0.1;
Reg.KD_postural             = 0;
Reg.HessianQP               = 1e-7;

%% State Machine configuration

% time between two yoga positions
StateMachine.joints_pauseBetweenYogaMoves = 3;

% contact forces threshold
StateMachine.wrench_thresholdContactOn    = 25;
StateMachine.wrench_thresholdContactOff   = 85;

% threshold on CoM and joints error
StateMachine.CoM_threshold                = 0.01;
StateMachine.joints_thresholdNotInContact = 5;
StateMachine.joints_thresholdInContact    = 50;

% initial state for state machine
StateMachine.initialState                 = 1;

% other configuration parameters for state machine
StateMachine.tBalancing                   = 1;
StateMachine.tBalancingBeforeYoga         = 1;
StateMachine.skipYoga                     = false;
StateMachine.demoOnlyBalancing            = false;
StateMachine.demoStartsOnRightSupport     = false; % If false, the Yoga demo is performed on the left foot first
StateMachine.yogaAlsoOnRightFoot          = false; % TO DO: yoga on both feet starting from right foot (not available for now)

%%%% List of possible "Yoga in loop" %%%%

% the robot will repeat the FULL DEMO (two feet balancing, yoga on left
% foot, back on two feet, yoga right foot, back on two feet). The demo is
% repeated until the user stops the Simulink model. This option is ignored
% if Sm.demoStartsOnRightSupport = true.
StateMachine.twoFeetYogaInLoop            = false;

% the robot will repeat the ONE FOOT yoga for the number of times the user
% specifies in the Sm.yogaCounter option. The robot WILL NOT go back to two
% feet balancing in between to consecutive yoga. WARNING: if the option
% Sm.yogaAlsoOnRightFoot is true, then the robot will repeat first the yoga
% on left foot for the number of times the user specifies in the Sm.yogaCounter,
% and then it will repeat the yoga on the right foot for the same number of times.
StateMachine.oneFootYogaInLoop            = false;
StateMachine.yogaCounter                  = 5;

%% Parameters for motors reflected inertia

% transmission ratio (1/N)
Config.Gamma                 = 0.01*eye(ROBOT_DOF);

% modify the value of the transmission ratio for the hip pitch.
% TODO: avoid to hard-code the joint numbering
Config.Gamma(end-5, end-5)   = 0.0067;
Config.Gamma(end-11,end-11)  = 0.0067;

% motors inertia (Kg*m^2)
legsMotors_I_m               = 0.0827*1e-4;
torsoPitchRollMotors_I_m     = 0.0827*1e-4;
torsoYawMotors_I_m           = 0.0585*1e-4;
armsMotors_I_m               = 0.0585*1e-4;

% add harmonic drives reflected inertia
if Config.INCLUDE_HARMONIC_DRIVE_INERTIA

    legsMotors_I_m           = legsMotors_I_m + 0.054*1e-4;
    torsoPitchRollMotors_I_m = torsoPitchRollMotors_I_m + 0.054*1e-4;
    torsoYawMotors_I_m       = torsoYawMotors_I_m + 0.021*1e-4;
    armsMotors_I_m           = armsMotors_I_m + 0.021*1e-4;
end

Config.I_m                   = diag([torsoPitchRollMotors_I_m*ones(2,1);
                                     torsoYawMotors_I_m;
                                     armsMotors_I_m*ones(8,1);
                                     legsMotors_I_m*ones(12,1)]);

% parameters for coupling matrices. Updated according to the wiki:
%
% http://wiki.icub.org/wiki/ICub_coupled_joints
%
% and corrected according to https://github.com/robotology/robots-configuration/issues/39
t            = 0.615;
r            = 0.022;
R            = 0.04;

% coupling matrices
T_LShoulder  = [-1  0  0;
                -1 -t  0;
                 0  t -t];

T_RShoulder  = [ 1  0  0;
                 1  t  0;
                 0 -t  t];

T_torso      = [ 0.5    -0.5     0;
                 0.5     0.5     0;
                 r/(2*R) r/(2*R) r/R];

if Config.INCLUDE_COUPLING

    Config.T = blkdiag(T_torso,T_LShoulder,1,T_RShoulder,1,eye(12));
else
    Config.T = eye(ROBOT_DOF);
end

% gain for feedforward term in joint torques calculation. Valid range: a
% value between 0 and 1
Config.K_ff  = 0;

% Config.USE_DES_JOINT_ACC_FOR_MOTORS_INERTIA if true, the desired joints
% accelerations are used for computing the feedforward term in joint
% torques calculations. Not effective if Config.K_ff = 0.
Config.USE_DES_JOINT_ACC_FOR_MOTORS_INERTIA = false;

%% Constraints for QP for balancing

% The friction cone is approximated by using linear interpolation of the circle.
% So, numberOfPoints defines the number of points used to interpolate the circle
% in each cicle's quadrant
numberOfPoints               = 4;
forceFrictionCoefficient     = 1/3;
torsionalFrictionCoefficient = 1/75;
fZmin                        = 10;

% physical size of the foot
feet_size                    = [-0.05  0.10;     % xMin, xMax
                                -0.025 0.025];   % yMin, yMax

% Compute contact constraints (friction cone, unilateral constraints)
[ConstraintsMatrix, bVectorConstraints] = wbc.computeRigidContactConstraints ...
    (forceFrictionCoefficient, numberOfPoints, torsionalFrictionCoefficient, feet_size, fZmin);


close all;
clear all;
clc;

data_file_path = 'bin/mmv_phase_transition_noiseless_s_8.mat';
options.export = true;
options.export_dir = 'bin';
options.export_name = 'mmv_noiseless_s_8';
options.subtitle = 'Noiseless, S = 8';
options.chosen_ks = [2, 4, 8, 16, 32, 64];
spx.pursuit.PhaseTransitionAnalysis.print_results(data_file_path, ...
    'CoSaMP', options);


function fd1d_heat_implicit_test ( )

%*****************************************************************************80
%
%% FD1D_HEAT_IMPLICIT_TEST tests the FD1D_HEAT_IMPLICIT library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 January 2012
%
%  Author:
%
%    John Burkardt
%
  timestamp ( )
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_HEAT_IMPLICIT_TEST:\n' );
  fprintf ( 1, '  MATLAB version.\n' );
  fprintf ( 1, '  Test the FD1D_HEAT_IMPLICIT library.\n' );

  fd1d_heat_implicit_test01 ( );
  fd1d_heat_implicit_test02 ( );
  fd1d_heat_implicit_test03 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_HEAT_IMPLICIT_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function medit_io_test03 ( filename )

%*****************************************************************************80
%
%% MEDIT_IO_TEST03 reads and prints the sizes in a MESH dataset.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 October 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'MEDIT_IO_TEST03\n' );
  fprintf ( 1, '  Read a mesh file and print its sizes.\n' );

  [ dim, vertices, edges, triangles, quadrilaterals, tetrahedrons, ...
    hexahedrons ] = mesh_size_read ( filename );
%
%  Print information.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Header information for "%s":\n', filename );

  mesh_size_print ( dim, vertices, edges, triangles, quadrilaterals, ...
    tetrahedrons, hexahedrons );

  return
end


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

% Creates a Matlab array d0 for the absorbtion probability in the SABR
% model. It uses a csv file which can be downloaded via P. Dousts page
% mentioned in his RISK article "No-Arbitrage SABR"

n1 = length(sabrVol);
n2 = length(sabrbeta);
n3 = length(sabrrho);
n4 = length(sabrnu);
n5 = length(sabrtau);

d0 = zeros(n1,n2,n3,n4,n5);
xindex = 1;
for j2=1:n2
    for j4 = 1:n4
        for j3=1:n3
            for j1=1:n1
                for j5 = 1:n5
                    value = data(xindex,4 + j5);
                    d0(j1,j2,j3,j4,j5) =  value;
                end
                xindex = xindex+1;
            end
        end
    end
end

d0 = d0/2500000;


Wxkpixbg=reshape(Wxk*Hkt,peval.nx,peval.ny,peval.nt)+peval.bg;
resid=(Wxkpixbg-dpixc);
resid_norm=resid./Wxkpixbg;
rnm=mean(resid_norm,3);


function polar_info_esti = FastSCL_decoder(llr, L, info_bits, lambda_offset, llr_layer_vec, bit_layer_vec, psi_vec, node_type_matrix, H_crc)
%2018.1.7.14:16 Yu Y. R.
%LLR-based SCL deocoder
%Systematic polar code used
%4 nodes are identified and decoded, i.e., rate0, rate1, rep, spc,
%No BLER loss, while using fast algorithms.
%const
N = length(llr);
m = log2(N);
%memory declared
P = zeros(N - 1, L); %llr is public-used, so N - 1 is enough.
C = zeros(2 * N - 1, 2 * L);
PM = zeros(L, 1);
activepath = zeros(L, 1);
lazy_copy = zeros(m, L);
%initialize the 1st SC decoder
activepath(1) = 1;
lazy_copy(:, 1) = 1;
%decoding starts
%default: in the case of path clone in REP and leaf node,
%origianl always corresponds to bit 0s, while the new path bit 1s.
for i_node = 1 : size(node_type_matrix, 1)
    current_index = node_type_matrix(i_node, 1);
    llr_layer = llr_layer_vec(current_index);
    M = node_type_matrix(i_node, 2);%number of leaf nodes in this constituent node
    reduced_layer = log2(M); %For LLR recursion, this reduced layer denotes where to stop; For Bit recursion, this denotes where to start.
    psi = psi_vec(i_node);%This psi is used for bits recursion
    psi_mod_2 = mod(psi, 2);%To decide whether the bit recuision should continue. 1 : continue; 0 : stop.
    for l_index = 1 : L
        if activepath(l_index) == 0
            continue;
        end
        switch current_index
            case 1
                index_1 = lambda_offset(m);
                for beta = 0 : index_1 - 1
                    P(beta + index_1, l_index) = sign(llr(beta + 1)) *  sign(llr(beta + index_1 + 1)) * min(abs(llr(beta + 1)), abs(llr(beta + index_1 + 1)));
                end
                for i_layer = m - 2 : -1 : reduced_layer
                    index_1 = lambda_offset(i_layer + 1);
                    index_2 = lambda_offset(i_layer + 2);
                    for beta = index_1 : index_2 - 1
                        P(beta, l_index) = sign(P(beta + index_1, l_index)) *  sign(P(beta + index_2, l_index)) * ...
                            min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index)));
                    end
                end
            case N/2 + 1
                index_1 = lambda_offset(m);
                for beta = 0 : index_1 - 1
                    x_tmp = C(beta + index_1, 2 * l_index - 1);
                    P(beta + index_1, l_index) = (1 - 2 * x_tmp) * llr(beta + 1) + llr(beta + index_1 + 1);
                end
                for i_layer = m - 2 : -1 : reduced_layer
                    index_1 = lambda_offset(i_layer + 1);
                    index_2 = lambda_offset(i_layer + 2);
                    for beta = index_1 : index_2 - 1
                        P(beta, l_index) = sign(P(beta + index_1, l_index)) *  sign(P(beta + index_2, l_index)) * ...
                            min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index)));
                    end
                end
            otherwise
                index_1 = lambda_offset(llr_layer + 1);
                index_2 = lambda_offset(llr_layer + 2);
                for beta = index_1 : index_2 - 1
                    %lazy copy
                    P(beta, l_index) = (1 - 2 * C(beta, 2 * l_index - 1)) * P(beta + index_1, lazy_copy(llr_layer + 2, l_index)) + P(beta + index_2, lazy_copy(llr_layer + 2, l_index));
                end
                for i_layer = llr_layer - 1 : -1 : reduced_layer
                    index_1 = lambda_offset(i_layer + 1);
                    index_2 = lambda_offset(i_layer + 2);
                    for beta = index_1 : index_2 - 1
                        P(beta, l_index) = sign(P(beta + index_1, l_index)) *  sign(P(beta + index_2, l_index)) * ...
                            min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index)));
                    end
                end
        end
    end%LLR calculations. You may fold thiis code block.
    index_vec = M : 2 * M - 1;
    switch node_type_matrix(i_node, 3)
        case -1%****RATE 0*****
            x = zeros(M, 1);
            for l_index = 1 : L
                if activepath(l_index) == 0
                    continue;
                end
                C(index_vec, psi_mod_2 + 2 * l_index - 1) = x;
                PM(l_index) = PM(l_index) + sum(log(1 + exp(-P(index_vec, l_index))));
                %Do not forget updating path metric in rate 0 nodes
                %No copy in Rate 0 node
            end
        case 1%*****RATE 1*****
            %input LLR: P(index_vec, :)
            [PM, activepath, selected_subcodeword, lazy_copy] = Rate1(M, P(index_vec, :), activepath, PM, L, lazy_copy);
            %output: estimated sub polar codeword: 'selected_subcodeword'.
            for l_index = 1 : L
                if activepath(l_index) == 0
                    continue
                end
                C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index);
            end
        case 2%*****REP*****
           [PM, activepath, lazy_copy, selected_subcodeword] = Rep(PM, P(index_vec, :), activepath, L, M, lazy_copy);
           for l_index = 1 : L
               if activepath(l_index) == 0
                   continue
               end
               C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index);
           end
        case 3%*******SPC*******
            [PM, activepath, selected_subcodeword, lazy_copy] = SPC(index_vec, P(index_vec, :), activepath, PM, L, lazy_copy);
            for l_index = 1 : L
                if activepath(l_index) == 0
                    continue
                end
                C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index);
            end
    end
    %Internal Bits Update for each active path
    bit_layer = bit_layer_vec(current_index + M - 1);
    for l_index = 1 : L
        if activepath(l_index) == 0
            continue;
        end
        if psi_mod_2 == 1%right child of its mother
            for i_layer = reduced_layer : bit_layer - 1
                index_1 = lambda_offset(i_layer + 1);
                index_2 = lambda_offset(i_layer + 2);
                for beta = index_1 : index_2 - 1
                    C(beta + index_1, 2 * l_index) = mod(C(beta, 2 * lazy_copy(i_layer + 1, l_index) - 1) + C(beta, 2 * l_index), 2);
                    C(beta + index_2, 2 * l_index) = C(beta, 2 * l_index);
                end
            end
            index_1 = lambda_offset(bit_layer + 1);
            index_2 = lambda_offset(bit_layer + 2);
            for beta = index_1 : index_2 - 1
                C(beta + index_1, 2 * l_index - 1) = mod(C(beta, 2 * lazy_copy(bit_layer + 1, l_index) - 1) + C(beta, 2 * l_index), 2);
                C(beta + index_2, 2 * l_index - 1) = C(beta, 2 * l_index);
            end
        end
    end
    %lazy copy
    if i_node < size(node_type_matrix, 1)
        for i_layer = 1 : llr_layer_vec(current_index + M) + 1
            for l_index = 1 : L
                lazy_copy(i_layer, l_index) = l_index;
            end
        end
    end
end
%select the best path
[~, path_ordered] = sort(PM);
for l_index = 1 : L
    path_num = path_ordered(l_index);
    x = C(end - N + 1 : end, 2 * path_num - 1);
    info_with_crc = x(info_bits);
    err = sum(mod(H_crc * info_with_crc, 2));
    if err == 0
        polar_info_esti = info_with_crc;
        break;
    else
        if l_index == L
            x = C(end - N + 1 : end, 2 * path_ordered(1) - 1);
            polar_info_esti = x(info_bits);
        end
    end
end
end


function n = gqu_order ( l )

%*****************************************************************************80
%
%% GQU_ORDER computes the order of a GQU rule from the level.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 June 2012
%
%  Author:
%
%    John Burkardt.
%
%  Parameters:
%
%    Input, integer L, the level of the rule.
%    1 <= L.
%
%    Output, integer N, the order of the rule.
%
  if ( l < 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'GQU_ORDER - Fatal error!\n' );
    fprintf ( 1, '  1 <= L required.\n' );
    fprintf ( 1, '  Input L = %d\n', l );
    error (  'GQU_ORDER - Fatal error!' );
  elseif ( l <= 25 )
    n = l;
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'GQU_ORDER - Fatal error!\n' );
    fprintf ( 1, '  L <= 25 required.\n' );
    fprintf ( 1, '  Input L = %d\n', l );
    error (  'GQU_ORDER - Fatal error!' );
  end

  return
end


function [tempimg ]=displayout(Polyg,w,h,img)

r=[255 0 0 0 255 255 0];
g=[0 255 0 255 255 0 0];
b=[0 0 255 255 0 255 0];

rl=[0  0 0 255 255 255 0];
gl=[255 255 0 0 255 0 0];
bl=[0 255 255 0 0 255 0];

fields=zeros(h,w);
%1 floor
polyg=Polyg{1};
if numel(polyg)>0
    tempimg1=poly2mask(polyg(:,1),polyg(:,2),h,w);
else
    tempimg1=zeros(h,w);
end
fields=fields.*(fields~=0)+1*tempimg1.*(fields==0);

%2 middlewall

polyg=Polyg{2};
if numel(polyg)>0
    tempimg1=poly2mask(polyg(:,1),polyg(:,2),h,w);
else
    tempimg1=zeros(h,w);
end
fields=fields.*(fields~=0)+2*tempimg1.*(fields==0);
%3 right wall

polyg=Polyg{3};
if numel(polyg)>0
    tempimg1=poly2mask(polyg(:,1),polyg(:,2),h,w);
else
    tempimg1=zeros(h,w);
end
fields=fields.*(fields~=0)+3*tempimg1.*(fields==0);
%4 left wall

polyg=Polyg{4};
if numel(polyg)>0
    tempimg1=poly2mask(polyg(:,1),polyg(:,2),h,w);
else
    tempimg1=zeros(h,w);
end
fields=fields.*(fields~=0)+4*tempimg1.*(fields==0);
%
%5 ceiling

polyg=Polyg{5};
if numel(polyg)>0
    tempimg1=poly2mask(polyg(:,1),polyg(:,2),h,w);
else
    tempimg1=zeros(h,w);
end
fields=fields.*(fields~=0)+5*tempimg1.*(fields==0);

fields = fields.*(fields~=0) + 6*(fields==0);

mask_r = r(fields);
mask_g = g(fields);
mask_b = b(fields);
mask_color(:,:,1) = mask_r;
mask_color(:,:,2) = mask_g;
mask_color(:,:,3) = mask_b;

tempimg = double(img)*0.5 + mask_color*0.5;
% figure;
% imshow(uint8(tempimg),[]);

return


function [y]=tt_rc2(d,n,elem_fun,eps,varargin)
%[Y]=TT_RC2(D,N,ARR,ELEM_FUN,EPS,[OPTIONS])
%The TT-Renormalization-Cross algorithm
%input is: the dimension of the array d, the
%size vector n, the function that computes the prescribed element
%of an array, accuracy parameter eps
%and also additional arguments specified as 'rmax',10,'nswp',10
%'verb',true and so on
% 'x0', x0
%The elem function has syntax elem_fun(ind); all other additional
%information
%has to be passed as "anonymous" arguments

%The algorithm. It needs left & right index sets to be initialized.
%It needs supecores to be precomputed
%It is a good idea to store also the supercores (there will be d-1,
%i think) & update them; also certain indices maybe removed from the
%index set?? we will not do that;
%Two possibilities: current index contains maxvol submatrix;
%If not, increase, increase & increase (maybe even beyond the rank!)
%rank one subtraction can be made very stable

%Default parameters
if ( numel(n) == 1 )
  n=n*ones(1,d);
end
nswp=10;
rmax=1000;
x0=[];
verb=true;
vec=false; %If there is a vectorization in options, i.e. if elem_fun
%supports vectorized computations of many elements at once
for i=1:2:length(varargin)-1
    switch lower(varargin{i})
        case 'nswp'
            nswp=varargin{i+1};
        case 'rmax'
            rmax=lower(varargin{i+1});
        case 'x0'
            x0=varargin{i+1};
        case 'verb'
            verb=varargin{i+1};
        case 'vec'
            vec=varargin{i+1};
        otherwise
            error('Unrecognized option: %s\n',varargin{i});
    end
end

%The initial setup is done.

%We need initial index sets. Say, the vector of all ones (he-he)
%i_left;
%r_left;
%i_right;
%r_right;
i_left=cell(d,1);
i_right=cell(d,1);
r_left=cell(d,1);
r_right=cell(d,1);
ry=ones(d+1,1); %Initial ranks
%Find fiber maximum
ind=2*ones(d,1);
ind=find_fiber_maximum(elem_fun,ind);
for i=1:d
  i_left{i}=ind(i);
  i_right{i}=ind(i);
  r_left{i}=1;
  r_right{i}=1;
end

%Before we get the multiindex sets (helps to compute s-u-p-e-r-c-o-r-e-s)

ind_left=get_multi_left(i_left,r_left,ry);
ind_right=get_multi_right(i_right,r_right,ry);

%Now we have to compute s-u-p-e-r-c-o-r-e-s (not cores!) using ind_left &
%ind_right
super_core=cell(d-1,1);
for i=1:d-1 %There are d-1 s-u-p-e-r-c-o-r-e-s
   %Compute the index set for the i-th one
   index_set=zeros(d,ry(i),n(i),n(i+1),ry(i+2));
   if ( i == 1 )
       ileft=zeros(1,0);
   else
      ileft=ind_left{i-1};
   end
   if ( i == d - 1 )
      iright = zeros(1,0);
   else
      iright=ind_right{i+2};
   end
   for s1=1:ry(i)
      for s2=1:ry(i+2)
        for i1=1:n(i)
           for i2=1:n(i+1)
              index_set(:,s1,i1,i2,s2)=[ileft(s1,:),i1,i2,iright(s2,:)];
           end
        end
      end
   end
   M=ry(i)*n(i)*n(i+1)*ry(i+2);
   index_set=reshape(index_set,[d,M]);
   if ( vec )
      super_core{i}=reshape(elem_fun(index_set),[ry(i),n(i),n(i+1),ry(i+2)]);
   else
       cur_core=zeros(M,1);
      for k=1:M
         cur_core(k)=elem_fun(index_set(:,k));
      end
      super_core{i}=reshape(cur_core,[ry(i),n(i),n(i+1),ry(i+2)]);
   end

end
%Initialization is done.
%Now to the main iteration

%Through all the s-u-p-e-r-c-o-r-e-s
swp=1;
dir='lr';
i=1;
while ( swp <= nswp )
   %The method acts as follows.
   %1) Test if the current supercore is well approximated by the
   %current cross
   %2) If yes, do nothing.
   %3) If no, add the required indices to the cross and perform
   %modifications of the s-u-p-e-r-c-o-r-e-s

   %Nikrena ne soobrajau
   %Bilo: (i1,i2,i3,i4,i5)
   %Pofiksili (i1,i2), uvelichili r2. Rashirilos' mnojestvo (i2,i3,i4,i5)
   %(nikomu ne nujno)
   %V seredine: (i1,i2) (i3,i4,i5)+ - uvelichilos' mojectvo
   %Kogda uvelichili (i3,i4,i5) viros ry(3), uvelichilos 1 superyadro
   cur_core=super_core{i};
   %we have to convert the pair i_left{i} & r_left{i} to the
   %index set for the matrix cur_core

   cur_core=reshape(cur_core,[ry(i)*n(i),n(i+1)*ry(i+2)]);
   %i1=get_full_ind(i_left{i},r_left{i});
   %i2=get_full_ind(i_right{i+1},r_right{i+1});
    %ry(i)*n(i)

    i1=r_left{i}+(i_left{i}-1)*ry(i);
    i2=i_right{i+1}+(r_right{i+1}-1)*n(i+1);
  % if ( numel(i1)==2)
  %     if ( i1(1) == 2 && i1(2) == 2 )
  %   keyboard;
  %     end
  % end
  [i1,i2]=new_cross(cur_core,i1,i2,eps);
       %Increase i_left{i} & i_right{i+1}
       [radd_left,iadd_left]=ind2sub([ry(i);n(i)],i1);
       [iadd_right,radd_right]=ind2sub([n(i+1);ry(i+2)],i2);
       i_left{i}=iadd_left;
       r_left{i}=radd_left;
       %if ( i == 8 )
       %    keyboard
       %end
       i_right{i+1}=iadd_right;
       r_right{i+1}=radd_right;
       ry(i+1)=numel(i1);
       %Zaglushka
       ind_left=get_multi_left(i_left,r_left,ry);

       ind_right=get_multi_right(i_right,r_right,ry);

      %   fprintf('Index set in question: \n');
      %   ind_left{3}
      % if ( i == 3 && swp == 2 )
      %   keyboard;
      % end
       %keyboard;
       if ( i > 1 )
         %Recompute supercore{i-1}
         super_core{i-1}=compute_supercore(i-1,elem_fun,d,n,ry,ind_left,ind_right,vec);
       end
       if ( i < d - 1)
         super_core{i+1}=compute_supercore(i+1,elem_fun,d,n,ry,ind_left,ind_right,vec);
         %Recompute supercore{i+1};
       end

   %Convert iadd1 to i_left and i_right format; compute new
   %ind_left{i+1},ind_right{i+1}
   if ( strcmp(dir,'lr') )
     if ( i == d-1 )
        dir='rl';
     else
        i=i+1;
     end
   else
     if ( i == 1 )
        dir ='lr';
        swp=swp+1;
     else
        i=i-1;
     end
   end
   fprintf('Step %d sweep %d rank=%3.1f \n',i,swp,mean(ry));
end
fprintf('Done! \n');
keyboard;

return
end

function [super_core]=compute_supercore(i,elem_fun,d,n,ry,ind_left,ind_right,vec)
%[super_core]=compute_supercore(i,elem_fun,n,ry,ind_left,ind_right)
   index_set=zeros(d,ry(i),n(i),n(i+1),ry(i+2));
   if ( i == 1 )
       ileft=zeros(1,0);
   else
      ileft=ind_left{i-1};
   end
   if ( i == d - 1 )
      iright = zeros(1,0);
   else
      iright=ind_right{i+2};
   end
   for s1=1:ry(i)
      for s2=1:ry(i+2)
        for i1=1:n(i)
           for i2=1:n(i+1)
              index_set(:,s1,i1,i2,s2)=[ileft(s1,:),i1,i2,iright(s2,:)];
           end
        end
      end
   end
   M=ry(i)*n(i)*n(i+1)*ry(i+2);
   index_set=reshape(index_set,[d,M]);
   if ( vec )
      super_core=reshape(elem_fun(index_set),[ry(i),n(i),n(i+1),ry(i+2)]);
   else
       cur_core=zeros(M,1);
      for k=1:M
         cur_core(k)=elem_fun(index_set(:,k));
      end
      super_core=reshape(cur_core,[ry(i),n(i),n(i+1),ry(i+2)]);
   end

return
end

function [i1,i2]=new_cross(mat,i1,i2,eps)
%[i1,i2]=enlarge_cross(mat,i1,i2,eps)
%Tests whether the current index set gives a reasonable approximation
%to the matrix, and enlarges the basis if necessary.
%The method acts as follows.

%A-C*A11^{-1} R

%sbm=mat(i1,i2);
%[u,s,v]=svd(sbm,'econ');
%nrm=norm(mat);s=diag(s);
%r=numel(find(
%mat_save=mat;
i1=[];
i2=[];
desirata=eps*norm(mat,'fro');
er=norm(mat,'fro');
while ( er > desirata )
   %Find maximal element in mat
   [~,ind]=max(abs(mat(:)));
   ind=tt_ind2sub(size(mat),ind);
   i=ind(1); j=ind(2);
    i1=[i1;i];
    i2=[i2;j];
    u1=mat(:,j); u2=mat(i,:);
    u1=u1/mat(i,j);
    mat=mat-u1*u2;
    er=norm(mat,'fro');
end
% i0=[i1;iadd1]; j0=[i2;iadd2];
% sbm=mat_save(i0,j0);
% ss=svd(sbm);
% fprintf('%10.10e \n',ss)
% sbm=mat_save(i1,i2);
% fprintf('AND PREVIOUS \n');
% ss=svd(sbm);
% fprintf('%10.10e \n',ss)

return
end

function [ind_left]=get_multi_left(i_left,r_left,ry)
%[ind_left]=get_multi_left(i_left,r_left,ry)
%Computes (all) left multiindex sets for a given compact representation
  d=numel(i_left);
  ind_left=cell(d,1);
  ind_left{1}=i_left{1};
  for i=2:d
      %ind_cur=zeros(
      %ind_cur is an array of size ry(i-1) x i
      ind_cur=zeros(ry(i+1),i);
      r_prev=r_left{i};
      ind_prev=ind_left{i-1};
      i_prev=i_left{i};
      for s=1:ry(i+1)
          %ind_prev(p1(s
         ind_cur(s,:)=[ind_prev(r_prev(s),:),i_prev(s)];
      end
      ind_left{i}=ind_cur;
  end
return
end

function [ind_right]=get_multi_right(i_right,r_right,ry)
%[ind_right]=get_multi_right(i_right,r_right,ry)
%Computes (all) right multiindex sets for a given compact representation
  d=numel(i_right);
  ind_right=cell(d,1);
  ind_right{d}=i_right{d};
  for i=d-1:-1:1
      %ind_cur=zeros(
      %ind_cur is an array of size ry(i) x i
      ind_cur=zeros(ry(i),d-i+1);
      r_prev=r_right{i};
      ind_prev=ind_right{i+1};
      i_prev=i_right{i};
      for s=1:ry(i)
         ind_cur(s,:)=[i_prev(s), ind_prev(r_prev(s),:)];
      end
      ind_right{i}=ind_cur;
  end

return
end

function [ind]=find_fiber_maximum(elem_fun,ind)
%[ind]=find_fiber_maximum(elem_fun,ind)
%Simple ALS method to compute (approximate) maximum in a tensor
%In fact, need some non-zero
%fact=2; %If the new one <= fact times larger than the previous, stop

return
end


% GEODEMO_4 Compare horizontal slices from two different CF compliant structured
% grid models (CH3D and ROMS) at a particular time step and depth
clear

%% CH3D salinity
url{1}='http://testbedapps.sura.org/thredds/dodsC/estuarine_hypoxia/ch3d/agg.nc';
var{1}='salinity';
titl{1}='CH3D';

%% ROMS salt
url{2}='http://testbedapps.sura.org/thredds/dodsC/estuarine_hypoxia/chesroms_1tdo/agg.nc';
var{2}='salt';
titl{2}='CHESROMS';

%% Choose a date,depth, and spatial extent
dat=[2005 1 10 0 0 0];  % Jan 10, 2005 00:00 UTC
depth=-5;  % horizontal slice 5 m from surface
ax=[  -77.4572  -75.4157   36.7224   39.6242]; %lon/lat range
cax=[0 33];  %color range
lat_mid=38; % for scaling plots

%% Perform analysis without using dataset dependant code
% Access datasets, get 3d field at given time data, interpolate data to a constant z, plot results at z depth

figure;
for i=1:length(url);
  nc{i}=ncgeodataset(url{i});
  jd{i}=nj_time(nc{i},var{i});  % using nj_time
  itime=date_index(jd{i},dat);
  disp(['reading data from ' titl{i} '...'])

  % using nj_tslice here, which doesn't allow for subsetting or
  % striding:  you get the whole 3D field at a particular time step:
  [s{i},g{i}]=nj_tslice(nc{i},var{i},itime);
  sz{i}=zsliceg(s{i},g{i}.z,depth);
  a{i}=subplot(1,length(url),i);
  pcolorjw(g{i}.lon,g{i}.lat,double(sz{i}));colorbar
  axis(ax);
  caxis(cax);
  title(sprintf('%s, depth=%f: %s',titl{i},depth,datestr(g{i}.time)));
  set (a{i}, 'DataAspectRatio', [1 cos(lat_mid*pi/180) 1000] );

end


function square_symq_gnuplot ( n, x, header )

%*****************************************************************************80
%
%% SQUARE_SYMQ_GNUPLOT: GNUPLOT plot of the symmetric square quadrature rule.
%
%  Licensing:
%
%    This code is distributed under the GNU GPL license.
%
%  Modified:
%
%    11 July 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Hong Xiao, Zydrunas Gimbutas,
%    A numerical algorithm for the construction of efficient quadrature
%    rules in two and higher dimensions,
%    Computers and Mathematics with Applications,
%    Volume 59, 2010, pages 663-676.
%
%  Parameters:
%
%    Input, real N, the number of nodes.
%
%    Input, real X(2,N), the coordinates of the nodes.
%
%    Input, string HEADER, a string to be used to identify
%    the files created.
%

%
%  Create the vertex file.
%
  vertex_filename = strcat ( header, '_vertices.txt' );
  vertex_unit = fopen ( vertex_filename, 'wt' );
  fprintf ( vertex_unit, '%g  %g\n', -1.0, -1.0 );
  fprintf ( vertex_unit, '%g  %g\n', +1.0, -1.0 );
  fprintf ( vertex_unit, '%g  %g\n', +1.0, +1.0 );
  fprintf ( vertex_unit, '%g  %g\n', -1.0, +1.0 );
  fprintf ( vertex_unit, '%g  %g\n', -1.0, -1.0 );
  fclose ( vertex_unit );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Created vertex file "%s"\n', vertex_filename );
%
%  Create node file.
%
  node_filename = strcat ( header, '_nodes.txt' );
  node_unit = fopen ( node_filename, 'wt' );
  for j = 1 : n
    fprintf ( node_unit, '%g  %g\n', x(1:2,j) );
  end
  fclose ( node_unit );
  fprintf ( 1, '  Created node file "%s"\n', node_filename );
%
%  Create graphics command file.
%
  command_filename = strcat ( header, '_commands.txt' );
  command_unit = fopen ( command_filename, 'wt' );
  fprintf ( command_unit, '# %s\n', command_filename );
  fprintf ( command_unit, '#\n' );
  fprintf ( command_unit, '# Usage:\n' );
  fprintf ( command_unit, '#  gnuplot < %s\n', command_filename );
  fprintf ( command_unit, '#\n' );
  fprintf ( command_unit, 'set term png\n' );
  plot_filename = strcat ( header, '.png' );
  fprintf ( command_unit, 'set output "%s"\n', plot_filename );
  fprintf ( command_unit, 'set xlabel "<--- X --->"\n' );
  fprintf ( command_unit, 'set ylabel "<--- Y --->"\n' );
  fprintf ( command_unit, 'set title "%s"\n', header );
  fprintf ( command_unit, 'set grid\n' );
  fprintf ( command_unit, 'set key off\n' );
  fprintf ( command_unit, 'set size ratio -1\n' );
  fprintf ( command_unit, 'set style data lines\n' );
  fprintf ( command_unit, 'set timestamp\n' );
  fprintf ( command_unit, 'plot "%s" with lines lw 3, \\\n', vertex_filename );
  fprintf ( command_unit, '     "%s" with points pt 7 lt 0\n', node_filename );
  fclose ( command_unit );

  fprintf ( 1, '  Created command file "%s"\n', command_filename );

  return
end


function ho=comprose(x,y,n,w,az,varargin)
%COMPROSE Compass rose plot
%
%       COMPROSE(X,Y,N,W,AZ) adds a compass rose on current axis located at
%       position X,Y with N points (N is 1, 4, 8 or 16), width W (radius)
%       and North pointing to azimuth AZ (in degree, AZ = 0 means an arrow
%       pointing to positive Y-axis direction, rotating clockwise).
%
%       COMPROSE(...,FS) adds Cardinal directions with font size FS.
%
%       COMPROSE(...,'param1',value1,'param2',value2,...) specifies any
%       additionnal properties of the Patch using standard parameter/value
%       pairs. Note that 'FaceColor' concerns only the default black-filled
%       parts of the drawing.
%
%	H=COMPROSE(...) returns a Nx3 matrix of object handles: first column
%	addresses solid filled patches, second column for white patches, third
%	column for Cardinal direction text.
%
%       Examples:
%		comprose(0,0,8,.5,10)
%
%		comprose(2,-1,1,2,0,20,'LineWidth',2,'FaceColor',.5*[1,1,1])
%
%		h = comprose(1,2.5,16,1,-10);
%		set(h(:,1),'FaceColor',[0,.5,.5],'EdgeColor',.5*[1,1,1])
%		set(h(:,2),'FaceColor',.9*[1,1,1])
%
%       See also PATCH.
%
%	Author: Francois Beauducel <beauducel@ipgp.fr>
%	Created: 2012-06-24

%	Copyright (c) 2012, François Beauducel, covered by BSD License.
%	All rights reserved.
%
%	Redistribution and use in source and binary forms, with or without
%	modification, are permitted provided that the following conditions are
%	met:
%
%	   * Redistributions of source code must retain the above copyright
%	     notice, this list of conditions and the following disclaimer.
%	   * Redistributions in binary form must reproduce the above copyright
%	     notice, this list of conditions and the following disclaimer in
%	     the documentation and/or other materials provided with the distribution
%
%	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
%	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%	ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
%	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
%	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
%	POSSIBILITY OF SUCH DAMAGE.

if nargin < 5
	error('Not enough input arguments.')
end

if nargin > 5 & isnumeric(varargin{1})
	fs = varargin{1};
	varargin = varargin(2:end);
else
	fs = 0;
end

if ~isnumeric(x) | ~isnumeric(y) | ~isnumeric(n) | ~isnumeric(w) | ~isnumeric(az)
	error('X,Y,N,W, and AZ must be numeric.')
end

if all(n ~= [1,4,8,16])
	error('N must be equal to 1, 4, 8 or 16.')
end

hh = [];

for k = n:-1:1
	h = branch(x,y,k,w,az,fs,varargin{:});
	hh = [hh;h];
end

if nargout > 0
	ho = hh;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h = branch(x,y,k,w,az,fs,varargin)

cpt = {'N','E','S','W','NE','SE','SW','NW', ...
	'NNE','ENE','ESE','SSE','SSW','WSW','WNW','NNW'};
cph = {'center','left','center','right','left','left','right','right', ...
	'left','left','left','left','right','right','right','right'};
cpv = {'bottom','middle','top','middle','bottom','top','top','bottom', ...
	'bottom','bottom','top','top','top','top','bottom','bottom'};

if k <= 4
	a = (k-1)*90 + az;
else
	if k <= 8
		a = (k-8)*90 - 45 + az;
		w = w*.8;
		fs = fs*.8;
	else
		a = (k-16)*45 - 22.5 + az;
		w = w*.6;
		fs = fs*.6;
	end
end

r = .15;
xx = w*[0 0 r];
yy = w*[0 1 r];
x1 =  xx*cosd(a) + yy*sind(a);
y1 = -xx*sind(a) + yy*cosd(a);
x2 = -xx*cosd(a) + yy*sind(a);
y2 =  xx*sind(a) + yy*cosd(a);
h(1) = patch(x1 + x,y1 + y,'k',varargin{:});
h(2) = patch(x2 + x,y2 + y,'k',varargin{:},'FaceColor','w');

% Cardinal points
xp = 1.03*x1(2) + x;
yp = 1.03*y1(2) + y;
h(3) = text(xp,yp,cpt{k}, ...
	'HorizontalAlignment',cph{k},'VerticalAlignment',cpv{k},'Rotation',-az);
if fs > 0
	set(h(3),'FontSize',fs','FontWeight','bold')
else
	set(h(3),'Visible','off')
end


function [newbnd] = mesh2edge(bnd)

% MESH2EDGE finds the edge lines from a triangulated mesh or the edge
% surfaces from a tetrahedral or hexahedral mesh. An edge is defined as an
% element that does not border any other element. This also implies that a
% closed triangulated surface has no edges.
%
% Use as
%   [edge] = mesh2edge(mesh)
%
% See also POLY2TRI

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

if isfield(bnd, 'tri')
  % make a list of all edges
  edge1 = bnd.tri(:, [1 2]);
  edge2 = bnd.tri(:, [2 3]);
  edge3 = bnd.tri(:, [3 1]);
  edge = cat(1, edge1, edge2, edge3);

elseif isfield(bnd, 'tet')
  % make a list of all triangles that form the tetraheder
  tri1 = bnd.tet(:, [1 2 3]);
  tri2 = bnd.tet(:, [2 3 4]);
  tri3 = bnd.tet(:, [3 4 1]);
  tri4 = bnd.tet(:, [4 1 2]);
  edge = cat(1, tri1, tri2, tri3, tri4);

elseif isfield(bnd, 'hex')
  % make a list of all "squares" that form the cube/hexaheder
  % FIXME should be checked, this is impossible without a drawing
  square1 = bnd.hex(:, [1 2 3 4]);
  square2 = bnd.hex(:, [5 6 7 8]);
  square3 = bnd.hex(:, [1 2 6 5]);
  square4 = bnd.hex(:, [2 3 7 6]);
  square5 = bnd.hex(:, [3 4 8 7]);
  square6 = bnd.hex(:, [4 1 5 8]);
  edge = cat(1, square1, square2, square3, square4, square5, square6);

end % isfield(bnd)

% soort all polygons in the same direction
% keep the original as "edge" and the sorted one as "sedge"
sedge = sort(edge, 2);

% % find the edges that are not shared -> count the number of occurences
% n = size(sedge,1);
% occurences = ones(n,1);
% for i=1:n
%   for j=(i+1):n
%     if all(sedge(i,:)==sedge(j,:))
%       occurences(i) = occurences(i)+1;
%       occurences(j) = occurences(j)+1;
%     end
%   end
% end
%
% % make the selection in the original, not the sorted version of the edges
% % otherwise the orientation of the edges might get flipped
% edge = edge(occurences==1,:);

% find the edges that are not shared
indx = findsingleoccurringrows(sedge);
edge = edge(indx, :);

% replace pnt by pos
bnd = fixpos(bnd);

% the naming of the output edges depends on what they represent
newbnd.pos  = bnd.pos;
if isfield(bnd, 'tri')
  % these have two vertices in each edge element
  newbnd.line = edge;
elseif isfield(bnd, 'tet')
  % these have three vertices in each edge element
  newbnd.tri = edge;
elseif isfield(bnd, 'hex')
  % these have four vertices in each edge element
  newbnd.poly = edge;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUBFUNCTION, see http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=1833#c12
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function indx = findsingleoccurringrows(X)
[X, indx] = sortrows(X);
sel  = any(diff([X(1,:)-1; X],1),2) & any(diff([X; X(end,:)+1],1),2);
indx = indx(sel);

function indx = finduniquerows(X)
[X, indx] = sortrows(X);
sel  = any(diff([X(1,:)-1; X],1),2);
indx = indx(sel);


function [node,elem,face]=s2m(v,f,keepratio,maxvol,method,regions,holes)
%
% [node,elem,face]=s2m(v,f,keepratio,maxvol,method)
% [node,elem,face]=s2m(v,f,keepratio,maxvol,'tetgen',regions,holes)
%
% volumetric mesh generation from a closed surface, shortcut for surf2mesh
%
% author: Qianqian Fang (fangq <at> nmr.mgh.harvard.edu)
%
% inputs and outputs are similar to those defined in surf2mesh
%
% if method='cgalpoly', s2m will call cgals2m and keepratio should be a
% structure (as the 'opt' input in cgals2m)
%
% input default values:
%       method: if ignored, iso2mesh uses surf2mesh ('tetgen') to do the
%               tetrahedral mesh generation
%       regions,holes: if ignored, iso2mesh assumes both are empty
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

p0=min(v(:,1:3));
p1=max(v(:,1:3));
if(nargin>=5 && strcmp(method,'cgalpoly'))
    [node,elem,face]=cgals2m(v,f,keepratio,maxvol);
    return;
end
if(nargin<=5)
    regions=[];
end
if(nargin<=6)
    holes=[];
end
[node,elem,face]=surf2mesh(v,f,p0,p1,keepratio,maxvol,regions,holes);


%% Simulation Data
simu = simulationClass();               % Initialize Simulation Class
simu.simMechanicsFile = 'RM3.slx';      % Specify Simulink Model File
simu.mode = 'normal';                   % Specify Simulation Mode ('normal','accelerator','rapid-accelerator')
simu.explorer = 'on';                   % Turn SimMechanics Explorer (on/off)
simu.startTime = 0;                     % Simulation Start Time [s]
simu.rampTime = 100;                    % Wave Ramp Time [s]
simu.endTime = 400;                     % Simulation End Time [s]
simu.solver = 'ode4';                   % simu.solver = 'ode4' for fixed step & simu.solver = 'ode45' for variable step
simu.dt = 0.1; 							% Simulation time-step [s]

%% Wave Information
% % noWaveCIC, no waves with radiation CIC
% waves = waveClass('noWaveCIC');       % Initialize Wave Class and Specify Type

% Regular Waves
waves = waveClass('regular');           % Initialize Wave Class and Specify Type
waves.height = 2.5;                     % Wave Height [m]
waves.period = 8;                       % Wave Period [s]

% % Regular Waves with CIC
% waves = waveClass('regularCIC');          % Initialize Wave Class and Specify Type
% waves.height = 2.5;                       % Wave Height [m]
% waves.period = 8;                         % Wave Period [s]

% % Irregular Waves using PM Spectrum
% waves = waveClass('irregular');           % Initialize Wave Class and Specify Type
% waves.height = 2.5;                       % Significant Wave Height [m]
% waves.period = 8;                         % Peak Period [s]
% waves.spectrumType = 'PM';                % Specify Wave Spectrum Type

% % Irregular Waves using JS Spectrum with Equal Energy and Seeded Phase
% waves = waveClass('irregular');           % Initialize Wave Class and Specify Type
% waves.height = 2.5;                       % Significant Wave Height [m]
% waves.period = 8;                         % Peak Period [s]
% waves.spectrumType = 'JS';                % Specify Wave Spectrum Type
% waves.bem.option = 'EqualEnergy';         % Uses 'EqualEnergy' bins (default)
% waves.phaseSeed = 1;                      % Phase is seeded so eta is the same

% % Irregular Waves using PM Spectrum with Traditional and State Space
% waves = waveClass('irregular');           % Initialize Wave Class and Specify Type
% waves.height = 2.5;                       % Significant Wave Height [m]
% waves.period = 8;                         % Peak Period [s]
% waves.spectrumType = 'PM';                % Specify Wave Spectrum Type
% simu.stateSpace = 1;                      % Turn on State Space
% waves.bem.option = 'Traditional';         % Uses 1000 frequnecies

% % Irregular Waves with imported spectrum
% waves = waveClass('spectrumImport');      % Create the Wave Variable and Specify Type
% waves.spectrumFile = 'spectrumData.mat';  % Name of User-Defined Spectrum File [:,2] = [f, Sf]

% % Waves with imported wave elevation time-history
% waves = waveClass('elevationImport');          % Create the Wave Variable and Specify Type
% waves.elevationFile = 'elevationData.mat';     % Name of User-Defined Time-Series File [:,2] = [time, eta]

%% Body Data
% Float
body(1) = bodyClass('hydroData/rm3.h5');
    % Create the body(1) Variable, Set Location of Hydrodynamic Data File
    % and Body Number Within this File.
body(1).geometryFile = 'geometry/float.stl';    % Location of Geomtry File
body(1).mass = 'equilibrium';
    % Body Mass. The 'equilibrium' Option Sets it to the Displaced Water
    % Weight.
body(1).inertia = [20907301 21306090.66 37085481.11];  % Moment of Inertia [kg*m^2]

% Spar/Plate
body(2) = bodyClass('hydroData/rm3.h5');
body(2).geometryFile = 'geometry/plate.stl';
body(2).mass = 'equilibrium';
body(2).inertia = [94419614.57 94407091.24 28542224.82];

%% PTO and Constraint Parameters
% Floating (3DOF) Joint
constraint(1) = constraintClass('Constraint1'); % Initialize Constraint Class for Constraint1
constraint(1).location = [0 0 0];               % Constraint Location [m]

% Translational PTO
pto(1) = ptoClass('PTO1');                      % Initialize PTO Class for PTO1
pto(1).stiffness = 0;                           % PTO Stiffness [N/m]
pto(1).damping = 1200000;                       % PTO Damping [N/(m/s)]
pto(1).location = [0 0 0];                      % PTO Location [m]


classdef DotProduct < dagnn.ElementWise

    properties (Transient)
        numInputs
    end

    methods
        function outputs = forward(obj, inputs, params)
            obj.numInputs = numel(inputs) ;
            outputs{1} = inputs{1} ;
            for k = 2:obj.numInputs
                outputs{1} = outputs{1} .* inputs{k} ;
            end
        end

        function [derInputs, derParams] = backward(obj, inputs, params, derOutputs)
            for k = 1:obj.numInputs
                derInputs{k} = derOutputs{1} ;
                for ko = 1:obj.numInputs
                    if ko ~= k
                        derInputs{k} = derInputs{k} .* inputs{ko};
                    end
                end
            end
            derParams = {} ;
        end

        function outputSizes = getOutputSizes(obj, inputSizes)
            outputSizes{1} = inputSizes{1} ;
            for k = 2:numel(inputSizes)
                if all(~isnan(inputSizes{k})) && all(~isnan(outputSizes{1}))
                    if ~isequal(inputSizes{k}, outputSizes{1})
                        warning('DotProduct layer: the dimensions of the input variables is not the same.') ;
                    end
                end
            end
        end

        function rfs = getReceptiveFields(obj)
            numInputs = numel(obj.net.layers(obj.layerIndex).inputs) ;
            rfs.size = [1 1] ;
            rfs.stride = [1 1] ;
            rfs.offset = [1 1] ;
            rfs = repmat(rfs, numInputs, 1) ;
        end

        function obj = DotProduct(varargin)
            obj.load(varargin) ;
        end
    end
end


function F = real(F)
%REAL   Complex real part of a CHEBFUN.
%   REAL(F) is the real part of F.
%
% See also IMAG, ISREAL.

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

% Handle the empty case:
if ( isempty(F) )
    return
end

for j = 1:numel(F)
    % Take real part of the pointValues:
    F(j).pointValues = real(F(j).pointValues);

    % Take real part of the FUNs:
    for k = 1:numel(F(j).funs)
        F(j).funs{k} = real(F(j).funs{k});
    end
end

end


function cheby_u_test ( )

%*****************************************************************************80
%
%% CHEBY_U_TEST tests the use of the MEX file CHEBY_U.CPP
%
%  Discussion:
%
%    The file cheby_u.cpp is a C++ function which computes the
%    Chebyshev U polynomials.
%
%    This M file "compiles" cheby_u.cpp, and then shows how it can be called.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 September 2013
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CHEBY_U_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Demonstrate a simple use of the MEX compiler,\n' );
  fprintf ( 1, '  which allows MATLAB to call C++ functions.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Get a directory listing.\n' );
  fprintf ( 1, '  The file CHEBY_U.CPP should be there.\n' );

  ls

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Compile the file CHEBY_U.CPP.\n' );

  mex cheby_u.cpp

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Get a directory listing.  A new file should show up,\n' );
  fprintf ( 1, '  containing the compiled information.\n' );

  ls

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Now use CHEBY_U as though it were a MATLAB M-file\n' );
  fprintf ( 1, '  function.\n' );

  n = 12;
  x = 0.2;

  cx_check(1:n+1) = [ ...
     1.0000000000, ...
     0.4000000000, ...
    -0.8400000000, ...
    -0.7360000000, ...
     0.5456000000, ...
     0.9542400000, ...
    -0.1639040000, ...
    -1.0198016000, ...
    -0.2440166400, ...
     0.9221949440, ...
     0.6128946176, ...
    -0.6770370970, ...
    -0.8837094564 ];

  cx = cheby_u ( n, x );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Evaluation point X = %f\n', x );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   N           U(N,X)          U(N,X)\n' );
  fprintf ( 1, '           (computed)     (tabulated)\n' );
  fprintf ( 1, '\n' );

  for i = 1 : n + 1

    fprintf ( 1, '  %2d  %14f  %14f\n', i-1, cx(i), cx_check(i) );

  end
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CHEBY_U_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


function OUT = VARmakelags(DATA,lag)
% =======================================================================
% Builds a matrix with lagged values of DATA, i.e. if DATA = [x1 x2],
% VARmakelags(DATA,1) yields OUT = [x1 x2 x1(-1) x2(-1)]. Serves as an
% input to VARmakexy
% =======================================================================
% OUT = VARmakelags(DATA,lag)
% -----------------------------------------------------------------------
% INPUT
%   - DATA: matrix containing the original data
%   - lag: lag order
% -----------------------------------------------------------------------
% OUTPUT
%   - OUT: matrix of lagged values
% -----------------------------------------------------------------------
% EXAMPLE
%   x = [1 2; 3 4; 5 6; 7 8; 9 10];
%   OUT = VARmakelags(x,2)
% =======================================================================
% VAR Toolbox 3.0
% Ambrogio Cesa-Bianchi
% ambrogiocesabianchi@gmail.com
% March 2012. Updated November 2020
% -----------------------------------------------------------------------

% Get dimesion of DATA
[nobs, ~]= size(DATA);

% Create the lagged matrix
OUT = [];
for jj=0:lag-1
    OUT = [DATA(jj+1:nobs-lag+jj,:), OUT];
end

% Finally, save the non-lagged values...
aux = DATA(lag+1:end,:);

%... and append to the lagged matrix
OUT = [aux OUT];


function cy = zcopy ( n, cx, incx, cy, incy )

%*****************************************************************************80
%
%% ZCOPY copies a complex vector X to a vector Y.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 May 2006
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979.
%
%    Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
%    Basic Linear Algebra Subprograms for Fortran Usage,
%    Algorithm 539,
%    ACM Transactions on Mathematical Software,
%    Volume 5, Number 3, September 1979, pages 308-323.
%
%  Parameters:
%
%    Input, integer N, the number of elements in CX and CY.
%
%    Input, complex CX(*), the first vector.
%
%    Input, integer INCX, the increment between successive entries of CX.
%
%    Input, complex CY(*), the second vector.
%
%    Input, integer INCY, the increment between successive entries of CY.
%
%    Output, complex CY(*), the second vector, with certain elements
%    copied from CX.
%
  cy(1:incy:1+(n-1)*incy) = cx(1:incx:1+(n-1)*incx);

  return
end


function gp_save_loudspeakers(file,x0)
%GP_SAVE_LOUDSPEAKERS saves x0 as a text file in a Gnuplot compatible format
%
%   Usage: gp_save_loudspeakers(file,x0)
%
%   Input parameters:
%       file        - filename of the data file
%       x0          - secondary sources [nx7]
%
%   GP_SAVE_LOUDSPEAKERS(file,x0) saves x0(:,1:2) as positions of the
%   loudspeakers, an orientation value calculated from x0(:,4:6), and the
%   activity x0(:,7) of the loudspeakers in a text file useable by gnuplot.
%
%   See also: gp_save, gp_save_matrix

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

%% ===== Checking of input  parameters ==================================
nargmin = 2;
nargmax = 2;
narginchk(nargmin,nargmax);
isargchar(file);
isargsecondarysource(x0);

%% ===== Main ============================================================
% Write header to the file
fid = fopen(file,'w');
fprintf(fid,'# Loudspeaker file generated by gp_save_loudspeakers.m\n');
fprintf(fid,'# x0 y0 phi ls_activity\n');
fclose(fid);

% Calculate phi
loudspeaker(:,1:2) = x0(:,1:2);
[loudspeaker(:,3),~,~] = cart2sph(x0(:,4),x0(:,5),x0(:,6));
loudspeaker(:,4) = x0(:,7);

% Append the data to the file using tabulator as a delimiter between the data
if isoctave
    dlmwrite(file,loudspeaker,'\t','-append');
else
    dlmwrite(file,loudspeaker,'delimiter','\t','-append');
end


clear all; close all; clc;
%% Initialization
%data load
% name={'1_bykim','2_dblee','3_eskim','9_prchoi','10_smkang','12_yskim'}; %session 0
name={'1_bykim','2_dblee','3_eskim','4_jhsuh','5_mgjung','6_mhlee','7_mjkim','8_oykwon','9_prchoi','10_smkang','11_spseo','12_yskim','13_jyha','14_hmyoo','15_jwlee','16_wbsim','17_hwnoh','18_dysull','19_jyhan','20_jwbae','21_syjung','22_dkhan','23_hjwon','24_nkkil','25_khshim'}; % session 1
% name={'1_bykim','2_dblee','3_eskim','4_jhsuh','5_mgjung','7_mjkim','9_prchoi','10_smkang','12_yskim','13_jyha','14_hmyoo','15_jwlee','16_wbsim','17_hwnoh','18_dysull','19_jyhan','20_jwbae','21_syjung','22_dkhan','23_hjwon'}; % session 2
session = {'session1'};
task = {'mi_off','mi_on'};
fs=100;

%pre-processing
channel_index = [1:32];
band = [8 30];
time_interval = [1000 3500];

%feature-extraction
CSPFilter=2;
%classifiaction

%% Data load and mat save
for sub=1:length(name)
    for onoff=1:2
        file3 = ['E:\Users\cvpr\Desktop\StarlabDB_2nd\',name{sub},'\'];
        BMI.EEG_DIR=['E:\Users\cvpr\Desktop\StarlabDB_2nd\',name(sub),'\',session];
        BMI.EEG_DIR=cell2mat(BMI.EEG_DIR);
        file=fullfile(BMI.EEG_DIR, task{onoff});
        marker={'1','left';'2','right'};
        [EEG.data, EEG.marker, EEG.info]=Load_EEG(file,{'device','brainVision';'marker', marker;'fs', fs});
        field={'x','t','fs','y_dec','y_logic','y_class','class', 'chan'};
        CNT=opt_eegStruct({EEG.data, EEG.marker, EEG.info}, field);
        CNTT{sub,onoff} = CNT;
    end
    %     filename1= ['mi_cnt_s1_on'];
    %     save([file3, filename1], 'CNT');
end
%% 'mat' load
% for sub=1:11
%
% %     name={'bykim','dblee','ejlee','eskim','mhlee','prchoi','sbsim','smkang','yelee','yskim'};
%     name={'bykim','eskim','prchoi','smkang','oykwon'};
%     file3 = ['E:\Users\cvpr\Desktop\StarlabDB_2nd\',name{sub},'\'];
%     filename4 = ['mi_cnt_s1_on.mat'];
%
%     cnt = load([file3, filename4]);
%     % MI 19 ch
%     cnt= prep_selectChannels(cnt.CNT, {'Name',{'FC5','FC3','FC1','C5','C3','C1','Cz','CP5','CP3','CP1','CP6','CP4','CP2','C6','C4','C2','FC6','FC4','FC2'}});
%     cnt=prep_filter(cnt, {'frequency', [7 13]});
%     new_smt{sub,1}=prep_segmentation(cnt, {'interval', [750 3500]});
%
% end
%% Pre-processing
clear CNT clear BMI ans EEG field file file3 marker sub
for NUM=1:length(CNTT)
    for onoff=1:2
        CNTch = prep_selectChannels(CNTT{NUM,onoff}, {'Index', channel_index});
        CNTchfilt =prep_filter(CNTch , {'frequency', band});
        all_SMT{NUM,onoff} = prep_segmentation(CNTchfilt, {'interval', time_interval});
        clear CNTch CNTchfilt
    end
end
%% Feature extraction and classification
%% CSP - LDA
for num = 1:length(all_SMT)
    [SMT, CSP_W, CSP_D]=func_csp(all_SMT{num,1},{'nPatterns', CSPFilter});
    FT=func_featureExtraction(SMT, {'feature','logvar'});
    [CF_PARAM]=func_train(FT,{'classifier','LDA'});
    SMT_te=func_projection(all_SMT{num,2}, CSP_W);

    FT_te=func_featureExtraction(SMT_te, {'feature','logvar'});
    [cf_out]=func_predict(FT_te, CF_PARAM);
    [loss out]=eval_calLoss(FT_te.y_dec, cf_out);
    sub_acc(:,num)=1-loss';
    clear SMT CSP_W CSP_D FT CF_PARAM SMT_te FT_Te cf_out loss out
end
    all_acc =sub_acc';
    all_mean_acc = mean(sub_acc,2);
%% FBCSP - LDA

%% BSSFO - LDA


function [sys,x0,str,ts]=abcrtoqdor(t,x,u,flag)
%dfsfgsfdgdghdhdfg
switch flag
    case 0
        [sys,x0,str,ts]=mdlInitializeSizes;
    case 3
        sys=mdlOutput(t,x,u);
    case {1,2,4,9}
        sys=[];
    otherwise
        error(['Unhandel flag =',num2str(flag)]);
end;
%========================================================================
%========================================================================
function [sys,x0,str,ts]=mdlInitializeSizes
sizes=simsizes;
sizes.NumContStates= 0;
sizes.NumDiscStates= 0;
sizes.NumOutputs= 1;
sizes.NumInputs= 2;
sizes.DirFeedthrough=1;
sizes.NumSampleTimes=1;
sys=simsizes(sizes);
x0=[];
str=[];
ts=[-1 0];
%=========================================================================
%=========================================================================
function sys=mdlOutput(t,x,u);
%=========================================================================
 vc=u(1);
 vm=u(2);
q=(vc*pi)/(3*vm);
if q>1
    q=1;
end
if q<-1
    q=-1;
end
a=acos(q);
  sys=a*180/pi;


function [C_trialAvr,C_trialRes,C_score,C_d2var_perstim,C_p] = GetTrialAvrLongTrace(hfig,C)
%%

isFulllength = 0; % isFulllength = true for analyses before 12/18/17 - XC

fishset = getappdata(hfig,'fishset');
periods = getappdata(hfig,'periods');

if fishset == 1
    period = periods;
    C_3D_0 = reshape(C,size(C,1),period,[]);

%     C_3D = zscore(C_3D_0,0,2);
%     C_d2var_perstim = nanmean(nanstd(C_3D,0,3),2);
%     C_score = C_d2var_perstim;

    C_period = mean(C_3D_0,3);%prctile(C_3D_0,20,3);%mean(C_3D_0,3);
    nPeriods = round(size(C,2)/period);
    C_trialAvr = repmat(C_period,1,nPeriods);

    C_trialRes = C-C_trialAvr;
    C_3D_tRes = reshape(C_trialRes,size(C,1),period,[]);
%     C_3D_tRes = zscore(C_3D_tRes_0,0,2);
    d2var = (nanstd(C_3D_tRes,0,3)).^2;
    C_score = nanmean(d2var,2);

    C_p = C;
    C_d2var_perstim = [];
else
    stimset = getappdata(hfig,'stimset');
    stimrange = getappdata(hfig,'stimrange');
    timelists = getappdata(hfig,'timelists');

    C_trialAvr = [];
%     C_d2std = [];
    C_d2var_perstim = [];
    C_p = []; % 12/18/17 - XC
    for i = 1:length(stimrange)
        i_stim = stimrange(i);
        if stimset(i_stim).nReps(1)>1
            offset = length(horzcat(timelists{stimrange(1:i-1)}));% works for i=0 too
            tIX_ = 1+offset:length(timelists{stimrange(i)})+offset;

            period = periods(i_stim);
            C_this = C(:,tIX_);

            C_this = zscore(C_this,0,2); % 05/11/18

            C_3D_0 = reshape(C_this,size(C,1),period,[]);
            C_period = mean(C_3D_0,3);%median(C_3D_0,3);
            nPeriods = length(tIX_)/period;
            C_trialAvr_this = repmat(C_period,1,nPeriods);
            C_trialAvr = horzcat(C_trialAvr,C_trialAvr_this); %#ok<AGROW>
            C_trialRes_this = C_this-C_trialAvr_this;

            C_3D_tRes = reshape(C_trialRes_this,size(C,1),period,[]);
            d2var = (nanstd(C_3D_tRes,0,3)).^2; % d2var = (mad(C_3D_tRes,0,3)).^2;
            C_d2var_perstim = horzcat(C_d2var_perstim,nanmean(d2var,2)); %#ok<AGROW>

            C_p = horzcat(C_p,C_this); % 12/18/17 - XC

%             C_3D = zscore(C_3D_0,0,2);
% %             C_d2std = horzcat(C_d2std,nanstd(C_3D,0,3));
%             d2var = (nanstd(C_3D,0,3)).^2;
%             C_d2var_perstim = horzcat(C_d2var_perstim,nanmean(d2var,2));
%             %             C_3D = zscore(C_3D_0,0,2);
%             %             H_raw = horzcat(H_raw,nanmean(nanstd(C_3D,0,3),2));
        else % taking out 12/18/17 - XC
            if isFulllength
                offset = length(horzcat(timelists{stimrange(1:i-1)}));% works for i=0 too
                tIX_ = 1+offset:length(timelists{stimrange(i)})+offset;
                C_trialAvr = horzcat(C_trialAvr,zeros(size(C,1),length(tIX_))); %#ok<AGROW>
            end
        end
    end

    % condense C_d2var_perstim for multiple stimsets down to 1 score
    if isempty(C_d2var_perstim)
        errordlg('chosen stimulus range not suitable for stim-lock analysis');
%         C_score = 1:numU;
        return;
    end
    C_score = zeros(size(C_d2var_perstim,1),1);
    for i = 1:size(C_d2var_perstim,1)
        C_score(i) = min(C_d2var_perstim(i,:));
    end

    if isFulllength
        C_trialRes = C-C_trialAvr;
    else
        C_trialRes = C_p-C_trialAvr; % 12/18/17 - XC
    end
end

end


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function y = Spread(S1,S2)
    nsim = size(S1,1);
    nt = size(S1,2);
    A = S1(:,nt)./S1(:,1) - S2(:,nt)./S2(:,1);
    val = [max(A,[],2) zeros(nsim,1)];
    y = mean(max(val,[],2));
end