function [y,S,k] = spm_csd_fmri_mar(P,M,U)
% Prediction of MAR coefficients for DCM
% FORMAT [y,S,K] = spm_csd_fmri_mar(P,M,U)
%
% P - model parameters
% M - model structure
% U - model inputs (expects U.csd as complex cross spectra)
%
% y - y(nw,nn,nn} - cross-spectral density for nn nodes
%                 - for nw frequencies in M.Hz
% K - Volterra kernels
% S - directed transfer functions (complex)
%
% This routine computes the spectral response of a network of regions
% driven by  endogenous fluctuations and exogenous (experimental) inputs.
% It returns the complex cross spectra of regional responses as a
% three-dimensional array. The endogenous innovations or fluctuations are
% parameterised in terms of a (scale free) power law, in frequency space.
%
% When the observer function M.g is specified, the CSD response is
% supplemented with observation noise in sensor space; otherwise the CSD
% is noiseless.
%
%
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_csd_fmri_mar.m 5618 2013-08-17 10:36:56Z karl $

% number of nodes and endogenous (neuronal) fluctuations
%--------------------------------------------------------------------------
np   = M.p;                                   % number of MAR lags
nn   = M.l;                                   % number of nodes (regions)

% cross-covaraince functions of neuronal fluctations (Vu) and noise (Vn)
%==========================================================================

% experimental inputs
%--------------------------------------------------------------------------
for i = 1:nn
    for j = 1:nn
        if any(any(P.C))
            for k = 1:M.N
                V(k) = P.C(i,:)*squeeze(U.ccf(k,:,:))*P.C(j,:)';
            end
            Vu{i,j} = toeplitz(V);
        else
            Vu{i,j} = sparse(M.N,M.N);
        end
    end
end

% neuronal inputs
%--------------------------------------------------------------------------
for i = 1:nn
    Vu{i,i} = Vu{i,i} + exp(P.a(1,i))*spm_Q(exp(P.a(2,i))/2,M.N);
end
Vu    = spm_cat(Vu);

% observation noise
%--------------------------------------------------------------------------
for i = 1:nn

    % global component
    %----------------------------------------------------------------------
    for j = 1:nn
        V       = exp(P.b(1,1))*spm_Q(exp(P.b(2,1))/2,np + 1)/64;
        Vn{i,j} = V((1:np),(1:np));
        Rn{i,j} = V((1:np) + 1,1);
    end

    % region specific
    %----------------------------------------------------------------------
    V       = exp(P.c(1,i))*spm_Q(exp(P.c(2,i))/2,np + 1)/8;
    Vn{i,i} = Vn{i,j} + V((1:np),(1:np));
    Rn{i,i} = Rn{i,j} + V((1:np) + 1,1);

end
Vn    = spm_cat(Vn);
Rn    = spm_cat(Rn);

% first-order Volterra kernel
%==========================================================================
P.C   = speye(nn,nn);
[S,k] = spm_dcm_mtf(P,M);

% matix form
%--------------------------------------------------------------------------
for i = 1:nn
    for j = 1:nn
        K{i,j} = k(:,i,j);
    end
end
K     = spm_cat(K);

% lagged matix form
%--------------------------------------------------------------------------
for i = 1:nn
    for j = 1:nn
        KK{i,j}    = zeros(nn,np);
        for p = 1:np
            t = (1 + p):size(k,1);
            KK{i,j}(t,p) = k(t - p,i,j);
        end
    end
end
KK    = spm_cat(KK);

% predicted MAR coefficients
%--------------------------------------------------------------------------
y     = spm_inv(KK'*Vu*KK + Vn)*(KK'*Vu*K + Rn);


function I = getPcontrolCurrentPack(t,t0,tf,x,param,extra)
%	getPcontrolCurrentPack returns the value of the input current as a function of
%	the time, states and parameters
%
%       I = getPcontrolCurrentPack(t,t0,tf,y,param,extra)
%
%       Inputs:
%               - t         : value of the current time step
%               - t0        : initial integration time
%               - tf        : final integration time
%               - x         : contains the array of all the states
%                             (differential and algebraic) at time t
%               - param     : contains the parameters structure
%               - extra     : extra parameters
%       Outputs:
%               - I     : Applied current desnity [A/m^2]

%   This file is part of the LIONSIMBA Toolbox
%
%	Official web-site: 	http://sisdin.unipv.it/labsisdin/lionsimba.php
% 	Official GitHUB: 	https://github.com/lionsimbatoolbox/LIONSIMBA
%
%   LIONSIMBA: A Matlab framework based on a finite volume model suitable for Li-ion battery design, simulation, and control
%   Copyright (C) 2016-2018 :Marcello Torchio, Lalo Magni, Davide Raimondo,
%                            University of Pavia, 27100, Pavia, Italy
%                            Bhushan Gopaluni, Univ. of British Columbia,
%                            Vancouver, BC V6T 1Z3, Canada
%                            Richard D. Braatz,
%                            Massachusetts Institute of Technology,
%                            Cambridge, Massachusetts 02142, USA
%
%   Main code contributors to LIONSIMBA 2.0:
%                           Ian Campbell, Krishnakumar Gopalakrishnan,
%                           Imperial college London, London, UK
%
%   LIONSIMBA is a free Matlab-based software distributed with an MIT
%   license.

% This script provides the value of the applied current density as a
% function of the voltage across the battery pack.

% Firstly we extract the variables related to the first and second cell. To
% this aim the field x_indices of the param structure contains the values
% of the absolute positionong of the variables in the overall x array.
% Indeed, when running simulations with multiple cells, the states array
% (x) will contain as many rows - for a given time instant t - as the sum
% of the states of all the cells involved in the simulation. x_indices
% stores, for each cell, what are the indices of the overall x in which the
% variables of a given cell are stored.

% Extract the first cell variables
cell1_variables = x(param{1}.x_index);
% Extract the second cell variables
cell2_variables = x(param{2}.x_index);

% At this stage, since we have put the variables of the 2 cells into
% cell1_variables and cell2_variables, use their relative indices to
% extract the exact values.

% Cell 1 voltage
V_1 = cell1_variables(param{1}.Phis_indices(1))-cell1_variables(param{1}.Phis_indices(end));

% Cell 2 voltage
V_2 = cell2_variables(param{2}.Phis_indices(1))-cell2_variables(param{2}.Phis_indices(end));

% Define the proportional action. Do not put extreme values, the simulator
% could crash
Kp = 100;

% Define the Voltage Setpoint
V_ref = 8.2;
% Define your linear or nonlinear function of t for evaluate the value
% of I.
I = Kp*(V_ref-(V_1+V_2));

end


function r = isfinite(p)
%ISFINITE     Logical result:  polynomial p contains only finite components, y/n
%
%   r = isfinite(p)
%
%Result 1 iff all coefficients of p are finite
%

% written  08/07/02     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  r = all(isfinite(p.c));


function obj = addNodeCost(obj, func, deps, nodes, auxdata, load_path)
    % Add a cost function that only depends on variables at a particular
    % node. The input argument ''nodes'' will specify at which nodes the
    % function is defined.
    %
    % @note This function provides a simple type of cost function which
    % dependends only on variables at some particular node. If multiple
    % nodes are specified, the final cost function will be the sum of the
    % function computated at each node.
    %
    % @attention In the case the cost function dependes on variables at
    % different nodes, please use the basic ''addCost'' method directly.
    %
    % @attention This method can be used to add any terminal cost function
    % by specify ''nodes'' as either ''first'' or ''last''.
    %
    % Parameters:
    % func: a symbolic function to be integrated @type SymFunction
    % deps: a list of dependent variables @type cellstr
    % node: an indicator of 'first' or 'last' node @type char
    % auxdata: auxilary constant data to be feed in the function
    % @type double

    % basic information of NLP decision variables
    nNode  = obj.NumNode;
    vars   = obj.OptVarTable;
    if ~iscell(deps), deps = {deps}; end

    assert(isa(func,'SymFunction'),...
        'The second argument must be a SymFunction object.'); %#ok<PSIZE>

    if nargin < 5
        auxdata = [];
    else
        if ~iscell(auxdata), auxdata = {auxdata}; end
    end

    if nargin < 6
        load_path = [];
    end

    if ~isempty(load_path)
        load(func,load_path);
    end
    siz = size(func);
    assert(prod(siz)==1,...
        'The cost function must be a scalar function.'); %#ok<PSIZE>

    if ischar(nodes)
        switch nodes
            case 'first'
                node_list = 1;
            case 'last'
                node_list = nNode;
            case 'except-first'
                node_list = 2:nNode;
            case 'except-last'
                node_list = 1:nNode-1;
            case 'except-terminal'
                node_list = 2:nNode-1;
            case 'all'
                node_list = 1:nNode;
            case 'cardinal'
                node_list = 1:2:nNode;
            case 'interior'
                node_list = 2:2:nNode-1;
            otherwise
                error('Unknown node type.');
        end
    else
        if ~isnumeric(nodes)
            error(['The node must be specified as a list or following supported characters:\n',...
                '%s'],implode({'first','last','all','except-first','except-last','except-terminal', 'cardinal', 'interior'},','));
        else
            node_list = nodes;
        end
    end

    n_node = numel(node_list);
    cost(n_node) = struct();
    [cost.Name] = deal(func.Name);
    [cost.Dimension] = deal(1);
    [cost.SymFun] = deal(func);
    [cost.AuxData] = deal(auxdata);
    for i=1:n_node
        idx = node_list(i);
        dep_vars = cellfun(@(x)vars.(x)(idx),deps,'UniformOutput',false);
        cost(i).DepVariables = vertcat(dep_vars{:});
    end

    obj = addCost(obj,func.Name,nodes,cost);
end


function capproach_prt(jdtdb)

% print closest approach conditions

% Orbital Mechanics with MATLAB

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

global au drsaved iplanet1 iplanet2 pnames

% convert julian day to calendar date and time strings

[cdstr, utstr] = jd2str(jdtdb);

% create text string

textstr = horzcat('time and conditions at closest approach between ', ...
    deblank(pnames(iplanet1, 1:7)), ' and ', deblank(pnames(iplanet2, 1:7)));

fprintf('\n\n');

disp(textstr);
fprintf('===============================================================\n\n');

fprintf('calendar date                ');

disp(cdstr);

fprintf('\nTDB time                     ');

disp(utstr);

fprintf('\nTDB Julian date              %16.8f \n', jdtdb);

jdutc = tdb2utc (jdtdb);

[cdstr, utstr] = jd2str(jdutc);

fprintf('\nUTC time                     ');

disp(utstr);

fprintf('\nUTC Julian date              %16.8f \n\n', jdutc);

% display heliocentric distance (kilometers and AU)

fprintf('close approach distance      %16.6f kilometers\n', drsaved);

fprintf('                             %16.12f AU\n', drsaved / au);


function f = addBreaks(f, breaks, tol)
%ADDBREAKS   Add breakpoints to the domain of a CHEBFUN.
%   ADDBREAKS(F, BREAKS) attempts to insert breakpoints in F at the points in
%   the vector BREAKS.  BREAKS need not be sorted or have only unique values,
%   but it should consist only of points in the domain of F.  Breakpoints will
%   not be inserted if they are too close together or too close to existing
%   breakpoints.
%
%   ADDBREAKS(F, BREAKS, TOL) does the same but uses the tolerance TOL as a
%   lower bound for the tolerance used in deciding if breakpoints are too close
%   to each other or to existing ones to qualify for insertion.
%
% See also ADDBREAKSATROOTS.

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

% Lower bound for tolerance:
if ( nargin == 2 )
    tol = 0;
end

% Since each column of an array-valued CHEBFUN must have the same breakpoints,
% we simply take unique(breaks(:)).
breaks = unique(breaks(:));

% Get rid of new breakpoints at infinity:
breaks( isinf(breaks) ) = [];

% Get rid of new breakpoints at infinity:
domain = f.domain( isfinite(f.domain) );

% Set a tolerance:
breakTol = max(100*eps*max(min(diff(domain)), 1), tol);

% Distance between new breakpoints and existing ones:
dist = abs(bsxfun(@minus, breaks, domain));

% Avoid introducing new breakpoints close to existing ones:
% Note that: 1. In case of [-Inf Inf], DIST is empty.
%            2. In case of [a Inf] or [-Inf b], BREAKTOL is empty.
if ( ~isempty(dist) && ~isempty(breakTol) )
    breaks( any(dist < breakTol, 2) ) = [];
end

% Add new breaks if required:
if ( ~isempty(breaks) )
    % Get the domain with the new breakpoints: (union is not required, by above)
    dom = unique([f.domain, breaks.']);

    % Handle periodic functions:
    if ( isPeriodicTech(f) )
        f = chebfun(f);
    end

    % Introduce these breakpoints into f:
    f = restrict(f, dom);
end

end


%% Export calibration data (corners + 3D coordinates) to
%% text files (in Willson-Heikkila's format or Zhang's format)

%% Thanks to Michael Goesele (from the Max-Planck-Institut) for the original suggestion
%% of adding this export function to the toolbox.

if ~exist('n_ima'),
   fprintf(1,'ERROR: No calibration data to export\n');

else

    if n_ima == 0,
        fprintf(1,'ERROR: No calibration data to export\n');
        return;
    end;

	check_active_images;

	check_extracted_images;

	check_active_images;

   fprintf(1,'Tool that exports calibration data to Willson-Heikkila or Zhang formats\n');

   qformat = -1;

   while (qformat ~=0)&(qformat ~=1),

      fprintf(1,'Two possible formats of export: 0=Willson and Heikkila, 1=Zhang\n')
      qformat = input('Format of export (enter 0 or 1): ');

      if isempty(qformat)
         qformat = -1;
      end;

      if (qformat ~=0)&(qformat ~=1),

         fprintf(1,'Invalid entry. Try again.\n')

      end;

   end;

   if qformat == 0,

		fprintf(1,'\nExport of calibration data to text files (Willson and Heikkila''s format)\n');
		outputfile = input('File basename: ','s');

		for kk = ind_active,

   		eval(['X_kk = X_' num2str(kk) ';']);
      	eval(['x_kk = x_' num2str(kk) ';']);

         Xx = [X_kk ; x_kk]';

			file_name = [outputfile num2str(kk)];

			disp(['Exporting calibration data (3D world + 2D image coordinates) of image ' num2str(kk) ' to file ' file_name '...']);

         eval(['save ' file_name ' Xx -ASCII']);

   	end;

   else

      fprintf(1,'\nExport of calibration data to text files (Zhang''s format)\n');
      modelfile = input('File basename for the 3D world coordinates: ','s');
      datafile = input('File basename for the 2D image coordinates: ','s');

      for kk = ind_active,

   		eval(['X_kk = X_' num2str(kk) ';']);
         eval(['x_kk = x_' num2str(kk) ';']);

         if ~exist(['n_sq_x_' num2str(kk)]),
            n_sq_x = 1;
            n_sq_y = size(X_kk,2);
         else
            eval(['n_sq_x = n_sq_x_' num2str(kk) ';']);
         	eval(['n_sq_y = n_sq_y_' num2str(kk) ';']);
         end;

 	      X = reshape(X_kk(1,:)',n_sq_x+1,n_sq_y+1)';
 	      Y = reshape(X_kk(2,:)',n_sq_x+1,n_sq_y+1)';
         XY = reshape([X;Y],n_sq_y+1,2*(n_sq_x+1));

         x = reshape(x_kk(1,:)',n_sq_x+1,n_sq_y+1)';
 	      y = reshape(x_kk(2,:)',n_sq_x+1,n_sq_y+1)';
         xy = reshape([x;y],n_sq_y+1,2*(n_sq_x+1));

         disp(['Exporting calibration data of image ' num2str(kk) ' to files ' modelfile num2str(kk) '.txt and ' datafile num2str(kk) '.txt...']);

         eval(['save ' modelfile num2str(kk) '.txt XY -ASCII']);
         eval(['save ' datafile num2str(kk) '.txt xy -ASCII']);

   	end;

end;

fprintf(1,'done\n');

end;


% Test manipulation of nested cell arrays

% Test nested extraction
A = {{1 {2 3}} {4 5} {6 7 8} {9 10}};
C_real = vec(1:10);
C = flatten_nested(A);
for i=length(C_real)
   if C{i}~=C_real(i)
      fprintf(1,'flatten_nested test failed\n');
      assert(false);
   end
end
fprintf(1,'flatten_nested test passed\n');

% Test nested element-wise modification
fnc = @(x)x + 1;
A = apply_to_nested(A,fnc);
C2 = flatten_nested(A);
for i=length(C_real)
   if C2{i}~=C_real(i)+1
      fprintf(1,'apply_to_nested test failed\n');
      assert(false);
   end
end
fprintf(1,'apply_to_nested test passed\n');

% MULTI-NESTED
% Test nested element-wise modification
A = { {{1} {2}} {{3} {4}} {{5} {6}} };
B = { {{-1} {-2}} {{-3} {-4}} {{-5} {-6}} };
C_real = zeros(6,1);
fnc = @(x,y) x + y;
A = multi_apply_to_nested(fnc,A,B);
C3 = flatten_nested(A);
for i=length(C_real)
   if C3{i}~=C_real(i)
      fprintf(1,'multi_apply_to_nested test failed\n');
      assert(false);
   end
end
fprintf(1,'multi_apply_to_nested test passed\n');

% MULTI-NESTED
% Test nested element-wise modification
A = { {{1} {2}} {{3} {4}} {{5} {6}} };
B = { {{-1} {-2}} {{-3} {-4}} {{-5} {-6}} };
C = { {{5} {10}} {{5} {10}} {{5} {12}} };
C_real = [5 10 5 10 5 12];
fnc = @(x,y,z) x + y + z;
A = multi_apply_to_nested(fnc,A,B,C);
C4 = flatten_nested(A);
for i=length(C_real)
   if C4{i}~=C_real(i)
      fprintf(1,'multi_apply_to_nested 3-arg test failed\n');
      assert(false);
   end
end
fprintf(1,'multi_apply_to_nested 3-arg test passed\n');


function y = Fault_decision_wr_t2(u)
global st16

% Using model defined by the structure st16 to make decision about type2 wr fault

sker=st16.x2sup+(abs(u))'*abs(u)*ones(st16.Nlsup,1)-2*st16.xsup*abs(u);
y=(st16.w)'*exp(-sker./(2*(st16.sigma).^2))+st16.b;

if y>=-0.3
    y=1;
else
    y=0;
end
end


function varargout = tan(varargin)
%TAN   Tangent of a DISKFUN.
%
% See also DISKFUN/SIN, DISKFUN/COS, DISKFUN/TANH

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

[varargout{1:nargout}] = tan@separableApprox(varargin{:});

end


function mv = mv_tuningChangeMap(mv);
%
% mv = mv_tuningChangeMap(mv);
%
% For multi-voxel UI, create a map in which the value for each voxel
% measures the change in stimulus "tuning" (i.e., the N-dimensional
% vector of response amplitudes to each of the N selected stimulus
% conditions) between that voxel and its neighbors.
%
% Note that the determination of what a voxel's neighbors are depends on
% the view:
%   Inplane views: the neighbors are neighboring 6-connected voxels in the
%                  inplane data, independent of whether these neighbors
%                  are in the gray, white matter, csf, or other;
%   Gray views:    determined using the gray graph.
%
% Flat and Volume views are not yet supported.
%
% ras, 11/05.
if ieNotDefined('mv'), mv = get(gcf, 'UserData'); end

switch mv.roi.viewType
    case 'Inplane',
        nVoxels = size(mv.coords, 2);

        % get amplitudes for each voxel
        amps = mv_amps(mv);

        % initialize map vals
        vals = zeros(1, nVoxels);

        % create an 'offset' matrix describing where neighbors in
        % 6-connected data would be -- this will be useful for finding
        % neighbor coords in the main loop:
        offsets = [-1 0 0; 1 0 0; 0 -1 0; 0 1 0; 0 0 -1; 0 0 1]';

        %%%%%main loop
        hwait = mrvWaitbar(0, 'Computing Tuning Change Map...');
        for v = 1:nVoxels
            % find indices I of neighboring voxels
            pt = mv.coords(:, v);
            neighbors = repmat(pt, [1 6]) - offsets;
            [found I] = intersectCols(mv.coords, neighbors);

            if isempty(I)
                % no neighbors contained in the multi-voxel data:
                % set value for this point to -1:
                vals(v) = -1;
            else
                % get amplitudes for this voxel, neighbors
                A = amps(v, :); % amplitudes for this voxel
                B = amps(I, :); % amplitudes for neighbors

                % compute mean Euclidean distance between A and columns
                % in B:
                diff = [B - repmat(A, [1 size(B,2)])];
                dist = sqrt(sum(diff.^2));
                vals(v) = mean(dist);
            end

            mrvWaitbar(v/nVoxels, hwait);
        end
        close(hwait);

        % Create a map volume with the tuning values
        mrGlobals; loadSession;
        hI = initHiddenInplane(mv.params.dataType, mv.params.scans(1));
        mapvol = zeros(dataSize(hI));
        mapvol(roiIndices(hI, mv.coords)) = vals;

        % export as map
        hI.map = cell(1, numScans(hI));
        hI.map{mv.params.scans(1)} = mapvol;
        hI.mapName = 'Tuning_Change_Map';
        saveParameterMap(hI, [], 1);

    case 'Gray',
        nVoxels = size(mv.coords, 2);

        % get amplitudes for each voxel
        amps = mv_amps(mv);

        % initialize map vals
        vals = zeros(1, nVoxels);

        % create an 'offset' matrix describing where neighbors in
        % 6-connected data would be -- this will be useful for finding
        % neighbor coords in the main loop:
        offsets = [-1 0 0; 1 0 0; 0 -1 0; 0 1 0; 0 0 -1; 0 0 1]';

        %%%%%main loop
        hwait = mrvWaitbar(0, 'Computing Tuning Change Map...');
        for v = 1:nVoxels
            % find indices I of neighboring voxels
            pt = mv.coords(:, v);
            neighbors = repmat(pt, [1 6]) - offsets;
            [found I] = intersectCols(mv.coords, neighbors);

            if isempty(I)
                % no neighbors contained in the multi-voxel data:
                % set value for this point to -1:
                vals(v) = -1;
            else
                % get amplitudes for this voxel, neighbors
                A = amps(v, :); % amplitudes for this voxel
                B = amps(I, :); % amplitudes for neighbors

                % compute mean Euclidean distance between A and columns
                % in B:
                diff = [B - repmat(A, [size(B,1) 1])];
                dist = sqrt(sum(diff.^2, 2));
                vals(v) = mean(dist(:));
            end

            mrvWaitbar(v/nVoxels, hwait);
        end
        close(hwait);

        % Create a map volume with the tuning values
        mrGlobals; loadSession;
        hG = initHiddenGray(mv.params.dataType, mv.params.scans(1));
        mapvol = zeros(dataSize(hG));
        mapvol(roiIndices(hG, mv.coords)) = vals;

        % export as map
        hG.map = cell(1, numScans(hG));
        hG.map{mv.params.scans(1)} = mapvol;
        hG.mapName = 'Tuning_Change_Map';
        saveParameterMap(hG, [], 1, 0);

    otherwise, % not yet supported
        error('Sorry, this view type is not yet supported.');
end

return


function test_ft_clusterplot

% MEM 12gb
% WALLTIME 00:20:00
% DEPENDENCY ft_clusterplot ft_statistics_montecarlo ft_timelockstatistics clusterstat findcluster

cd(dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/eventrelatedstatistics'));

% use the tutorial on http://www.fieldtriptoolbox.org/tutorial/eventrelatedstatistics

load ERF_orig
load GA_ERF_orig

cfg = [];
cfg.method      = 'template';
cfg.template    = 'ctf151_neighb.mat';               % specify type of template
cfg.layout      = 'CTF151.lay';                      % specify layout of sensors*
cfg.feedback    = 'yes';                             % show a neighbour plot
neighbours      = ft_prepare_neighbours(cfg, GA_FC); % define neighbouring channels

cfg = [];
cfg.channel     = 'MEG';
cfg.neighbours  = neighbours; % defined as above
cfg.latency     = [-0.25 1];
cfg.avgovertime = 'no';
cfg.parameter   = 'avg';
cfg.method      = 'montecarlo';
cfg.statistic   = 'ft_statfun_depsamplesT';
cfg.alpha       = 0.05;
cfg.correctm    = 'cluster';
cfg.correcttail = 'prob';
cfg.numrandomization = 'all';
cfg.minnbchan        = 2; % minimal neighbouring channels
Nsub = 10;
cfg.design(1,1:2*Nsub)  = [ones(1,Nsub) 2*ones(1,Nsub)];
cfg.design(2,1:2*Nsub)  = [1:Nsub 1:Nsub];
cfg.ivar                = 1; % the 1st row in cfg.design contains the independent variable
cfg.uvar                = 2; % the 2nd row in cfg.design contains the subject number
stat = ft_timelockstatistics(cfg,allsubjFIC{:},allsubjFC{:});

%% chan_time, this is the original one
cfg = [];
cfg.highlightsymbolseries = ['*','*','.','.','.'];
cfg.layout = 'CTF151.lay';
cfg.contournum = 0;
cfg.markersymbol = '.';
cfg.alpha = 0.05;
cfg.parameter='stat';
cfg.zlim = [-5 5];
cfg.toi  = [-0.1:0.1:0.9];
ft_clusterplot(cfg,stat);

%% chan_freq
stat.freq = 1:376;
cfg.toi = [20:20:200];
stat = rmfield(stat, 'time');
stat.dimord = 'chan_freq';

ft_clusterplot(cfg,stat);

%% chan_freq_time with singleton time
stat.time = 1;
stat.dimord = 'chan_freq_time';
cfg.toi = [20:20:200];

ft_clusterplot(cfg,stat);

%% chan_freq_time with singleton freq
stat.time = 1:376;
stat.freq = 1;
stat.dimord = 'chan_freq_time';

% insert the singleton dimension in the data
stat.posclusterslabelmat = reshape(stat.posclusterslabelmat, [151 1 376]);
stat.negclusterslabelmat = reshape(stat.negclusterslabelmat, [151 1 376]);
stat.prob     = reshape(stat.prob,    [151 1 376]);
stat.cirange  = reshape(stat.cirange, [151 1 376]);
stat.mask     = reshape(stat.mask,    [151 1 376]);
stat.stat     = reshape(stat.stat,    [151 1 376]);
stat.ref      = reshape(stat.ref,     [151 1 376]);

cfg.toi = [20:20:200];

ft_clusterplot(cfg,stat);


data_masterdir = GetCurrentDataDir();

range_fish = [5,6,7];
M_ClusGroup = [2,2,2,2];
M_Cluster = [1,1,1,1];

% M_fish_set = [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2];

%%
for i = 1:length(range_fish),
    i_fish = range_fish(i);
    disp(i_fish);

    LoadFullFish(hfig,i_fish);

    absIX = getappdata(hfig,'absIX');

    %% Cluster indexing
    i_ClusGroup = M_ClusGroup(i);
    i_Cluster = M_Cluster(i);
    Cluster = VAR(i_fish).ClusGroup{i_ClusGroup};
    numK = Cluster(i_Cluster).numK;
    gIX = Cluster(i_Cluster).gIX;

    cIX_abs = Cluster(i_Cluster).cIX_abs; % convert absolute index to index used for this dataset
    [~,cIX] = ismember(cIX_abs,absIX);
    setappdata(hfig,'cIX',cIX);
    toc

    %%
    periods = getappdata(hfig,'periods');
    if length(periods)>1,
        setappdata(hfig,'stimrange',1:length(periods));
    else
        setappdata(hfig,'stimrange',1);
    end
    UpdateTimeIndex(hfig); % set M_0
    M_0 = getappdata(hfig,'M_0');

    %%
    f.UpdateIndices(hfig,cIX,gIX,numK);

    %%
    isWkmeans = 1;
    AutoClustering(cIX,gIX,absIX,i_fish,M_0,isWkmeans)
end


function dpts = move_pts(pts, By, Bx)
dpts = pts;
for j = 1 : size(pts, 2)
    r = ceil(pts(1, j));
    c = ceil(pts(2, j));
    dpts(1, j) = dpts(1, j) + By(r, c);
    dpts(2, j) = dpts(2, j) + Bx(r, c);
end


function p = convert_perspective_log(p)

p.kept = 1:length(p.c);
if isempty(p.evalMap)
    return
end

if ~any(p.variabletype == 4)
    return
end

variableIndex = [];
for i=1:length(p.evalMap)
    variableIndex = [variableIndex p.evalMap{i}.variableIndex];
end

removable = [];
for i = 1:length(p.evalMap)
    if strcmp(p.evalMap{i}.fcn,'log')
        argument = p.evalMap{i}.variableIndex;
        if length(argument) == 1
            if p.variabletype(argument)==4
                monoms = p.monomtable(argument,:);
                if nnz(monoms) == 2
                    k = find(monoms);
                    p1 = monoms(k(1));
                    p2 = monoms(k(2));
                    if isequal(sort([p1 p2]) , [-1 1])
                        if p2>p1
                            x = k(2);
                            y = k(1);
                        else
                            x = k(1);
                            y = k(2);
                        end
                        % Ok, so we have log(x/y)
                        % is this multiplied by x somewhere
                        logxy = p.evalMap{i}.computes;
                        enters_in = find(p.monomtable(:,logxy));
                        other = setdiff(enters_in,p.evalMap{i}.computes);
                        if length(nnz(other)) == 1
                            monomsxlog = p.monomtable(other,:);
                            if nnz(monomsxlog) == 2 & (monomsxlog(x) == 1)
                                % Hey, x*log(x/y)!
                                % we change this monomial variable to a
                                % callback variable
                                p.evalMap{i}.fcn = 'negated_perspective_log';
                                p.evalMap{i}.arg{1} = recover([x;y]);
                                p.evalMap{i}.arg{2} = [];
                                p.evalMap{i}.variableIndex = [x y];
                                p.evalMap{i}.computes = other;
                                p.evalMap{i}.properties.bounds = @nplog_bounds;
                                p.evalMap{i}.properties.convexhull = @nplog_convexhull;
                                p.evalMap{i}.properties.derivative = @nplog_derivative;
                                p.evalMap{i}.properties.inverse = [];
                                p.variabletype(other) = 0;
                                p.monomtable(other,:) = 0;
                                p.monomtable(other,other) = 1;
                                p.evalVariables(i) = other;
                                % Figure out if x/y can be removed
                                % This is possible if the x/y term never is
                                % used besides inside the log term
                                if nnz(p.F_struc(:,1+argument)) == 1 & p.c(argument) == 0 & nnz(argument == variableIndex) == 1
                                    removable = [removable argument];
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
kept = 1:length(p.c);
kept = setdiff(kept,removable);
aux_used = zeros(1,length(p.c));
aux_used(p.aux_variables) = 1;
aux_used(removable)=[];
p.aux_variables = find(aux_used);
if length(removable) > 0
    kept = 1:length(p.c);
    kept = setdiff(kept,removable);
    [ii,jj,kk] = find(p.F_struc(:,1+removable));
    p.F_struc(:,1+removable) = [];
    p.F_struc(ii,:) = [];
    p.K.l = p.K.l - length(removable);
    p.c(removable) = [];
    p.Q(removable,:) = [];
    p.Q(:,removable) = [];
    p.variabletype(removable) = [];
    p.monomtable(:,removable) = [];
    p.monomtable(removable,:) = [];
    for i = 1:length(p.evalVariables)
        p.evalVariables(i) = find(p.evalVariables(i) == kept);
        for j = 1:length(p.evalMap{i}.variableIndex)
           p.evalMap{i}.variableIndex(j) = find(p.evalMap{i}.variableIndex(j) == kept);
        end
        for j = 1:length(p.evalMap{i}.computes)
           p.evalMap{i}.computes(j) = find(p.evalMap{i}.computes(j) == kept);
        end
    end
    p.lb(removable) = [];
    p.ub(removable) = [];
    p.used_variables(removable) = [];
end

function dp = nplog_derivative(x)
dp = [log(x(1)/x(2)) + 1;-x(1)/x(2)];

function [L,U] = nplog_bounds(xL,xU)
xU(isinf(xU)) = 1e12;
x1 = xL(1)*log(xL(1)/xL(2));
x2 = xU(1)*log(xU(1)/xL(2));
x3 = xL(1)*log(xL(1)/xU(2));
x4 = xU(1)*log(xU(1)/xU(2));
U = max([x1 x2 x3 x4]);
if (exp(-1)*xU(2) > xL(1)) & (exp(-1)*xU(2) < xU(1))
    L = -exp(-1)*xU(2);
else
    L = min([x1 x2 x3 x4]);
end

function [Ax,Ay,b,K] = nplog_convexhull(xL,xU);

x1 = [xL(1);xL(2)];
x2 = [xU(1);xL(2)];
x3 = [xL(1);xU(2)];
x4 = [xU(1);xU(2)];
x5 = (xL+xU)/2;

f1 = negated_perspective_log(x1);
f2 = negated_perspective_log(x2);
f3 = negated_perspective_log(x3);
f4 = negated_perspective_log(x4);
f5 = negated_perspective_log(x5);

df1 = nplog_derivative(x1);
df2 = nplog_derivative(x2);
df3 = nplog_derivative(x3);
df4 = nplog_derivative(x4);
df5 = nplog_derivative(x5);

[Ax,Ay,b,K] = convexhullConvex2D(x1,f1,df1,x2,f2,df2,x3,f3,df3,x4,f4,df4,x5,f5,df5);


function [ Acc ] = cssp_off2on(CNT,general_initparam,tau)

opt = opt_cellToStruct(general_initparam);
% Pre-processing
train_raw = prep_selectChannels(CNT{1}, {'Index', opt.channel_index});
train_cnt =prep_filter(train_raw  , {'frequency', opt.band});
train_smt = prep_segmentation(train_cnt, {'interval', opt.time_interval});

test_raw= prep_selectChannels(CNT{2}, {'Index', opt.channel_index});
test_cnt =prep_filter(test_raw , {'frequency', opt.band});
test_smt = prep_segmentation(test_cnt, {'interval', opt.time_interval});

% Feature extracion and Classification
for len_tau=1:length(tau)
    CV.train={
        '[SMT, CSP_W, CSP_D]=func_csp(SMT,{"nPatterns", [2]})'
        'FT=func_featureExtraction(SMT, {"feature","logvar"})'
        '[CF_PARAM]=func_train(FT,{"classifier","LDA"})'
        };
    CV.test={
        'SMT=func_projection(SMT, CSP_W)'
        'FT=func_featureExtraction(SMT, {"feature","logvar"})'
        '[cf_out]=func_predict(FT, CF_PARAM)'
        };
    CV.option={
        'KFold','10'
        };
    SMT=func_TDE(train_smt,train_cnt,tau(len_tau),opt.time_interval);
    [loss]=eval_crossValidation(SMT, CV); % input : eeg, or eeg_epo
    tau_result(1,len_tau)=1-loss;
end
[acc_cv,max_tau]=max(tau_result);
ttau=tau(max_tau);

SMT_tr=func_TDE(train_smt,train_cnt,ttau,opt.time_interval);
[SMT_tr, CSP_W, CSP_D]=func_csp(SMT_tr,{'nPatterns', opt.CSPFilter});
FT_tr=func_featureExtraction(SMT_tr, {'feature','logvar'});
[CF_PARAM]=func_train(FT_tr,{'classifier','LDA'});

SMT_te=func_TDE(test_smt,test_cnt,ttau,opt.time_interval);
SMT_te=func_projection(SMT_te, 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);
Acc=1-loss';
end


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

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

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


function [spectrogramPosition, tracePosition] = calculatePanelPositions(numchannels, channelNum, fractionalSpectrogramHeight, frameLeft, frameBottom, totalWidth, totalHeight);
debug.printfunctionstack('>');
channelHeight 		= totalHeight/numchannels;
spectrogramHeight 	= fractionalSpectrogramHeight * channelHeight;
traceHeight 		= channelHeight - spectrogramHeight;
spectrogramBottom   = frameBottom + (numchannels - channelNum) * channelHeight;
traceBottom         = spectrogramBottom + spectrogramHeight;
spectrogramPosition = [frameLeft, spectrogramBottom, totalWidth, spectrogramHeight];
tracePosition 		= [frameLeft, traceBottom      , totalWidth, traceHeight];
debug.printfunctionstack('<');


function [ o, x, w ] = en_r2_09_1 ( n, option )

%*****************************************************************************80
%
%% EN_R2_09_1 implements the Stroud rule 9.1 for region EN_R2.
%
%  Discussion:
%
%    The rule has order O = ( 2 * N^4 - 4 * N^3 + 22 * N^2 - 8 * N + 3 ) / 3.
%
%    The rule has precision P = 9.
%
%    EN_R2 is the entire N-dimensional space with weight function
%
%      w(x) = exp ( - x1^2 - x2^2 ... - xn^2 )
%
%    There are two versions of each rule, chosen by setting the
%    OPTION variable to 1 or 2.
%
%    The rule as tabulated by Stenger is available for N = 2 through 20.
%    This function accepts N = 3 through 6.
%
%     N    O
%    __  ___
%     3   77
%     4  193
%     5  421
%     6  825
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 January 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Arthur Stroud,
%    Approximate Calculation of Multiple Integrals,
%    Prentice Hall, 1971,
%    ISBN: 0130438936,
%    LC: QA311.S85.
%
%  Parameters:
%
%    Input, integer N, the spatial dimension.
%    3 <= N <= 6.
%
%    Input, integer OPTION, chooses rule option 1 or 2.
%
%    Output, integer O, the order.
%
%    Output, real X(N,O), the abscissas.
%
%    Output, real W(O), the weights.
%
  if ( n < 3 | 6 < n )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'EN_R2_09_1 - Fatal error!\n' );
    fprintf ( 1, '  3 <= N <= 6 required.\n' );
    error ( 'EN_R2_09_1 - Fatal error!' )
  end

  if ( nargin < 2 )
    option = 1;
  end

  if ( option < 1 | 2 < option )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'EN_R2_09_1 - Fatal error!\n' );
    fprintf ( 1, '  1 <= OPTION <= 2 required.\n' );
    error ( 'EN_R2_09_1 - Fatal error!' )
  end

  o = ( 2 * n^4 - 4 * n^3 + 22 * n^2 - 8 * n + 3 ) / 3;
  volume = sqrt ( pi^n );

  if ( n == 3 )
    u =    0.202018287045609E+01;
    v =    0.958572464613819E+00;
    b0 =   0.676448734429924E+00;
    b1 =   0.511989106291551E-02;
    b2 =   0.448595723493744E+00;
    b3 =   0.235223454595606E-03;
    b4 =   0.915390713080005E-01;
    b5 =   0.139208199920793E-01;
    b6 =   0.235223454595606E-03;
    b7 =   0.915390713080008E-01;
    b8 =   0.000000000000000E+00;
  elseif ( n == 4 & option == 1 )
    u =    0.202018287045609E+01;
    v =    0.958572464613819E+00;
    b0 = - 0.860452945007048E+00;
    b1 = - 0.405511998533795E-01;
    b2 =   0.107026475449715E+01;
    b3 =   0.138974239307092E-03;
    b4 = - 0.162248779448181E+00;
    b5 =   0.246740110027234E-01;
    b6 =   0.138974239307094E-03;
    b7 =   0.162248779448181E+00;
    b8 =   0.138974239307094E-03;
  elseif ( n == 4 & option == 2 )
    u =    0.958572464613819E+00;
    v =    0.202018287045609E+01;
    b0 =   0.265029088766810E-02;
    b1 =   0.637601342635332E+00;
    b2 = - 0.394394059389228E-01;
    b3 =   0.540829264827264E-01;
    b4 = - 0.416922717921281E-03;
    b5 =   0.246740110027234E-01;
    b6 =   0.540829264827270E-01;
    b7 =   0.416922717921281E-03;
    b8 =   0.540829264827269E-01;
  elseif ( n == 5 & option == 1 )
    u =    0.202018287045609E+01;
    v =    0.958572464613819E+00;
    b0 = - 0.827347006200826E+01;
    b1 = - 0.160820174530905E+00;
    b2 =   0.353499863758467E+01;
    b3 =   0.738976276909564E-03;
    b4 = - 0.862735421812943E+00;
    b5 =   0.437335458190621E-01;
    b6 = - 0.246325425636523E-03;
    b7 =   0.287578473937648E+00;
    b8 =   0.246325425636523E-03;
  elseif ( n == 5 & option == 2 )
    u =    0.958572464613819E+00;
    v =    0.202018287045609E+01;
    b0 = - 0.624416791055272E+00;
    b1 =   0.467494915583104E+00;
    b2 = - 0.152937760910536E+00;
    b3 =   0.287578473937646E+00;
    b4 = - 0.221692883072871E-02;
    b5 =   0.437335458190621E-01;
    b6 = - 0.958594913125490E-01;
    b7 =   0.738976276909568E-03;
    b8 =   0.958594913125492E-01;
  elseif ( n == 6 & option == 1 )
    u =    0.202018287045609E+01;
    v =    0.958572464613819E+00;
    b0 = - 0.361840434143098E+02;
    b1 = - 0.447936529138517E+00;
    b2 =   0.112077863004144E+02;
    b3 =   0.392940404320855E-02;
    b4 = - 0.254859786784158E+01;
    b5 =   0.775156917007496E-01;
    b6 = - 0.130980134773619E-02;
    b7 =   0.509719573568315E+00;
    b8 =   0.436600449245395E-03;
  elseif ( n == 6 & option == 2 )
    u =    0.958572464613819E+00;
    v =    0.202018287045609E+01;
    b0 =   0.448873836333650E+01;
    b1 = - 0.238473566140736E+01;
    b2 = - 0.413008493198885E+00;
    b3 =   0.152915872070494E+01;
    b4 = - 0.654900673868093E-02;
    b5 =   0.775156917007496E-01;
    b6 = - 0.509719573568314E+00;
    b7 =   0.130980134773618E-02;
    b8 =   0.169906524522772E+00;
  end

  x = zeros(n,o);
  w = zeros(o,1);

  k = 0;
%
%  1 point.
%
  k = k + 1;
% x(1:n,k) = 0.0;
  w(k) = b0;
%
%  2 * N points.
%
  for i = 1 : n
    k = k + 1;
    x(i,k) = - u;
    w(k) = b1;
    k = k + 1;
    x(i,k) = + u;
    w(k) = b1;
  end
%
%  2 * N points.
%
  for i = 1 : n
    k = k + 1;
    x(i,k) = - v;
    w(k) = b2;
    k = k + 1;
    x(i,k) = + v;
    w(k) = b2;
  end
%
%  4 * ( N * ( N - 1 ) / 2 ) points.
%
  for i = 1 : n - 1
    for j = i + 1 : n
      k = k + 1;
      x(i,k) = - u;
      x(j,k) = - u;
      w(k) = b3;
      k = k + 1;
      x(i,k) = - u;
      x(j,k) = + u;
      w(k) = b3;
      k = k + 1;
      x(i,k) = + u;
      x(j,k) = - u;
      w(k) = b3;
      k = k + 1;
      x(i,k) = + u;
      x(j,k) = + u;
      w(k) = b3;
    end
  end
%
%  4 * ( N * ( N - 1 ) / 2 ) points.
%
  for i = 1 : n - 1
    for j = i + 1 : n
      k = k + 1;
      x(i,k) = - v;
      x(j,k) = - v;
      w(k) = b4;
      k = k + 1;
      x(i,k) = - v;
      x(j,k) = + v;
      w(k) = b4;
      k = k + 1;
      x(i,k) = + v;
      x(j,k) = - v;
      w(k) = b4;
      k = k + 1;
      x(i,k) = + v;
      x(j,k) = + v;
      w(k) = b4;
    end
  end
%
%  4 * ( N * ( N - 1 ) ) points.
%
  for i = 1 : n - 1
    for j = i + 1 : n
      k = k + 1;
      x(i,k) = - u;
      x(j,k) = - v;
      w(k) = b5;
      k = k + 1;
      x(i,k) = - u;
      x(j,k) = + v;
      w(k) = b5;
      k = k + 1;
      x(i,k) = + u;
      x(j,k) = - v;
      w(k) = b5;
      k = k + 1;
      x(i,k) = + u;
      x(j,k) = + v;
      w(k) = b5;
      k = k + 1;
      x(i,k) = - v;
      x(j,k) = - u;
      w(k) = b5;
      k = k + 1;
      x(i,k) = - v;
      x(j,k) = + u;
      w(k) = b5;
      k = k + 1;
      x(i,k) = + v;
      x(j,k) = - u;
      w(k) = b5;
      k = k + 1;
      x(i,k) = + v;
      x(j,k) = + u;
      w(k) = b5;
    end
  end
%
%  8 * ( N * ( N - 1 ) * ( N - 2 ) / 6 ) points.
%
  for i = 1 : n - 2
    for j = i + 1 : n - 1
      for l = j + 1 : n
        k = k + 1;
        x(i,k) = - u;
        x(j,k) = - u;
        x(l,k) = - u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = - u;
        x(j,k) = - u;
        x(l,k) = + u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = - u;
        x(j,k) = + u;
        x(l,k) = - u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = - u;
        x(j,k) = + u;
        x(l,k) = + u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = + u;
        x(j,k) = - u;
        x(l,k) = - u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = + u;
        x(j,k) = - u;
        x(l,k) = + u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = + u;
        x(j,k) = + u;
        x(l,k) = - u;
        w(k) = b6;
        k = k + 1;
        x(i,k) = + u;
        x(j,k) = + u;
        x(l,k) = + u;
        w(k) = b6;
      end
    end
  end
%
%  8 * ( N * ( N - 1 ) * ( N - 2 ) / 6 ) points.
%
  for i = 1 : n - 2
    for j = i + 1 : n - 1
      for l = j + 1 : n
        k = k + 1;
        x(i,k) = - v;
        x(j,k) = - v;
        x(l,k) = - v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = - v;
        x(j,k) = - v;
        x(l,k) = + v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = - v;
        x(j,k) = + v;
        x(l,k) = - v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = - v;
        x(j,k) = + v;
        x(l,k) = + v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = + v;
        x(j,k) = - v;
        x(l,k) = - v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = + v;
        x(j,k) = - v;
        x(l,k) = + v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = + v;
        x(j,k) = + v;
        x(l,k) = - v;
        w(k) = b7;
        k = k + 1;
        x(i,k) = + v;
        x(j,k) = + v;
        x(l,k) = + v;
        w(k) = b7;
      end
    end
  end
%
%  16 * ( N * ( N - 1 ) * ( N - 2 ) * ( N - 3 ) / 24 ) points.
%
  for i = 1 : n - 3
    for j = i + 1 : n - 2
      for l = j + 1 : n - 1
        for m = l + 1 : n
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = - u;
          x(l,k) = - u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = - u;
          x(l,k) = - u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = - u;
          x(l,k) = + u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = - u;
          x(l,k) = + u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = + u;
          x(l,k) = - u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = + u;
          x(l,k) = - u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = + u;
          x(l,k) = + u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = - u;
          x(j,k) = + u;
          x(l,k) = + u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = - u;
          x(l,k) = - u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = - u;
          x(l,k) = - u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = - u;
          x(l,k) = + u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = - u;
          x(l,k) = + u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = + u;
          x(l,k) = - u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = + u;
          x(l,k) = - u;
          x(m,k) = + u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = + u;
          x(l,k) = + u;
          x(m,k) = - u;
          w(k) = b8;
          k = k + 1;
          x(i,k) = + u;
          x(j,k) = + u;
          x(l,k) = + u;
          x(m,k) = + u;
          w(k) = b8;
        end
      end
    end
  end

  return
end


function spm_dem_cue_movie(DEM,q)
% creates a movie of cued pointing
% FORMAT spm_dem_cue_movie(DEM,q)
%
% DEM - DEM structure from reaching simulations
% q   - flag switching from true to perceived reaching
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_dem_cue_movie.m 4230 2011-03-07 20:58:38Z karl $

% Dimensions
%--------------------------------------------------------------------------
N    = size(DEM.pU.x{1},2);
n    = size(DEM.pP.P{1},2);

% evaluate true location (targets)
%----------------------------------------------------------------------
for i = 1:N
    L(:,:,i) = DEM.pP.P{1};
end

if nargin > 1

    % evaluate perceived positions (motor plant)
    %----------------------------------------------------------------------
    x    = tan(DEM.qU.x{1}(1:2,:));                  % finger location
    c    = DEM.qU.x{1}(2 + (1:n),:);                 % target contrast

else

    % evaluate true positions (motor plant)
    %----------------------------------------------------------------------
    x    = tan(DEM.pU.x{1}(1:2,:));                  % finger location
    c    = DEM.pU.x{1}(2 + (1:n),:);                 % target contrast

end
c    = c - min(c(:)) + 1/32;
c    = c/max(c(:));
fin  = imread('pointfinger.jpg');

% movie
%--------------------------------------------------------------------------
s     = 2;
for i = 1:N

    cla
    axis image ij
    hold on

    % finger
    %----------------------------------------------------------------------
    imagesc(([-1 0] + .68)*s + x(1,i),([-1 0] + .96)*s + x(2,i),fin);
    hold on

    % trajectory
    %----------------------------------------------------------------------
    plot(x(1,1:i),x(2,1:i),'k:')

    % targets
    %----------------------------------------------------------------------
    for j = 1:n
        plot(L(1,j,i),L(2,j,i),'.','MarkerSize',64,'color',[c(j,i) (1 - c(j,i)) 0])
    end
    axis([-1 1 -1 1]*2)
    hold off
    drawnow

    % save
    %----------------------------------------------------------------------
    M(i) = getframe(gca);

end

% set ButtonDownFcn
%--------------------------------------------------------------------------
h = findobj(gca,'type','image');
set(h(1),'Userdata',{M,16})
set(h(1),'ButtonDownFcn','spm_DEM_ButtonDownFcn')


function cmap = polarmap(varargin)
%POLARMAP Polarized color map
%	POLARMAP applies a "polarized" blue-white-red colormap to current figure,
%	and adjusts the color axis limits to be centered to zero.
%
%	POLARMAP(M) fixes the number of colors to M (default is 64).
%
%	POLARMAP(MAP) applies linear shading to white to the center of colormap
%	MAP which can be any of existing colormaps (an Mx3 matrix of RGB).
%
%	POLARMAP(MAP,C) uses exponent C to modify the shading contrast. Default
%	is C = 1 for linear shading. Use C = 2 to strengthen the shading, or
%	C = 0.5 to attenuate it.
%
%	C=POLARMAP(...) returns an M-by-3 matrix containing the colormap, that
%	can be used with COLORMAP function like other colormaps.
%
%	Examples:
%		pcolor(peaks), shading interp
%		polarmap, colorbar
%
%	then try the following
%		polarmap(jet,0.5)
%
%	Note the polar shading has no real interest with colormaps that include
%	white color as one of the extremes (like GRAY, BONE, HOT, ...).
%
%	See also JET, HSV, COPPER, SPRING, SUMMER, WINTER, COOL, COLORMAP, RGBPLOT.
%
%	Author: Francois Beauducel, IPGP
%	Created: 2011-10-26
%	Updated: 2012-06-12

%	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.

% default parameters
m = 64;	% number of colors
c = 1;	% exponent of shading factor (1 = linear)

if nargin > 0
	if ~isnumeric(varargin{1}) | (size(varargin{1},2) ~= 3 & ~isscalar(varargin{1}))
		error('First argument must be numeric: scalar M or Mx3 color matrix');
	end
	if isscalar(varargin{1})
		m = varargin{1};
	end
end
if nargin > 0 & size(varargin{1},2) == 3
		map = varargin{1};
		m = size(map,1);
else
	map = bluered(m);
end

if nargin > 1 & isscalar(varargin{2})
	c = varargin{2};
end

% linear shading from min/max (colormap value) to center (white)
r = repmat(abs(linspace(1,-1,m)).^c,[3,1])';
map = map.*r + 1 - r;

if nargout > 0
	cmap = map;
else
	colormap(map)
	caxis([-1,1]*max(abs(caxis)))
	% Note: this fixes color axis to manual mode...
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function map = bluered(m)

if mod(m,2)
	z = [0,0,0];
	m2 = floor(m/2);
else
	z = zeros([0,3]);
	m2 = m/2;
end
map = [repmat([0,0,1],[m2,1]);z;repmat([1,0,0],[m2,1])];


function [ft] = dm2ft(dm)
% Convert length from decimeters to feet.
% Chad A. Greene 2012
ft = dm*0.3280839895013;


function sparse_grid_mixed_write_tests ( )

%*****************************************************************************80
%
%% SPARSE_GRID_MIXED_WRITE_TESTS calls SPARSE_GRID_MIXED_WRITE with various arguments.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 March 2011
%
%  Author:
%
%    John Burkardt
%
%  Local Parameters:
%
%    Local, real TOL, a tolerance for point equality.
%    A value of sqrt ( eps ) is reasonable, and will allow the code to
%    consolidate points which are equal, or very nearly so.  A value of
%    -1.0, on the other hand, will force the code to use every point, regardless
%    of duplication.
%
  addpath ( '../sandia_rules' );

  tol = sqrt ( eps );

  fprintf ( 1, '\n' );
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPARSE_GRID_MIXED_WRITE_TESTS\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Call SPARSE_GRID_MIXED_WRITE_TEST with various arguments.\n' );
  fprintf ( 1, '  All tests will use a point equality tolerance of %e\n', tol );

  dim_num = 2;
  level_max = 2;
  rule = [ 1, 1 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l2_ccxcc';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 3;
  rule = [ 1, 3 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l3_ccxgp';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 2;
  rule = [ 1, 4 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l2_ccxgl';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 2;
  rule = [ 1, 7 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l2_ccxlg';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 2;
  rule = [ 1, 8 ]';
  alpha = [ 0.0, 1.5 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l2_ccxglg';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 2;
  rule = [ 2, 9 ]';
  alpha = [ 0.0, 0.5 ]';
  beta = [ 0.0, 1.5 ]';
  file_name = 'sparse_grid_mixed_d2_l2_f2xgj';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 2;
  level_max = 2;
  rule = [ 6, 4 ]';
  alpha = [ 2.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l2_gghxgl';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );

  dim_num = 3;
  level_max = 2;
  rule = [ 1, 2, 5 ]';
  alpha = [ 0.0, 0.0, 0.0 ]';
  beta = [ 0.0, 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d3_l2_ccxf2xgh';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );
%
%  Dimension 2, Level 4, Rule 3
%
  dim_num = 2;
  level_max = 4;
  rule = [ 3, 3 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l4_gpxgp';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );
%
%  Dimension 2, Level 4, Rule 13
%
  dim_num = 2;
  level_max = 4;
  rule = [ 13, 13 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l4_gpsexgpse';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );
%
%  Dimension 2, Level 4, Rule 16
%
  dim_num = 2;
  level_max = 4;
  rule = [ 16, 16 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l4_gpmexgpme';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );
%
%  Dimension 2, Level 4, Rule 17
%
  dim_num = 2;
  level_max = 4;
  rule = [ 17, 17 ]';
  alpha = [ 0.0, 0.0 ]';
  beta = [ 0.0, 0.0 ]';
  file_name = 'sparse_grid_mixed_d2_l4_ccnxccn';
  sparse_grid_mixed_write_test ( dim_num, level_max, rule, alpha, beta, tol, ...
    file_name );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPARSE_GRID_MIXED_WRITE_TESTS\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  rmpath ( '../sandia_rules' );

  return
end


function [l c] = path_histogram(G,varargin)
% PATH_HISTOGRAM Compute a histogram of all shortest paths in graph G
%
% [l c] = path_histogram(G) computes all shortest paths in A one at a time
% and forms the histogram of the shortest distances between all vertices.
%
% [l c] = path_histogram(G,struct('sample',N)) uses N random samples instead of an
% exact solution.  (N=0 uses exact solution)
%
% Options:
%   options.weighted: use Dijkstra algorithm for weighted paths [{0} | 1]
%   options.intcount: use integer histogram bins [0 | {1}]
%   options.nbins: number of bins when intcount=0 [{50} | positive integer]
%   options.sample: use N iid samples instead of all sources
%     [{0} | positive integer]
%   options.verbose: output status for long runs [{0} | 1]
%
% Example:
%  load('graphs/cs-stanford.mat');
%  [l c] = path_histogram(A);
%  bar(l,c,[min(l),max(l)],'hist');

%
% David Gleich
% Copyright, Stanford University, 2008
%

% History
% 2008-03-14: Initial coding by David

options=struct('weighted',0,'intcount',1,'nbins',50','sample',0,'istrans',0,...
    'verbose',0);
if ~isempty(varargin), options = merge_structs(varargin{1}, options); end

if ~options.istrans, G = G'; end
bfsoptions=struct('istrans',1);

n=size(G,1); verb=options.verbose;

N = options.sample;
if N==0, vs=1:n; N = n;
else vs=ceil(n*rand(options.sample,1));
end

% sample from all vertices
H=sparse(n,1); t0=clock; p=1; Np=min(N,100);
for vi=1:N
    if verb && vi==(p*floor(N/Np) + max(mod(N,Np)-(Np-p),0))
        dt=etime(clock,t0); p=p+1;
        fprintf('  %5.1f : %9i of %9i; etr=%7f sec\n', ...
            100*(p-1)/Np, vi, N, N*dt/vi-dt);
    end
    di=bfs(G,vi,bfsoptions);
    di=di(di>0);             % only use reachable points
    H=H+accumarray(di,1,[n 1],@sum,0,true);
    bfsoptions.nocheck=1;    % don't repeat options check
end
l = find(H); c = nonzeros(H);

end

% internal copy of merge_structs
function S=merge_structs(A,B)
S = A; fn = fieldnames(B);
for ii = 1:length(fn), if (~isfield(A, fn{ii})), S.(fn{ii}) = B.(fn{ii}); end, end
end


function varargout = diff(varargin)
%DIFF   Derivative of a CHEBFUN2 object.
%   DIFF(F) is the derivative of F along the y direction.
%
%   DIFF(F, N) is the Nth derivative of F in the y direction.
%
%   DIFF(F, N, DIM) is the Nth derivative of F along the dimension DIM.
%     DIM = 1 (default) is the derivative in the y-direction.
%     DIM = 2 is the derivative in the x-direction.
%
%   DIFF(F, [NX NY]) is the partial derivative of NX of F in the first variable,
%   and NY of F in the second derivative. For example, DIFF(F,[1 2]) is
%   d^3F/dxd^2y.
%
% See also GRADIENT, SUM, PROD.

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

[varargout{1:nargout}] = diff@separableApprox(varargin{:});

end


function [ y, m, d, f ] = frac_borrow_common ( y, m, d, f )

%*****************************************************************************80
%
%% FRAC_BORROW_COMMON borrows fractions from days in a Common YMDF date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, integer M, integer D, real F,
%    a YMDF date.
%
%    Output, integer Y, integer M, integer D, real F,
%    the YMDF date has been adjusted.
%
  while ( f < 0.0 )

    f = f + 1.0;

    d = d - 1;

  end

  [ y, m, d ] = day_borrow_common ( y, m, d );

  return
end


function [z_irm,z_ibm,t] = applyIdealMasks(xt,xi,nfft,hop,fs)
%APPLYIDEALMASKS Calculate and apply ideal masks via STFT
%
%   Z_IRM = IOSR.BSS.APPLYIDEALMASKS(XT,XI) calculates the ideal ratio mask
%   (IRM) and applies it to the mixture XT+XI, where XT is the target
%   signal and XI is the interference signal. The IRM is calculated via the
%   STFT using 1024-point windows with 512-point overlap. Z_IRM, XT, and XI
%   are vectors. If XT and XI are of different lengths then the shorter
%   signal is zero-padded in order to make them the same length; Z_IRM is
%   the same length as XT and XI.
%
%   Z_IRM = IOSR.BSS.APPLYIDEALMASKS(XT,XI,NFFT) uses NFFT-length segments
%   in the STFT.
%
%   Z_IRM = IOSR.BSS.APPLYIDEALMASKS(XT,XI,WINDOW) uses
%   LENGTH(WINDOW)-length segments in the STFT and applies WINDOW to each
%   segment.
%
%   Z_IRM = IOSR.BSS.APPLYIDEALMASKS(XT,XI,WINDOW,HOP) uses hop size HOP
%   for the STFT.
%
%   [Z_IRM,Z_IBM] = IOSR.BSS.APPLYIDEALMASKS(...) calculates the ideal
%   binary mask (IBM) and applies it to the mixture, returning the result
%   to Z_IBM.
%
%   [Z_IRM,Z_IBM,T] = IOSR.BSS.APPLYIDEALMASKS(XT,XI,WINDOW,HOP,FS) uses
%   sampling frequency FS to return the corresponding time T of each
%   element in Z_IRM and Z_IBM.
%
%   See also IOSR.DSP.STFT, IOSR.DSP.ISTFT, IOSR.BSS.IDEALMASKS,
%            IOSR.BSS.APPLYMASKS.

%   Copyright 2016 University of Surrey.

    %% check input

    % check signals
    assert(isvector(xt) && numel(xt)>1, 'iosr:applyIdealMasks:invalidXt', 'XT must be a vector')
    assert(isvector(xi) && numel(xi)>1, 'iosr:applyIdealMasks:invalidXi', 'XI must be a vector')

    % make equal length
    maxlength = max([length(xi) length(xt)]);
    xt = pad(xt,maxlength);
    xi = pad(xi,maxlength);

    % check nfft
    if nargin<3
        nfft = 1024;
    end

    % determine window
    if numel(nfft)>1
        win = nfft;
        assert(isvector(win), 'iosr:applyIdealMasks:invalidWin', 'WINDOW must be a vector')
        nfft = length(win);
    else
        assert(round(nfft)==nfft && nfft>0, 'iosr:applyIdealMasks:invalidNfft', 'NFFT must be a positive integer')
        win = hamming(nfft);
    end

    % check x length
    assert(length(xt)>=nfft, 'iosr:applyIdealMasks:invalidXt', 'XT must have at least NFFT samples')
    assert(length(xi)>=nfft, 'iosr:applyIdealMasks:invalidXi', 'XI must have at least NFFT samples')

    % determine hop
    if nargin<4
        hop = fix(nfft/2);
    else
        assert(isscalar(hop) & round(hop)==hop, 'iosr:applyIdealMasks:invalidHop', 'HOP must be an integer')
        assert(hop<=nfft && hop>0, 'iosr:applyIdealMasks:invalidHop', 'HOP must be less than or equal to NFFT, and greater than 0')
    end

    % determine fs
    if nargin<5
        fs = 1;
    else
        assert(isscalar(fs), 'iosr:applyIdealMasks:invalidFs', 'FS must be an scalar')
    end

    %% calculate outputs

    % STFTs of signals and mixture
    st = iosr.dsp.stft(xt,win,hop);
    si = iosr.dsp.stft(xi,win,hop);
    mix = iosr.dsp.stft(xt+xi,win,hop);

    % return ideal masks
    [irm,ibm] = iosr.bss.idealMasks(st,si);

    % apply IRM
    z_irm = iosr.bss.applyMask(mix,irm,nfft,hop,fs);
    z_irm = pad(z_irm,maxlength);

    % apply IBM
    if nargout>1
        z_ibm = iosr.bss.applyMask(mix,ibm,nfft,hop,fs);
        z_ibm = pad(z_ibm,maxlength);
    end

    % calculate t
    if nargout>2
        t = (0:length(z_irm)-1)./fs;
    end

end

function y = pad(x,dur)
%PAD Zero-pad a vector

    if length(x)<dur
        y = [x(:); zeros(dur-length(x),1)];
    else
        y = x(:);
    end

end


%%% Setup
% restoredefaultpath;
close, clear, clc;

%%% Path
addpath(fullfile(pwd,'utils'));
addpath(fullfile(pwd,'libs','PROPACK'));
addpath(genpath(fullfile(pwd,'libs','manopt','manopt')));
addpath(fullfile(pwd,'libs','tensor_toolbox'));
addpath(fullfile(pwd,'libs','lightspeed'));

%%% Params
params.debug = 1;
clc;

%%% Load video
load(fullfile('trafficdb','traffic_patches.mat'));
V = im2double(imgdb{100}); % show_3dvideo(V);

%%% Observed entries
%Omega = ones(size(V));
%Omega = randi([0 1],size(V));
[~,Omega] = subsampling(V, 0.75);
%[~,Omega] = subsampling(V, 0.15);
% show_3dvideo(Omega);

%% Matrix completion
clc;
params.algs_path = 'algs_mc';
params.algs_name = get_algs_name(params);
displog('--- Matrix Completion ---');
for alg = 1:size(params.algs_name,2)
  %alg = 1;
  displog(['Current algorithm: ' params.algs_name(alg).name]);
  params.current_algorithm = alg;

  %%% Load algorithm
  current_alg_name = params.algs_name(params.current_algorithm).name;
  current_alg_path = fullfile(params.algs_path,current_alg_name);
  displog(['Loading algorithm: ' current_alg_name]);
  addpath(genpath(current_alg_path));

  %%% Matrix completion
  displog('Performing matrix completion');
  M = convert_video3d_to_2d(V); % imagesc(M)
  Idx = convert_video3d_to_2d(Omega); % imagesc(Idx)
  M(M == 0) = 1e-3;
  M = M.*Idx; % imagesc(M)
  params_mc.M = M;
  params_mc.Idx = Idx;
  M_hat = run_mc(params_mc); % imagesc(M_hat)

  % Build background model
  M_bg = mean(M_hat,2);
  I_bg = reshape(M_bg,size(V,1),size(V,2));
  if(params.debug)
    clf,imshow(I_bg);
    title(current_alg_name);
    pause(1);
  end

  rmpath(genpath(current_alg_path));
  %break;
end
clear alg seq;

%% Tensor completion
clc;
params.algs_path = 'algs_tc';
params.algs_name = get_algs_name(params);
displog('--- Tensor Completion ---');
for alg = 1:size(params.algs_name,2)
  %alg = 1;
  displog(['Current algorithm: ' params.algs_name(alg).name]);
  params.current_algorithm = alg;

  %%% Load algorithm
  current_alg_name = params.algs_name(params.current_algorithm).name;
  current_alg_path = fullfile(params.algs_path,current_alg_name);
  displog(['Loading algorithm: ' current_alg_name]);
  addpath(genpath(current_alg_path));

  %%% Tensor completion
  displog('Performing tensor completion');
  V(V == 0) = 1e-3;
  V = V.*Omega;
  params_tc.T = V;
  params_tc.Idx = Omega;
  params_tc.blksize = [16 16];
  V_hat = run_tc(params_tc); % imagesc(M_hat)

  % Build background model
  I_bg = mean(V_hat,3);
  if(params.debug)
    clf,imshow(I_bg);
    title(current_alg_name);
    pause(1);
  end

  rmpath(genpath(current_alg_path));
  %break;
end
clear alg seq;


% Sample code to generate class activation map from 10 crops of activations
% Bolei Zhou, March 15, 2016
% for the online prediction, make sure you have complied matcaffe

clear
addpath('/opt/caffe/matlab');

imgID = 2; % 1 or 2
img = imread(['img' num2str(imgID) '.jpg']);

img = imresize(img, [256 256]);
online = 0; % whether extract features online or load pre-extracted features

load('categories1000.mat');
if online == 1
    % load the CAM model and extract features

    net_weights = ['models/imagenet_googlenetCAM_train_iter_120000.caffemodel'];
    net_model = ['models/deploy_googlenetCAM_imagenet.prototxt'];
    net = caffe.Net(net_model, net_weights, 'test');

    weights_LR = net.params('CAM_fc',1).get_data();% get the softmax layer of the network

    scores = net.forward({prepare_image(img)});% extract conv features online
    activation_lastconv = net.blobs('CAM_conv').get_data();
	scores = scores{1};
else
    % use the extracted features and softmax parameters cached before hand
    load('data_net.mat'); % it contains the softmax weights and the category names of the network
    load(['data_img' num2str(imgID) '.mat']); %it contains the pre-extracted conv features
end

%% Class Activation Mapping

topNum = 5; % generate heatmap for top X prediction results
scoresMean = mean(scores,2);
[value_category, IDX_category] = sort(scoresMean,'descend');
[curCAMmapAll] = returnCAMmap(activation_lastconv, weights_LR(:,IDX_category(1:topNum)));

curResult = im2double(img);
curPrediction = '';

for j=1:topNum
    curCAMmap_crops = squeeze(curCAMmapAll(:,:,j,:));
    curCAMmapLarge_crops = imresize(curCAMmap_crops,[224 224]);
    curCAMmap_image = mergeTenCrop(curCAMmapLarge_crops);

    curHeatMap = map2jpg(curCAMmap_image, [], 'jet');
    curHeatMap = im2double(img)*0.2+curHeatMap*0.7;
    curResult = [curResult ones(size(curHeatMap,1),8,3) curHeatMap];
    curPrediction = [curPrediction ' --top'  num2str(j) ':' categories{IDX_category(j)}];

end
disp(curPrediction);
imwrite(curResult, 'result.jpg');
figure,imshow(curResult);
title(curPrediction)

if online==1
    caffe.reset_all();
end


% rundesignsimMAP2
% Tor Wager, 8/29/01
% if your input var name is already a variable in the wkspace, uses that...
% otherwise creates one with zeros.

warning off
index = 1;
name = input('Enter the name of the output variable and files ','s');
% eval([name ' = zeros(10,10);'])

% -------------------------------------------------
% common user variables
% -------------------------------------------------
tickRes = [.1 .1];
ISIrange = [.1 16]
FCrange = [.01 .81];
GA.sizegenerations = 100;

myISI = ISIrange(1):tickRes(1):ISIrange(2);
myFC = FCrange(1):tickRes(2):FCrange(2);

ISIsize = length(myISI);
FCsize = length(myFC);

ISItick = 1:max(round(ISIsize./25),1):ISIsize;
ISIticklab = myISI(ISItick);
FCtick = 1:2:FCsize;
FCticklab = myFC(FCtick);

eval([' if ~(exist(''' name ''') == 1), disp(''Creating new variable''),' name ' = zeros(ISIsize,FCsize);, else,disp(''Using existing variable''),end'])

disp(['Starting ' num2str(prod([ISIsize FCsize])) ' surface points.'])

% ----------------------------------------------------------------
% * HRF GAMMA FUNCTION - spm 99
% ----------------------------------------------------------------

   HRF = spm_hrf(.1);						% SPM HRF sampled at .1 s
   HRF = HRF/ max(HRF);

% ----------------------------------------------------------------
% * make the map
% ----------------------------------------------------------------

for RR = 1:size(myISI,2)
	% set ISI
    GA.ISI = myISI(RR);

    % ----------------------------------------------------------------
    % * get smoothing matrix and autocorrelation matrix
    % ----------------------------------------------------------------
    numStim = ceil(GA.scanLength / (GA.ISI));
    numsamps = ceil(numStim*GA.ISI/GA.TR);
	disp('  ...getting S and svi')
	[S,Vi,svi] = getSmoothing(GA.HPlength,GA.LPsmooth,GA.TR,numsamps,GA.xc);
	if isempty(S), S = 1;, end

   	clear Vi

	for CC = 1:size(myFC,2)
		disp(['Starting model ' num2str(index)])

		% set rest frequency
		GA.freqConditions(end) = myFC(CC);
		GA.freqConditions(1:end-1) = (1 - myFC(CC)) / (size(GA.freqConditions,2)-1);

		disp(['FREQC and ISI are:	' num2str(GA.freqConditions) ' and ' num2str(GA.ISI)])

        eval(['mymat = ' name ';'])
        if mymat(RR,CC) == 0        % only do it if it's not done yet.

        % ----------------------------------------------------------------
        % * randomize initial set of organisms
        % ----------------------------------------------------------------
        unsortedList = [];
        numStimEachCond = ceil((numStim) * GA.freqConditions);
	    clear listMatrix

	    for i = 1:size(GA.freqConditions,2)
	    	% unsorted list of all stims in proper frequencies
   		    startIndex = size(unsortedList,1)+1;
		    % multiplied by 1.5 because lists were coming out too short.
   		    unsortedList(startIndex:(startIndex + 2*numStimEachCond(i)-1),1) = GA.conditions(i);
        end

        disp('  ...randomizing organism start state')
        for z = 1:GA.sizeGenerations % generate random ordering of x conditions
  	        stimList = getRandom(unsortedList);
            listMatrix(:,z) = stimList; % a row for each subject
        end

            [fitness,convar,xtxi,models] = testlist(listMatrix,GA,HRF,'svi',svi,'S',S);
            convar = 1./convar;
	        eval([name '(RR,CC) = mean(convar,2);']);
        end % if mymat...

		%eval(['save ' name num2str(index) ' ' name ' SIM'])
		index = index + 1;
	end
end

eval(['save ' name])
figure;
set(gcf,'Color','w')
eval(['surf(' name ')']); colormap(copper)
eval(['set(gca,''XTick'',1:size(' name ',2))'])
set(gca,'XTickLabel',myFC)
%eval(['set(gca,''YTick'',1:size(' name ',1))'])
%set(gca,'YTickLabel',myISI)
xlabel('Proportion of blank intervals','FontSize',14)
ylabel('ISI in s','FontSize',14)
title('Surface map of ISI vs. proportion of blank intervals','FontSize',18)
zlabel('Efficiency of contrast [1 -1]','FontSize',14)

set(gca,'YTick',ISItick)
set(gca,'YTickLabel',ISIticklab)

warning on

break
%for line plots
figure;plot(MAP1)
plot(MAP1,'LineWidth',2)
legend({'.01' '.21' '.41' '.61' '.81'})
set(gca,'XTick',1:2:40)
set(gca,'XTickLabels',.1:.4:7.9)
title('Efficiency as a function of ISI and jitter: Linear HRF function','FontSize',14)
grid on

eval(['saveas(gcf,''' name ''',''fig'')'])
eval(['saveas(gcf,''' name ''',''jpg'')'])


function C = permutMat_yaw(tau_vec)
%permutMat_yaw takes tau_vec as an input and produces permutation matrix for
%yaw. Only initial conditions (yaw, yawdot, yaw2dot) and final (yawdot,
%yaw2dot) is being specified. Rest will be optimized with equality
%constraints.
r = 2; % up to 2nd derivative
n = 2*r+1; % 5th order
K = length(tau_vec);
C = eye((n+1)*K);
c = [];
idx = [];
for i=1:K-1
    if i == K-1
        ukn_row = (n+1)*i+1:(n+1)*i+4;  % Last term includes last angle
    else
        ukn_row = (n+1)*i+1:(n+1)*i+3;  % unknown rows: 7,8,9 , 13,14,15, ...
    end
    c = [c;C(ukn_row,:)];
    idx = [idx, ukn_row];
end
C(idx,:) = [];
C = [C;c];


% @authors:     Ahmad Humayun
% @contact:     ahumayun@cc.gatech.edu
% @affiliation: Georgia Institute of Technology
% @date:        Fall 2013 - Summer 2014

function [val] = compute_sp_unary_values(abst_obj, seed_region)
    % convert from superpixel to pixel level seeds
    pxl_seed_region = ismember(abst_obj.seg_obj.sp_data.sp_seg, ...
                               find(seed_region));
    pxl_seed_region = pxl_seed_region(:);

    % compute affinities based on pixel seed region
    I = abst_obj.seg_obj.I;
    if(size(I, 3) ~= 3)
        I(:,:,2) = I(:,:,1);
        I(:,:,3) = I(:,:,1);
    end

    %val = obj.compute_unary_values_patch_rgb(seed_region);
    % compute inverse distance (capacity) for each pixel from seed region
    val = compute_unary_values_rgb(I, pxl_seed_region, ...
                                   abst_obj.graph_seed_frame_weight, ...
                                   abst_obj.graph_unary_exp_scale);

    % sum values over whole superpixels
    val = accumarray(abst_obj.seg_obj.sp_data.sp_seg(:), val);
end

function val = compute_unary_values_rgb(I, seed_region, multiplier, ...
                                        exp_scale)
    K = 5; % 10

    %%%%%% RGB space %%%%%%%%%%%
    pix = reshape(I, size(I,1)*size(I,2), 3);

    %%%%%%% HSV space %%%%%%%%%%%
    %pix = uint8(255*reshape(rgb2hsv(obj_I), size(obj_I,1)* size(obj_I,2), 3));

    %%%%%%% LAB space %%%%%%%%%%%%
    %pix = reshape(rgb2lab(obj_I), size(obj_I,1)* size(obj_I,2), 3);
    %pix(:,1) = pix(:,1)*2.55;
    %pix(:,[2 3]) = 255*((pix(:,[2 3]) + 110) / 220);
    %pix = uint8(pix);
    %t = tic();

    % get color values for the seed region
    seed_pix = pix(seed_region,:)';

    if K > size(seed_pix,2)
        K = size(seed_pix,2);
%        seed_pix = [seed_pix, seed_pix];
    end

    % get K representative colors from the seed region
    centers = vl_ikmeans(seed_pix, K, 'Method', 'lloyd');  % centers in columns!
    %toc(t);
    %obj.show_centers_colors(centers);

    %center = mean(double(pix_rgb(seed_region,:)));
    %dists = sum(abs(pix_rgb - center(ones(size(obj_I,1)* size(obj_I,2),1),:)),2);

    %ext_pix_rgb = pix(:,:,ones(K,1));

    dists = inf(size(pix,1),1);
    pix = single(pix);

    % compute the l1 norm of each pixel from one of the K cluster centers.
    % Store it if its the shortest distance seen so far
    for i=1:K
        center = single(centers(:,i)');
        dists = min(dists, sum(abs(bsxfun(@minus, pix, center)),2));
    end
    % exp(-dists x const) inverts the distance - high values will become
    % low (values will range between 0 and 1)
    val = double(0.3 * multiplier * exp(-dists*exp_scale));
end


function [I3, I2]=Cell_centri(I0,  coeff, latent, area_real, boundary, t5)
if(~exist('t5','var'))
    t5=.2;
end
area_right=area_real+2*t5*sqrt(latent(1))*coeff(:,1);
area_left=area_real-2*t5*sqrt(latent(1))*coeff(:,1);

[inner(:,2),inner(:,1)]=find(I0>=0);
centerlized1=inner-repmat(area_right', size(inner,1),1);
score1=centerlized1*coeff(:,1);

centerlized2=inner-repmat(area_left', size(inner,1),1);
score2=centerlized2*coeff(:,1);
I1=I0;
I1((score1.*score2)<0)=0;
I1((score1.*score2)>0)=1;
I2=I1;
figure;
imshow(I1)
hold on
h=imshow(I0);
alpha(h, 0.5)
I3=false(size(I0));

%% get rid of the part left
stats = regionprops(I0, 'Area','FilledArea','MajorAxisLength',...
    'MinorAxisLength', 'Orientation', 'Eccentricity','PixelIdxList');
AA=struct2cell(stats);
% area=zeros(1,size(AA,2));
% ratio=zeros(1,size(AA,2));
plist=cell(1,size(AA,2));
for i=1:size(AA,2)
%     area(i)=AA{1,i};
%     ratio(i)=AA{2,i}./AA{3,i};
    plist{i}=AA{7,i};
    if all(I1(plist{i})==0)
        I3(plist{i})=1;
    end

end
[A, B]=find(I3==1);
[IDX, D]=knnsearch(boundary, [B,A]);
index1=find(I3==1);
I3=false(size(I0));
I3(index1(D<1.5*sqrt(latent(2))))=1;


function test_findcluster

% MEM 8gb
% WALLTIME 00:20:00
% DEPENDENCY findcluster

[dum, ftpath] = ft_version;
cd(fullfile(ftpath, 'private'));

ft_hastoolbox('spm12', 1);

% create a data matrix and a spatial neighbourhoodmatrix
nchan = 5;
C     = diag(ones(1,4),-1)+diag(ones(1,4),1)>0;
dat   = zeros(5,4,3);
dat(1:2,1:2,1:2) = 1;
dat(3,2:3,2:3) = 1;
dat(4,1,1:3) = 1;
dat(5,2:4,3) = 1;
dat = dat>0;

% input is space x something x something
[clus, num] = findcluster(dat,C);
assert(num==3);
assert(sum(clus(:)==1)==12);
assert(sum(clus(:)==2)==3);
assert(sum(clus(:)==3)==3);

% channel 2 is disconnected from the rest
C2 = C;
C2(1,1:3) = [0 0 1];
C2(3,1:3) = [1 0 0];
C2(2,1:3) = 0;
[clus, num] = findcluster(dat,C2);
assert(num==4);
assert(sum(clus(:)==1)==8);
assert(sum(clus(:)==2)==4);
assert(sum(clus(:)==3)==3);
assert(sum(clus(:)==4)==3);

% input is as if it's a spatial 3D reshapeable volume
[clus, num] = findcluster(shiftdim(dat,-1),false);
assert(num==3);
assert(sum(clus(:)==1)==12);
assert(sum(clus(:)==2)==3);
assert(sum(clus(:)==3)==3);

dat4d = repmat(dat, [1 1 1 4]);
dat5d = repmat(dat, [1 1 1 4 5]);
dat6d = repmat(dat, [1 1 1 4 5 6]);
dat7d = repmat(dat, [1 1 1 4 5 6 7]);

[clus4d, num4d] = findcluster(dat4d,C);
assert(num4d==3);
assert(sum(clus4d(:)==1)==12*4);
assert(sum(clus4d(:)==2)==3*4);
assert(sum(clus4d(:)==3)==3*4);

[clus5d, num5d] = findcluster(dat5d,C);
assert(num5d==3);
assert(sum(clus5d(:)==1)==12*4*5);
assert(sum(clus5d(:)==2)==3*4*5);
assert(sum(clus5d(:)==3)==3*4*5);

[clus6d, num6d] = findcluster(dat6d,C);
assert(num6d==3);
assert(sum(clus6d(:)==1)==12*4*5*6);
assert(sum(clus6d(:)==2)==3*4*5*6);
assert(sum(clus6d(:)==3)==3*4*5*6);

[clus7d, num7d] = findcluster(dat7d,C);
assert(num7d==3);
assert(sum(clus7d(:)==1)==12*4*5*6*7);
assert(sum(clus7d(:)==2)==3*4*5*6*7);
assert(sum(clus7d(:)==3)==3*4*5*6*7);

[clus4d, num4d] = findcluster(shiftdim(dat4d,-1), false);
assert(num4d==3);
assert(sum(clus4d(:)==1)==12*4);
assert(sum(clus4d(:)==2)==3*4);
assert(sum(clus4d(:)==3)==3*4);

[clus5d, num5d] = findcluster(shiftdim(dat5d,-1), false);
assert(num5d==3);
assert(sum(clus5d(:)==1)==12*4*5);
assert(sum(clus5d(:)==2)==3*4*5);
assert(sum(clus5d(:)==3)==3*4*5);

[clus6d, num6d] = findcluster(shiftdim(dat6d,-1), false);
assert(num6d==3);
assert(sum(clus6d(:)==1)==12*4*5*6);
assert(sum(clus6d(:)==2)==3*4*5*6);
assert(sum(clus6d(:)==3)==3*4*5*6);

[clus7d, num7d] = findcluster(shiftdim(dat7d,-1), false);
assert(num7d==3);
assert(sum(clus7d(:)==1)==12*4*5*6*7);
assert(sum(clus7d(:)==2)==3*4*5*6*7);
assert(sum(clus7d(:)==3)==3*4*5*6*7);


function [g] = mg2g(mg)
% Convert mass from milligrams to grams.
% Chad Greene 2012
g = mg*0.001 ;


%compute vy_cm
function [data,units]=compute_vy_cm(trx,n)

larvae=trx.exp2flies{n};
numlarvae=numel(larvae);
vy_cm=cell(1,numlarvae);

for i=1:numlarvae
    larva=larvae(i);
    vy_cm{1,i}=(trx(larva).y_mm(2:end)-trx(larva).y_mm(1:end-1))./trx(larva).dt;
end

units=parseunits('mm/s');
data=vy_cm;


% ------------------------------------------------------------------------
%  Copyright (C)
%  Universitat Politecnica de Catalunya BarcelonaTech (UPC) - Spain
%  University of California Berkeley (UCB) - USA
%
%  Jordi Pont-Tuset <jordi.pont@upc.edu>
%  Pablo Arbelaez <arbelaez@berkeley.edu>
%  June 2014
% ------------------------------------------------------------------------
% This file is part of the MCG package presented in:
%    Arbelaez P, Pont-Tuset J, Barron J, Marques F, Malik J,
%    "Multiscale Combinatorial Grouping,"
%    Computer Vision and Pattern Recognition (CVPR) 2014.
% Please consider citing the paper if you use this code.
% ------------------------------------------------------------------------
function [int_area, int_bbox] = boxes_intersection( bbox1, bbox2 )
    up1    = bbox1(1);
    left1  = bbox1(2);
    down1  = bbox1(3);
    right1 = bbox1(4);

    up2    = bbox2(1);
    left2  = bbox2(2);
    down2  = bbox2(3);
    right2 = bbox2(4);

    int_left  = max(left1,left2);
    int_right = min(right1,right2);
    int_up    = max(up1,up2);
    int_down  = min(down1,down2);

    if (int_left<=int_right) && (int_up<=int_down)
        int_bbox = [int_up, int_left, int_down, int_right];
        int_area = box_area(int_bbox);
    else
        int_bbox = [];
        int_area = 0;
    end
end


function spectrumscope_ex3
% SPECTRUMSCOPE_EX3   Spectrum scope example, using the Data Acquisition Toolbox
%
% See comments on bottom of file for extra notes on this application

%    Scott Hirsch 2-25-04
%    shirsch@mathworks.com
%    Copyright 1998-2004 The MathWorks, Inc.

%%
% Create analoginput object (Data Acquisition Toolbox)
daqreset
ai = analoginput('winsound');
chan = addchannel(ai,1:2);

%%
% Configure analoginput object
Fs = 44100;     % Sample Rate
set(ai,'SampleRate',Fs);
set(ai,'SamplesPerTrigger',4096);

%%
% Initialize scope
Nfft = ai.SamplesPerTrigger/2;                  % FFT Length.
NTraces = length(chan);                         % Number of traces on scope
hSpectrumScope = spectrumscope(Fs,Nfft,NTraces);% Initialize spectrum scope

%%
% Configure acquisition to update scope
set(ai,'TriggerRepeat',inf)
set(ai,'TriggerFcn',{@updateplot,hSpectrumScope,Nfft});

% Put a stop button on the scope
% This is available on MATLAB Central
if exist('daqstopbutton','file')
    daqstopbutton(gcf,ai);
else
    start(ai);
    disp('Type "stop(daqfind)" to stop the application.  Then, go to MATLAB Central and download daqstopbutton.m!');
end;

function updateplot(ai,event,hSpectrumScope,Nfft)
d = peekdata(ai,Nfft);
spectrumscope(hSpectrumScope,d);

%%
% Comments:
%
% For an application that simple gives me some real-time visualization of
% the data that I am acquiring, I prefer to use PEEKDATA instead of
% GETDATA.  Since GETDATA always grabs the oldest data in the buffer, there
% can easily be a significant lag from when an event occurs to when the
% response to the event is shown on the screen. PEEKDATA grabs the most
% recently acquired data, so it makes for much more responsive
% applications.  PEEKDATA is also non-blocking, so it won't slow down your
% application while waiting for data.  This means that you need to make
% sure there is enough data in the buffer before you call PEEKDATA.  This
% is why I set the amount of data I grab per call to peekdata (Nfft) to
% something less than the amount of data acquired per trigger.
%
% There are a bunch of different callback functions for running continuous
% applications.  I happen to like using Triggers, but you could just as
% easily use TimerFcn or SamplesAcquiredFcn


function diplayFinalModelsCT_HN(pathWORK,outcomes)
% -------------------------------------------------------------------------
% function diplayFinalModelsCT_HN(pathWORK,outcomes)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function displays the final models for all analyzed outcomes in the
% HN study for the 'CT' feature set only, in terms of: multivariable model
% response, model variables, and prediction performance estimation. See
% ref.[1] for more details. Goal: comparison with the "Radiomics signature"
% of (Aerts et al., Nat Commun, 2014)
% -------------------------------------------------------------------------
% REFERENCE:
% [1] Vallieres, M. et al. (2015). FDG-PET/CT radiomics models for the
%     early prediction of different tumour outcomes in head and neck cancer.
%     The Journal of Nuclear Medicine, aa(bb), xxx-yyy.
%     doi:
% -------------------------------------------------------------------------
% INPUTS:
% - pathWORK: Full path to the HN WORKSPACE directory.
% - outcomes: Structure specifying the status (1 or 0) for different
%             outcomes in HN cancer. Contains: outcomes.Failure,
%             outcomes.Locoregional, outcomes.Distant, outcomes.Death. See
%             ref.[1] for more details.
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: July 2015
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015  Martin Vallieres
%
%    This package is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This package is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

startpath = pwd;
nameOutcomes = fieldnames(outcomes);
nOutcomes = length(nameOutcomes);

for o = 1:nOutcomes
    cd([pathWORK,'/FINAL_MODELS/',nameOutcomes{o},'/CTonly'])
    load('finalModel'), load('coeff'), load('modelCI'), load('response') % Variables 'finalModel', 'coeff',  'modelCI', and 'response' now present in MATLAB workspace
    order = size(finalModel.Data,2);
    plotSigmoidalResponse(response,outcomes.(nameOutcomes{o}),modelCI,upper(nameOutcomes{o}))
    fprintf(['\n\n --> THE FINAL MULTIVARIABLE MODEL (CT FEATURE SET) FOR ''%s'' OUTCOME IS:\n\n'...
             '               g(x) =               \n'],upper(nameOutcomes{o}))
    for i = 1:order
        fprintf([num2str(coeff(i)),' X ',finalModel.Name{i},'\n'])
        fprintf('                    +               \n')
    end
    fprintf(['                   ',num2str(coeff(end)),'\n'])
    fprintf('\nWITH CORRESPONDING PREDICTION PERFORMANCE ESTIMATION:\n')
    fprintf(['AUC = ',num2str(roundsd(finalModel.AUC632,ceil(log10(finalModel.AUC632/roundsd(finalModel.SE_AUC632,1))))),' ± ',num2str(roundsd(finalModel.SE_AUC632,1)),'\n'])
    fprintf(['Sensitivity = ',num2str(roundsd(finalModel.Sensitivity632,ceil(log10(finalModel.Sensitivity632/roundsd(finalModel.SE_Sensitivity632,1))))),' ± ',num2str(roundsd(finalModel.SE_Sensitivity632,1)),'\n'])
    fprintf(['Specificity = ',num2str(roundsd(finalModel.Specificity632,ceil(log10(finalModel.Specificity632/roundsd(finalModel.SE_Specificity632,1))))),' ± ',num2str(roundsd(finalModel.SE_Specificity632,1)),'\n'])
    fprintf('\n\n')
end

cd(startpath)
end


function rgb_3x3 = image_denoise_rgb_3x3 ( rgb )

%*****************************************************************************80
%
%% IMAGE_DENOISE_RGB_3X3 filters out noise from an RGB image.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, uint8 RGB(:,:,3), the noisy RGB data.
%
%    Output, uint8 RGB_3X3(:,:,3), the RGB data for the filtered image.
%
  r = image_denoise_gray_3x3 ( rgb(:,:,1) );
  g = image_denoise_gray_3x3 ( rgb(:,:,2) );
  b = image_denoise_gray_3x3 ( rgb(:,:,3) );

  rgb_3x3 = zeros ( size ( rgb ) );

  rgb_3x3 = uint8 ( rgb_3x3 );

  rgb_3x3(:,:,1) = r(:,:);
  rgb_3x3(:,:,2) = g(:,:);
  rgb_3x3(:,:,3) = b(:,:);

  return
end


%SerialLink.IKUNC Inverse manipulator by optimization without joint limits
%
% Q = R.ikunc(T, OPTIONS) are the joint coordinates (1xN) corresponding to
% the robot end-effector pose T which is an SE3 object or homogenenous
% transform matrix (4x4), and N is the number of robot joints. OPTIONS is
% an optional list of name/value pairs than can be passed to fminunc.
%
% Q = robot.ikunc(T, Q0, OPTIONS) as above but specify the
% initial joint coordinates Q0 used for the minimisation.
%
% [Q,ERR] = robot.ikunc(T,...) as above but also returns ERR which is the
% scalar final value of the objective function.
%
% [Q,ERR,EXITFLAG] = robot.ikunc(T,...) as above but also returns the
% status EXITFLAG from fminunc.
%
% [Q,ERR,EXITFLAG,OUTPUT] = robot.ikunc(T,...) as above but also returns the
% structure OUTPUT from fminunc which contains details about the optimization.
%
% Trajectory operation::
%
% In all cases if T is a vector of SE3 objects (1xM) or a homogeneous transform
% sequence (4x4xM) then returns the joint coordinates corresponding to
% each of the transforms in the sequence.  Q is MxN where N is the number
% of robot joints. The initial estimate of Q for each time step is taken as
% the solution from the previous time step.
%
% ERR and EXITFLAG are also Mx1 and indicate the results of optimisation
% for the corresponding trajectory step.
%
% Notes::
% - Requires fminunc from the MATLAB Optimization Toolbox.
% - Joint limits are not considered in this solution.
% - Can be used for robots with arbitrary degrees of freedom.
% - In the case of multiple feasible solutions, the solution returned
%   depends on the initial choice of Q0
% - Works by minimizing the error between the forward kinematics of the
%   joint angle solution and the end-effector frame as an optimisation.
%   The objective function (error) is described as:
%           sumsqr( (inv(T)*robot.fkine(q) - eye(4)) * omega )
%   Where omega is some gain matrix, currently not modifiable.
%
% Author::
% Bryan Moutrie
%
% See also SerialLink.ikcon, fmincon, SerialLink.ikine, SerialLink.fkine.

% Copyright (C) Bryan Moutrie, 2013-2015
% Licensed under the GNU Lesser General Public License
% see full file for full statement
%
% LICENSE STATEMENT:
%
% This file is part of pHRIWARE.
%
% pHRIWARE is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as
% published by the Free Software Foundation, either version 3 of
% the License, or (at your option) any later version.
%
% pHRIWARE 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 Lesser General Public
% License along with pHRIWARE.  If not, see <http://www.gnu.org/licenses/>.

function [qstar, error, exitflag, output] = ikunc(robot, T, varargin)

    % check if Optimization Toolbox exists, we need it
    assert( exist('fminunc', 'file')>0, 'rtb:ikunc:nosupport', 'Optimization Toolbox required');

    if isa(T, 'SE3')
        T = T.T;
    end

    % create output variables
    T_sz = size(T,3);
    qstar = zeros(T_sz,robot.n);
    error = zeros(T_sz,1);
    exitflag = zeros(T_sz,1);

    problem.solver = 'fminunc';
    problem.x0 = zeros(1, robot.n);
    problem.options = optimoptions('fminunc', ...
        'Algorithm', 'quasi-newton', ...
        'Display', 'off'); % default options for ikunc

    if nargin > 2
        % check if there is a q0 passed
        if isnumeric(varargin{1}) && length(varargin{1}) == robot.n
            problem.x0 = varargin{1};
            varargin = varargin(2:end);
        end
    end
    if ~isempty(varargin)
        % if given, add optional argument to the list of optimiser options
        problem.options = optimoptions(problem.options, varargin{:});
    end

    reach = sum(abs([robot.a, robot.d]));
    omega = diag([1 1 1 3/reach]);

    for t = 1:T_sz
        problem.objective = ...
            @(x) sumsqr(((T(:,:,t) \ robot.fkine(x).T) - eye(4)) * omega);

        [q_t, err_t, ef_t, out_t] = fminunc(problem);

        if ef_t ~= 1
            if T_sz > 1
                warning('step %d: errflag = %d, err = %f\n', t, ef_t, err_t);
            else
                warning('errflag = %d, err = %f\n', ef_t, err_t);
                out_t
            end
        end
        qstar(t,:) = q_t;
        error(t) = err_t;
        exitflag(t) = ef_t;
        output(t) = out_t;

        problem.x0 = q_t;
    end

end

function s = sumsqr(A)
    s = sum(A(:).^2);
end


function Z = convolution1d(X, W, b)
% convolution1d   A fully connected layer
%
%   Z = convolution1d(X, W, b) applies a fully connected layer. We call it
%   1-D convolution because this is what it's called in the original GPT-2
%   repo.
%
%   Inputs:
%       X   - A numInputFeatures-by-numInputSubwords array.
%       W   - A numOutputFeatures-by-numInputFeatures weight matrix.
%       b   - A numOutputFeatures-by-1 bias vector.
%
%   Output:
%       Z   - A numOutputFeatures-by-numInputSubwords array.

Z = dlmtimes(W,X) + b;

end


function [dat] = ft_preproc_hilbert(dat, option)

% FT_PREPROC_HILBERT computes the Hilbert transpose of the data and optionally
% performs post-processing on the complex representation, e.g. the absolute
% value of the Hilbert transform of a band-pass filtered signal corresponds
% with the amplitude envelope.
%
% Use as
%   [dat] = ft_preproc_hilbert(dat, option)
% where
%   dat        data matrix (Nchans X Ntime)
%   option     string that determines whether and how the Hilbert transform
%              should be post-processed, can be
%                'abs'
%                'complex'
%                'real'
%                'imag'
%                'absreal'
%                'absimag'
%                'angle'
%
% The default is to return the absolute value of the Hilbert transform.
%
% See also PREPROC

% Copyright (C) 2008, 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$

% set the defaults if option is not specified
if nargin<2 || isempty(option)
  option = 'abs';
end

% preprocessing fails on channels that contain NaN
if any(isnan(dat(:)))
  ft_warning('FieldTrip:dataContainsNaN', 'data contains NaN values');
end

% use the non-conjugate transpose to be sure
dat = transpose(hilbert(transpose(dat)));

% do postprocessing of the complex representation
switch option
    case {'yes' 'abs'}
        dat = abs(dat);   % this is the default if 'yes' is specified
    case {'no' 'complex'}
        dat = dat;        % this is the default if 'no' is specified
    case 'real'
        dat = real(dat);
    case 'imag'
        dat = imag(dat);
    case 'absreal'
        dat = abs(real(dat));
    case 'absimag'
        dat = abs(imag(dat));
    case 'angle'
        dat = (angle(dat./abs(dat)));
    case 'unwrap_angle'
        dat = unwrap(angle(dat./abs(dat)),[],2);
    otherwise
        ft_error('incorrect specification of the optional input argument');
end


% Copyright 2016 Google Inc.
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http ://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.

% Slice (apply) bilateral guided upsampling.
%
% Inputs:
%
% gamma: the affine bilateral grid.
%   size: [height width depth num_output_channels num_input_channels]
% input_image is a double tensor: the (full-resolution) input image
% edge_image is a double matrix: the (full-resolution) edge image
%
function output = bguSlice(gamma, input_image, edge_image)

% Find downsampling coordinates, without rounding.
input_height = size(input_image, 1);
input_width = size(input_image, 2);
grid_height = size(gamma, 1);
grid_width = size(gamma, 2);
grid_depth = size(gamma, 3);
affine_output_size = size(gamma, 4);
affine_input_size = size(gamma, 5);

% meshgrid inputs and outputs are x, then y, with x right, y down.
[ x, y ] = meshgrid(0:(input_width - 1), 0:(input_height - 1));

% Downsample x and y to grid space (leaving them as floats).
bg_coord_x = ((x + 0.5) * (grid_width - 1) / input_width);
bg_coord_y = ((y + 0.5) * (grid_height - 1) / input_height);
bg_coord_z = edge_image * (grid_depth - 1);

% Add 1 to all coordinates for MATLAB.
bg_coord_xx = bg_coord_x + 1;
bg_coord_yy = bg_coord_y + 1;
bg_coord_zz = bg_coord_z + 1;

% interp3 takes xx, yy, zz.
affine_model = {affine_output_size, affine_input_size};
for j = 1:affine_input_size
    for i = 1:affine_output_size
            affine_model{i,j} = interp3(gamma(:,:,:,i,j), ...
                bg_coord_xx, bg_coord_yy, bg_coord_zz);
    end
end

% Iterate over each row.
% TODO: optimize this.
for i = 1:affine_output_size
    affine_model2{i,1} = cat(4, affine_model{i,:});
end
affine_model3 = cat(3, affine_model2{:,1});

input1 = cat(3, input_image, ones(size(input_image,1), size(input_image,2)));

output = 0;
for i = 1:affine_input_size
    output = output + bsxfun(@times, affine_model3(:,:,:,i), input1(:,:,i));
end