function [field, allVarString, indVarName, pdeVarNames, pdeflag, ...
    eigVarNames, allVarNames]  = setupFields(guifile, input, type, allVarString)
%SETUPFIELDS   Convert input from GUI window to format useful for Chebfun.
%
% Calling sequence:
%
%   [FIELD, ALLVARSTRING, INDVARNAME, PDEVARNAMES, PDEFLAG,  EIGVARNAMES, ...
%       ALLVARNAMES] = SETUPFIELDS(GUIFILE, INPUT, TYPE, ALLVARSTRING)
%
% Here, the inputs are:
%
%   GUIFILE:        A CHEBGUI object, describing the problem shown in the GUI.
%   INPUT:          The 'String' property of a particular input field of the GUI.
%   TYPE:           The type of the field (differential equation, boundary
%                   conditions or initial guess/condition).
%   ALLVARSTRING:   A strings, containing the name of all variables that appear
%                   in a problem.
%
% The outputs are:
%   FIELD:          A string that can be converted to anonymous function,
%                   describing the INPUT variable.
%   ALLVARSTRING:   A strings, containing the name of all variables that appear
%                   in a problem.
%   INDVARNAME:     A cell-array of strings that contains the name of the
%                   independent variables that appear in the problem. The first
%                   entry corresponds to the time variable, the second to the
%                   potential time variable.
%   PDEVARNAMES:    A cell array of strings that appear on PDE format in INPUT,
%                   i.e. u_t.
%   PDEFLAG:        A vector, whose kth element is equal to 1 of the kth line of
%                   INPUT is of PDE format, e.g. u_t = u'', 0 otherwise.
%   EIGVARNAMES:    A string that indicates how the eigenvalue parameter appears
%                   in the problem, that is, either l, lam or lambda.
%   ALLVARNAMES:    A cell array of string, containing the name of all variables
%                   that appear in a problem.

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

% For BCs, we need to check whether varNames contains anything not found in
% varNames of the DE. Should we make the varNames of the DE as parameters? Also
% check for indVarName in deRHS.

% Number of rows in the input.
numOfRows = max(size(input));

% Binary flag for PDE detection. The kth element is going to be equal to 1 of
% the kth row of the input has PDE input in it, e.g. u_t.
pdeflag = zeros(1,numOfRows);

% What variables appear with the PDE subscript _ on them?
pdeVarNames = '';

% A temporary string for the space variable, as we don't know yet whether it is
% going to be r, t or x. This will then get replaced later.
dummys = 'DUMMYSPACE';

if ( numOfRows == 1 )
    % In this case, we only have to deal with a single line of input.
    [anFun, indVarName, allVarNames, pdeVarNames, eigVarNames, commaSeparated] = ...
        setupLine(guifile, input{1}, type);

    % Check whether we have too many variables involved in a PDE.
    if ( ~isempty(pdeVarNames) ) % Not a PDE (or we can't do this type yet!)
        pdeflag = true;

        % Are we actually working in PDE mode?
        assert(strcmpi(guifile.type, 'PDE'), ...
            'CHEBFUN:CHEBGUI:setupField:incorrectPDEmode', ...
            ['Problem specified appears to be a PDE. Please ensure you''re' ...
            'working in the correct mode in Chebgui.'])

        % Check whether we have a match of variable names, i.e. we want u
        % and u_t, not u and v_t:
        if ( (length(allVarNames) > 1) || (length(pdeVarNames) > 1) )
            error('CHEBFUN:CHEBGUI:setupFields:numberOfVariables', ...
                'Too many variables.');
        end

        % Find where the PDE variable appears:
        underScoreLocation = strfind(pdeVarNames{1},'_');
        if ( ~strcmp(allVarNames{1}, pdeVarNames{1}(1:underScoreLocation-1)) )
            error('CHEBFUN:CHEBGUI:setupFields:variableNames', ...
                'Inconsistent variable names.');
        end
    end

    % Only need to convert the cell to a string for DE -- information has been
    % passed for BCs
    if ( strcmp(type, 'DE') )
        allVarString = allVarNames{1};
    end

    % Create the string which will become the anonymous function. Put x (or t)
    % as the first argument of the anonymous function if we have a BVP or EIG.

    % If we are working with an eigenvalue problem, the differential equation
    % will have important information on both sides of the = sign if we are
    % solving a generalized problem. In this case, we want to keep the input in
    % two separate strings in a cell-array.
    if ( strcmp(guifile.type, 'eig') && iscell(anFun) )
        field1 = ['@(', dummys, ',', allVarString, ') ', anFun{1}];
        field2 = ['@(', dummys, ',', allVarString, ') ', anFun{2}];
        field = {field1 ; field2};
    elseif ( ~strcmp(guifile.type, 'pde') && strcmp(type, 'DE') )
        field = ['@(', dummys, ',', allVarString, ') ', anFun];

    % Otherwise, add variables in front of what will be anonymous functions.
    % This is not needed for 'dirichlet', 'neumann', etc... This can only happen
    % in BCs, and in that case, allVarNames will be empty
    elseif ( ~isempty(allVarNames) )
        if ( commaSeparated )
            anFun = ['[', anFun, ']'];
        end

        if ( strcmp(type, 'BCnew') )
            field = ['@(', dummys, ',', allVarString, ') ', anFun];
        else
            field = ['@(', allVarString, ') ', anFun, ''];
        end
    else
        field = anFun;
    end

else % Have a system, go through each row
    % Keep track of every variable encountered in the problem
    allVarNames = {};
    allPdeVarNames = {};
    indVarName = [];
    anFun = cell(1, numOfRows);
    % Loop through the rows
    for k = 1:numOfRows
        [anFun{k}, indVarNameTemp, varNames, pdeVarNames, eigVarNames, dummy] = ...
            setupLine(guifile, input{k}, type);
        if ( strcmp(anFun{k}([1 end]), '[]') )
            anFun{k}([1 end]) = [];
        end

        % Update what variables appear in the problem.
        allVarNames = [allVarNames ; varNames];

        % Only allow one time derivative in each line
        if ( length(pdeVarNames) > 1 )
            error('CHEBFUN:CHEBGUI:setupFields:tooManyTimeDerivatives', ...
                'Only one time derivative per line allowed')
        end

        if ( isempty(pdeVarNames) )
            % Indicate that no PDE variable was found in this line.
            pdeVarNames = '|';
        else
            % Indicate that this line was of PDE format.
            pdeflag(k) = 1;
        end

        if ( isempty(indVarName) )
            indVarName = indVarNameTemp;
        elseif ( ~myStringCompare(indVarName{1}, indVarNameTemp{1}) || ...
                ~myStringCompare(indVarName{2}, indVarNameTemp{2}) )
            error('CHEBFUN:CHEBGUI:setupFields:differentIndepVars', ...
                'Different names for independent variables detected')
        end

        % Update what variables appear on PDE format.
        allPdeVarNames = [allPdeVarNames ; pdeVarNames];
    end

    % Remove duplicate variable names
    allVarNames = unique(allVarNames);

    % Construct the handle part. For the DE field, we need to collect all
    % the variable names in one string. If we are working with BCs, we have
    % already passed that string in (as the parameter allVarString).
    if ( strcmp(type, 'DE') )
        allVarString = allVarNames{1};
        for varCounter = 2:length(allVarNames)
            allVarString = [allVarString, ',', allVarNames{varCounter}];
        end
    end

    indx = (1:numOfRows)';
    % For PDEs we need to reorder so that the order of the time derivatives
    % matches the order of the input arguments.
    if ( any(pdeflag) )
        for k = 1:numel(allPdeVarNames)
            if ( ~pdeflag(k) )
                continue % Not a PDE variable, do nothing
            end

            vark = allPdeVarNames{k};
            if ( strcmp(vark, '|') )
                continue  % Skip dummy pdevarname
            end

            % Get the kth pdevarname
            vark = vark(1:find(vark == '_', 1, 'first')-1);

            % Find which varname this matches
            idx3 = find(strcmp(vark,allVarNames));

            % Update the index list
            indx(find(indx == idx3)) = indx(k);
            indx(k) = idx3;
        end

        [dummy, indx] = sort(indx);     % Invert the index
        pdeflag = pdeflag(indx);        % Update the pdeflags
        allPdeVarNames(strcmp(allPdeVarNames, '|')) = []; % Delete the junk
        pdeVarNames = allPdeVarNames;
    end

    % Did we have PDE variables but are not actually working in PDE mode?
    assert( ~( any(pdeflag) && ~strcmpi(guifile.type, 'PDE')), ...
        'CHEBFUN:CHEBGUI:setupField:incorrectPDEmode', ...
        ['Problem specified appears to be a PDE. Please ensure that you''re' ...
        ' working in the correct mode in Chebgui.'])

    % If we are solving a BVP or EIG, we now need x as the first argument as
    % well. However, we don't want that variable in allVarString as we use that
    % information when setting up BCs. Create the string that goes at the start
    % of the final string.
    if ( (~strcmp(guifile.type, 'pde') && strcmp(type, 'DE')) || ...
            strcmp(type, 'BCnew') )
        fieldStart = ['@(', dummys, ',', allVarString, ') '];
    else
        fieldStart = ['@(', allVarString, ') '];
    end

    % Construct the function. Need to treat eig. problems separately as there we
    % can have nontrivial LHS and RHS at the same time.
    allAnFun = [];
    if ( strcmp(guifile.type, 'eig') && iscell(anFun{1}) )
        allAnFun1 = [];
        allAnFun2 = [];
        for k = 1:numOfRows
            allAnFun1 = [allAnFun1, anFun{indx(k)}{1}, ';'];
            allAnFun2 = [allAnFun2, anFun{indx(k)}{2}, ';'];
        end

        % Remove the last comma
        allAnFun1(end) = [];
        allAnFun2(end) = [];

        % Set up LHS and RHS fields
        field1 = [fieldStart, '[', allAnFun1, ']'];
        field2 = [fieldStart, '[', allAnFun2, ']'];
        field = {field1 ; field2};
    else
        % Concatenate each anonymous functions vertically.
        for k = 1:numOfRows
            allAnFun = [allAnFun, anFun{indx(k)},  '; '];
        end
        allAnFun(end-1:end) = []; % Remove the last semicolon and space.

        % Wrap the concatenated field with []-s.
        field = [fieldStart, '[', allAnFun, ']'];
    end

end

end

function [field, indVarName, varNames, pdeVarNames, eigVarNames, commaSeparated] ...
    = setupLine(guifile, input, type)
%SETUPLINE      Convert an individual input line to format useful for Chebfun.
%
% Calling sequence:
%
%   [FIELD, INDVARNAME, VARNAMES, PDEVARNAMES, EIGVARNAMES, COMMASEPARATED] =
%       SETUPLINE(GUIFILE, INPUT, TYPE)
%
% Here, the inputs are:
%
%   GUIFILE:        A CHEBGUI object, describing the problem shown in the GUI.
%   INPUT:          A single line of the 'String' property of a particular
%                   input field of the GUI.
%   TYPE:           The type of the field (differential equation, boundary
%                   conditions or initial guess/condition).
%
% The outputs are:
%   FIELD:          A string that can be converted to anonymous function,
%                   describing the INPUT variable.
%   INDVARNAME:     A cell-array of strings that contains the name of the
%                   independent variables that appear in the problem. The first
%                   entry corresponds to the time variable, the second to the
%                   potential time variable.
%   VARNAMES:       A cell array of string, containing the name of all variables
%                   that appear in the line INPUT.
%   PDEVARNAMES:    A cell array of strings that appear on PDE format in the
%                   line INPUT, i.e. u_t.
%   EIGVARNAMES:    A string that indicates how the eigenvalue parameter appears
%                   in the problem, that is, either l, lam or lambda.
%   COMMASEPARATED: Equal to 1 if the line INPUT is comma separated, for
%                   example, "u=1, v=2+x".

% Do we need to convert a BC to an anonymous function?
convertBCtoAnon = 0;

% Usually, input lines are not comma separated.
commaSeparated = 0;

if ( ~isempty(strfind(input, '@')) ) % User supplied anon. function
    % Look at the part of the string that starts after the @(x,u,...) part.
    firstRPloc = strfind(input, ')');
    trimmedInput = input(firstRPloc+1:end);

    % Inspect the string, which will give us the name of the independent
    % variable (which we assume to be either r, x or t).
    [field, indVarName, varNames, pdeVarNames, eigVarNames, commaSeparated] = ...
        stringParser.str2anon(trimmedInput, guifile.type, type);

    return

elseif ( any(strcmp(type,{'BC','BCnew'})) )  % More types of syntax for BCs
    bcNum = str2num(input);

    % Check whether we have a number (OK), allowed strings (OK) or whether
    % we will have to convert the string to anon. function (i.e. the input
    % is on the form u' +1 = 0).
    if ( ~isempty(bcNum) )
        field = input;
        indVarName = []; % Don't need to worry about lin. func. in this case
        varNames = [];
        pdeVarNames = [];
        eigVarNames = [];
    elseif ( strcmpi(input, 'dirichlet') || strcmpi(input, 'neumann') || ...
            strcmpi(input, 'periodic') )
        % Add extra 's to allow evaluation of the string
        field = ['''', input, ''''];
        indVarName = []; % Don't need to worry about lin. func. in this case
        varNames = [];
        pdeVarNames = [];
        eigVarNames = [];
    else
        convertBCtoAnon = 1;
        guifile.type = 'bvp'; % Convert to 'BVP' type for BCs.
    end
end

if ( any(strcmp(type, {'DE', 'INIT', 'INITSCALAR'})) || convertBCtoAnon )
    % Convert to anonymous function string
    [field, indVarName, varNames, pdeVarNames, eigVarNames, commaSeparated] = ...
        stringParser.str2anon(input, guifile.type, type);
end

end

function res =  myStringCompare(str1, str2)
% Modified strcmp, if we compare with an empty string, give a match
if ( isempty(str1) || isempty(str2) )
    res = 1;
else
    res = strcmp(str1, str2);
end

end


function st = type( x )

s = size( x );
len = prod( s );
if len == 1,
    nzs = len;
    st = 'scalar';
else
    nzs = nnz( any( cvx_basis( x ), 1 ) );
    nd = length( s );
    st = sprintf( '%dx', s );
    st = st( 1 : end - 1 );
    if nd > 2,
        st = [ st, ' array' ];
    elseif any( s == len ),
        st = [ st, ' vector' ];
    else
        st = [ st, ' matrix' ];
    end
end
if nzs < len,
    if nzs > 1,
        st = sprintf( '%s, %d nonzeros', st, nzs );
    elseif nzs == 1,
        st = sprintf( '%s, 1 nonzero', st );
    end
end

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


classdef TestGetOptimalDFTSize
    %TestGetOptimalDFTSize

    methods (Static)
        function test_1
            N = cv.getOptimalDFTSize(101);
            validateattributes(N, {'numeric'}, {'scalar', 'integer'});
        end

        function test_error_argnum
            try
                cv.getOptimalDFTSize();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function varargout = process_plv1( varargin )
% PROCESS_PLV1: Compute the Phase locking value between one signal and all the others, in one file.

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2012-2020

eval(macro_method);
end

%% ===== GET DESCRIPTION =====
function sProcess = GetDescription() %#ok<DEFNU>
    % Description the process
    sProcess.Comment     = 'Phase locking value 1xN';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Connectivity';
    sProcess.Index       = 670;
    sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/Connectivity';
    % Definition of the input accepted by this process
    sProcess.InputTypes  = {'data',     'results',  'matrix'};
    sProcess.OutputTypes = {'timefreq', 'timefreq', 'timefreq'};
    sProcess.nInputs     = 1;
    sProcess.nMinFiles   = 1;

    % === CONNECT INPUT
    sProcess = process_corr1n('DefineConnectOptions', sProcess, 0);
    % === FREQ BANDS
    sProcess.options.freqbands.Comment = 'Frequency bands for the Hilbert transform:';
    sProcess.options.freqbands.Type    = 'groupbands';
    sProcess.options.freqbands.Value   = bst_get('DefaultFreqBands');
    % === PLV METHOD
    sProcess.options.plvmethod.Comment = {'PLV: Phase locking value', 'ciPLV:  Corrected imaginary phase locking value', 'wPLI: Weighted phase lag index'; 'plv', 'ciplv', 'wpli'};
    sProcess.options.plvmethod.Type    = 'radio_label';
    sProcess.options.plvmethod.Value   = 'plv';
    % === KEEP TIME
    sProcess.options.keeptime.Comment = 'Keep time information, and estimate the PLV across trials
(requires the average of many trials)';
    sProcess.options.keeptime.Type    = 'checkbox';
    sProcess.options.keeptime.Value   = 0;
    % === PLV MEASURE
    sProcess.options.plvmeasure.Comment = {'None (complex)', 'Magnitude', 'Measure:'};
    sProcess.options.plvmeasure.Type    = 'radio_line';
    sProcess.options.plvmeasure.Value   = 2;
    % === OUTPUT MODE
    sProcess.options.outputmode.Comment = {'Save individual results (one file per input file)', 'Concatenate input files before processing (one file)', 'Save average connectivity matrix (one file)'};
    sProcess.options.outputmode.Type    = 'radio';
    sProcess.options.outputmode.Value   = 1;
    sProcess.options.outputmode.Group   = 'output';
end

%% ===== FORMAT COMMENT =====
function Comment = FormatComment(sProcess) %#ok<DEFNU>
    if ~isempty(sProcess.options.plvmethod.Value)
        iMethod = find(strcmpi(sProcess.options.plvmethod.Comment(2,:), sProcess.options.plvmethod.Value));
        if ~isempty(iMethod)
            Comment = str_striptag(sProcess.options.plvmethod.Comment{1,iMethod});
        else
            Comment = sProcess.Comment;
        end
    else
        Comment = sProcess.Comment;
    end
end

%% ===== RUN =====
function OutputFiles = Run(sProcess, sInputA) %#ok<DEFNU>
    % Input options
    OPTIONS = process_corr1n('GetConnectOptions', sProcess, sInputA);
    if isempty(OPTIONS)
        OutputFiles = {};
        return
    end
    % Keep time or not: different methods
    OPTIONS.Method = sProcess.options.plvmethod.Value;
    if sProcess.options.keeptime.Value
        OPTIONS.Method = [OPTIONS.Method 't'];
    end
    % Hilbert and frequency bands options
    OPTIONS.Freqs = sProcess.options.freqbands.Value;
    OPTIONS.isMirror = 0;
    % PLV measure
    if isfield(sProcess.options, 'plvmeasure') && isfield(sProcess.options.plvmeasure, 'Value') && ~isempty(sProcess.options.plvmeasure.Value)
        switch (sProcess.options.plvmeasure.Value)
            case 1,  OPTIONS.PlvMeasure = 'none';
            case 2,  OPTIONS.PlvMeasure = 'magnitude';
        end
    else
        OPTIONS.PlvMeasure = 'magnitude';
    end

    % Compute metric
    OutputFiles = bst_connectivity({sInputA.FileName}, {sInputA.FileName}, OPTIONS);
end


%kvskthick 'Exoskeleton by Thickening'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vskthick.pane file
%
% Parameters:
% InputFile: i 'Input Image ', required: 'input image'
% InputFile: str1 'Struct Element 1', required: 'Structuring Element'
% InputFile: str2 'Struct Element 2', required: 'Structuring Element'
% MultiChoice: r 'Struct El. Rotation Step', default: 1: 'Rotation step'
%    Choices are:
%   1: '1 '
%   2: '2 '
%   3: '4 '
% OutputFile: o 'Output Image ', required: 'resulting output image'
%
% Example: o = kvskthick({i, str1, str2}, {'i','';'str1','';'str2','';'r',1;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% vskthick - Exoskeleton by Thickening
%
%  DESCRIPTION
% .I vskthick
% will do the exoskeleton by thickening of an input image by a set of structuring elements.
%
% The output image data type will be the same as that of the highest data type
% of the input image.
%
% Some useful pairs of structuring elements:
%
%                               0 0 0    1 1 1
%   Conditional Segmentation    0 1 0    0 0 0
%                               1 1 1    0 0 0
%
%                               0 0 0    1 0 0
%   Pseudo Convex Hull          0 1 1    1 0 0
%                               0 0 0    1 0 0
%
%                               1 0 0    0 0 0
%   Convex Hull                 1 0 0    0 1 0
%                               1 0 0    0 0 0
%
%                               0 0 0    1 1 1
%   Homotopic Pruning           0 1 0    1 0 1
%                               0 0 0    1 1 1
%
%
%
%  EXAMPLES
% vskthick -i ball.xv -str1 b272.str -str2 b273.str -r 1 -o outimage.xv
%
% Will do the exoskeleton by thickening of image 1 "ball.xv" by the structuring element b272.str and b273.str, rotating the struct. els. 1 step after each iteration, with the resulting image written to "outimage.xv".
%
%  "SEE ALSO"
% vcast1(1)
%
%  RESTRICTIONS
% .I vskthick
% can be defined for all data types supported by Khoros, but at the moment it has been implemented just for the bit and unsigned char types.
% The structuring elements are subsets of the 3x3 matrix and the origin is always at the center of this matrix.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993-1997 Junior Barrera, Roberto Lotufo.  All rights reserved.
%

function varargout = kvskthick(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kvskthick(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'str1', '__input';'str2', '__input';'r', 1;'o', '__output'};
maxval={0,0,0,0,0};
minval={0,0,0,0,0};
istoggle=[0,0,0,0,0];
was_set=istoggle * 0;
paramtype={'InputFile','InputFile','InputFile','MultiChoice','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'vskthick"  '],Inputs,narglist);


function cvx_expert_check( fname, varargin )

global cvx___
if ~cvx___.expert && ( isempty(varargin) || any( cellfun( 'isclass', varargin, 'cvx' ) ) ),
    fprintf( 1, [ 'CVX Warning:\n', ...
        '   Models involving "%s" or other functions in the log, exp, and entropy\n', ...
        '   family are solved using an experimental successive approximation method.\n', ...
        '   The method requires multiple calls to the solver, so it can be slow; and\n', ...
        '   in certain cases it fails to converge. See Appendix D of the the user''s\n', ...
        '   guide for more information about this method, and for instructions on how\n', ...
        '   to suppress this warning in the future.\n' ], fname );
    cvx___.expert = true;
end


function result  = omp_spr(Y, K, epsilon, sparse_output)
    if nargin < 4
        sparse_output = 1;
    end
    Y_normalized = spx.norm.normalize_l2(Y);
    result = mex_omp_spr(Y, Y_normalized, K, epsilon, sparse_output);
end


function [y, dzdg, dzdb, moments] = vl_nnbnorm_wrapper(x, g, b, moments, test, varargin)
%VL_NNBNORM_WRAPPER AutoNN wrapper for MatConvNet's vl_nnbnorm
%   VL_NNBNORM has a non-standard interface (returns a derivative for the
%   moments, even though they are not an input), so we must wrap it.
%   Layer.vl_nnbnorm replaces a standard VL_NNBNORM call with this one.
%
%   This also lets us supports nice features like setting the parameter
%   sizes automatically (e.g. building a net with VL_NNBNORM(X) is valid).

% Copyright (C) 2016-2017 Joao F. Henriques.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

  % use number of channels in X to extend scalar (i.e. default) params to
  % the correct size. this way the layer can be constructed without
  % knowledge of the number of channels. scalars also permit gradient
  % accumulation with any tensor shape (in CNN_TRAIN_AUTONN).
  if isscalar(g)
    g(1:size(x,3),1) = g ;
  end
  if isscalar(b)
    b(1:size(x,3),1) = b ;
  end
  if isscalar(moments)
    moments(1:size(x,3),1:2) = moments ;
  end

  if isempty(x)
    % vl_nnbnorm throws an error on empty inputs. however, these can happen
    % in some dynamic architectures, so handle this case.
    y = zeros(size(x), 'like', x) ;
    if nargout > 1
      dzdg = zeros(size(g), 'like', g) ;
      dzdb = zeros(size(b), 'like', b) ;
      moments = zeros(size(moments), 'like', moments) ;
    end
    return
  end

  if ~test
    if numel(varargin) >= 1 && isnumeric(varargin{1})
      % training backward mode
      [y, dzdg, dzdb, moments] = vl_nnbnorm(x, g, b, varargin{:}) ;
    else
      % training forward mode
      y = vl_nnbnorm(x, g, b, varargin{:}) ;
    end
  else
    % test mode, pass in moments
    if numel(varargin) >= 1 && isnumeric(varargin{1})
      % test backward mode (to implement e.g. bnorm frozen during training)
      [y, dzdg, dzdb, moments] = vl_nnbnorm(x, g, b, varargin{1}, 'moments', moments, varargin{2:end}) ;
    else
      % test forward mode
      y = vl_nnbnorm(x, g, b, 'moments', moments, varargin{:}) ;
    end
  end

end


function ReinhardTMOv(hdrv, filenameOutput, tmo_alpha, tmo_white, tmo_gamma, tmo_quality, tmo_video_profile)
%
%
%      ReinhardTMOv(hdrv, filenameOutput, tmo_alpha, tmo_white, tmo_gamma, tmo_quality, tmo_video_profile)
%
%
%       Input:
%           -hdrv: a HDR video structure; use hdrvread to create a hdrv
%           structure
%           -filenameOutput: output filename (if it has an image extension,
%           single files will be generated)
%           -tmo_alpha:
%           -tmo_white:
%           -tmo_gamma: gamma for encoding the frame
%           -tmo_quality: the output quality in [1,100]. 100 is the best quality
%           1 is the lowest quality.%
%           -tmo_video_profile: the compression profile (encoder) for compressing the stream.
%           Please have a look to the profile of VideoWriter from the MATLAB
%           help. Depending on the version of MATLAB some profiles may be not
%           be present.
%
%     Copyright (C) 2013-15 Francesco Banterle
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
%
%     The paper describing this technique is:
%     "Real-time Automated Tone Mapping System for HDR Video"
% 	  by Chris Kiser, Erik Reinhard, Mike Tocci and Nora Tocci
%     in IEEE International Conference on Image Processing, 2012
%
%

if(~exist('tmo_alpha', 'var'))
    tmo_alpha = 0.5;
end

if(~exist('tmo_white', 'var'))
    tmo_white = 1e6;
end

if(~exist('tmo_gamma', 'var'))
    tmo_gamma = -2.2;
end

if(tmo_gamma < 0)
    bsRGB = 1;
else
    bsRGB = 0;
end

if(~exist('tmo_quality', 'var'))
    tmo_quality = 95;
end

if(~exist('tmo_video_profile', 'var'))
    tmo_video_profile = 'MPEG-4';
end

name = RemoveExt(filenameOutput);
ext  = fileExtension(filenameOutput);

bVideo = 0;
writerObj = 0;

if(strcmp(ext, 'avi') == 1 | strcmp(ext, 'mp4') == 1)
    bVideo = 1;
    writerObj = VideoWriter(filenameOutput, tmo_video_profile);
    writerObj.FrameRate = hdrv.FrameRate;
    writerObj.Quality = tmo_quality;
    open(writerObj);
end

hdrv = hdrvopen(hdrv, 'r');

disp('Tone Mapping...');

beta = 0.5;

for i=1:hdrv.totalFrames
    disp(['Processing frame ', num2str(i)]);
    [frame, hdrv] = hdrvGetFrame(hdrv, i);

    %Only physical values
    frame = RemoveSpecials(frame);
    frame(frame < 0) = 0;

    %computing statistics for the current frame
    L = lum(frame);
    Lav_cur = logMean(L);

    if(i == 1)
        Lav_prev = Lav_cur;
    end

    Lav = Lav_prev * (1 - beta) + beta * Lav_cur;

    %tone mapping
    [frameOut, ~, ~] = ReinhardTMO(frame, tmo_alpha, tmo_white, 'global', -1, Lav);

    %Gamma/sRGB encoding
    if(bsRGB)
        frameOut = ConvertRGBtosRGB(frameOut, 0);
    else
        frameOut = GammaTMO(frameOut, tmo_gamma, 0, 0);
    end

    frameOut = ClampImg(frameOut, 0.0, 1.0);

    if(bVideo)
        writeVideo(writerObj, frameOut);
    else
        imwrite(frameOut, [name, sprintf('%.10d',i), '.', ext]);
    end

    %updating for the next frame
    Lav_prev = Lav;
end
disp('OK');

if(bVideo)
    close(writerObj);
end

hdrvclose(hdrv);

end


classdef Layer < handle
  %LAYER Base class for a network layer in a DagNN

  properties (Access = public, Hidden, Transient)
    net
    layerIndex
  end

  methods
    function outputs = forward(obj, inputs, params)
    %FORWARD Forward step
    %  OUTPUTS = FORWARD(OBJ, INPUTS, PARAMS) takes the layer object OBJ
    %  and cell arrays of inputs and parameters and produces a cell
    %  array of outputs evaluating the layer forward.
      outputs = {} ;
    end

    function [derInputs, derParams] = backward(obj, inputs, params, derOutpus)
    %BACKWARD  Bacwkard step
    %  [DERINPUTS, DERPARAMS] = BACKWARD(OBJ, INPUTS, INPUTS, PARAMS,
    %  DEROUTPUTS) takes the layer object OBJ and cell arrays of
    %  inputs, parameters, and output derivatives and produces cell
    %  arrays of input and parameter derivatives evaluating the layer
    %  backward.
      derInputs = {} ;
      derOutputs = {} ;
    end

    function reset(obj)
    %RESET Restore internal state
    %  RESET(OBJ)resets the layer OBJ, clearing any internal state.
    end

    function params = initParams(obj)
    %INIT Initialize layer parameters
    %  PARAMS = INIT(OBJ) takes the layer OBJ and returns a cell
    %  array of layer parameters PARAMS with some initial
    %  (e.g. random) values.
      params = {} ;
    end

    function move(obj, device)
    %MOVE Move data to CPU or GPU
    %  MOVE(DESTINATION) moves the data associated to the layer object OBJ
    %  to either the 'gpu' or the 'cpu'. Note that variables and
    %  parameters are moved automatically by the DagNN object
    %  containing the layer, so this operation affects only data
    %  internal to the layer (e.g. the mask in dropout).
    end

    function forwardAdvanced(obj, layer)
    %FORWARDADVANCED  Advanced driver for forward computation
    %  FORWARDADVANCED(OBJ, LAYER) is the advanced interface to compute
    %  the forward step of the layer.
    %
    %  The advanced interface can be changed in order to extend DagNN
    %  non-trivially, or to optimise certain blocks.

      in = layer.inputIndexes ;
      out = layer.outputIndexes ;
      par = layer.paramIndexes ;
      net = obj.net ;

      inputs = {net.vars(in).value} ;

      % give up if any of the inputs is empty (this allows to run
      % subnetworks by specifying only some of the variables as input --
      % however it is somewhat dangerous as inputs could be legitimaly
      % empty)
      if any(cellfun(@isempty, inputs)),         return ; end

      % clear inputs if not needed anymore
      for v = in
        net.numPendingVarRefs(v) = net.numPendingVarRefs(v) - 1 ;
        if net.numPendingVarRefs(v) == 0
          if ~net.vars(v).precious & ~net.computingDerivative & net.conserveMemory
            net.vars(v).value = [] ;
          end
        end
      end

      % call the simplified interface
      outputs = obj.forward(inputs, {net.params(par).value}) ;
      [net.vars(out).value] = deal(outputs{:}) ;

    end

    function backwardAdvanced(obj, layer)
    %BACKWARDADVANCED Advanced driver for backward computation
    %  BACKWARDADVANCED(OBJ, LAYER) is the advanced interface to compute
    %  the backward step of the layer.
    %
    %  The advanced interface can be changed in order to extend DagNN
    %  non-trivially, or to optimise certain blocks.
      in = layer.inputIndexes ;
      out = layer.outputIndexes ;
      par = layer.paramIndexes ;
      net = obj.net ;

      inputs = {net.vars(in).value} ;
      derOutputs = {net.vars(out).der} ;
%       for i = 1:numel(derOutputs)
%         if isempty(derOutputs{i}), return ; end
%       end
        if all(cellfun(@isempty,derOutputs)), return ; end
        if any(cellfun(@isempty, inputs)),
            return ;
        end

      if net.conserveMemory
        % clear output variables (value and derivative)
        % unless precious
        for i = out
          if net.vars(i).precious, continue ; end
          net.vars(i).der = [] ;
          net.vars(i).value = [] ;
        end
      end

      % compute derivatives of inputs and paramerters
      [derInputs, derParams] = obj.backward ...
        (inputs, {net.params(par).value}, derOutputs) ;

      % accumuate derivatives
      for i = 1:numel(in)
        v = in(i) ;
        if net.numPendingVarRefs(v) == 0 || isempty(net.vars(v).der)
          net.vars(v).der = derInputs{i} ;
        elseif ~isempty(derInputs{i})
          net.vars(v).der = net.vars(v).der + derInputs{i} ;
        end
        net.numPendingVarRefs(v) = net.numPendingVarRefs(v) + 1 ;
      end
%       if isempty(derParams),
%           return;
%       end;
      for i = 1:numel(par)
        p = par(i) ;
        if (net.numPendingParamRefs(p) == 0 && ~net.accumulateParamDers) ...
              || isempty(net.params(p).der)
          net.params(p).der = derParams{i} ;
        else
          net.params(p).der = net.params(p).der + derParams{i} ;
        end
        net.numPendingParamRefs(p) = net.numPendingParamRefs(p) + 1 ;
      end

    end

    function rfs = getReceptiveFields(obj)
    %GETRECEPTIVEFIELDS  Get receptive fields.
    %   RFS = GETRECEPTIVEFIELDS(OBJ) gets the receptive fields
    %   of each output varaibles in each input variable.
    %
    %   A *receptive field* is a structure with fields
    %
    %   - size: size of the receptive field
    %   - stride: stride of the receptive field
    %   - offset: offset of the receptive field
    %
    %   It should be interpreted as follows. Given a pixel of
    %   vertical coordinate u in an output variable OUT(y,...) , the first and last
    %   pixels affecting that pixel in an input variable IN(v,...) are:
    %
    %        v_first = stride(1) * (y - 1) + offset(1) - size(1)/2 + 1
    %        v_last  = stride(1) * (y - 1) + offset(1) + size(1)/2 + 1
    %
    %   RFS is a struct array of such structure, with one row for each
    %   input variable and one column for each output variable, expressing
    %   all possible combinations of inputs and outputs.
      rfs = [] ;
    end

    function outputSizes = getOutputSizes(obj, inputSizes)
      outputSizes = {} ;
    end

    function load(obj, varargin)
    %LOAD Initialize the layer from a paramter structure
    %  LOAD(OBJ, S) initializes the layer object OBJ from the parameter
    %  structure S.  It is the opposite of S = SAVE(OBJ).
    %
    %  LOAD(OBJ, OPT1, VAL1, OPT2, VAL2, ...) uses instead the
    %  option-value pairs to initialize the object properties.
    %
    %  LOAD(OBJ, {OPT1, VAL1, OPT2, VAL2, ...}) is an equivalent form
    %  to the previous call.
      s = dagnn.Layer.argsToStruct(varargin{:}) ;
      for f = fieldnames(s)'
        f = char(f) ;
        obj.(f) = s.(f) ;
      end
    end

    function s = save(obj)
    %SAVE Save the layer configuration to a parameter structure
    %  S = SAVE(OBJ) extracts all the properties of the layer object OBJ
    %  as a structure S. It is the oppostie of LOAD(OBJ, S).
    %
    %  By default, properties that are marked as transient,
    %  dependent, abstract, or private in the layer object are not
    %  saved.
      s = struct ;
      m = metaclass(obj) ;
      for p = m.PropertyList'
        if p.Transient || p.Dependent || p.Abstract, continue ; end
        s.(p.Name) = obj.(p.Name) ;
      end
    end

    function attach(obj, net, index)
    %ATTACH  Attach the layer to a DAG.
    %   ATTACH(OBJ, NET, INDEX). Override this function to
    %   configure parameters or variables.
      obj.net = net ;
      obj.layerIndex = index ;
      for input = net.layers(index).inputs
        net.addVar(char(input)) ;
      end
      for output = net.layers(index).outputs
        net.addVar(char(output)) ;
      end
      for param = net.layers(index).params
        net.addParam(char(param)) ;
        p = net.getParamIndex(char(param)) ;
      end
    end

  end % methods

  methods (Static)
    function s = argsToStruct(varargin)
    %ARGSTOSTRUCT  Convert varadic arguments to structure
    %  S = ARGSTOSTRCUT('opt1', val1, ....) converts the list of options
    %  into a structure.
    %
    %  S = ARGSTOSTRUCT({'opt1', val1, ...}) is equivalent to the
    %  previous call.
    %
    %  S = ARGSTOSTRUCT(S) where S is a structure returns S as is.

      if numel(varargin) == 1 && isstruct(varargin{1})
        s = varargin{1} ;
      else
        if numel(varargin) == 1 && iscell(varargin{1})
          args = varargin{1} ;
        else
          args = varargin ;
        end
        s = cell2struct(args(2:2:end),args(1:2:end),2) ;
      end
    end
  end

end % classdef


function plot_cloud(M, points, style)
    if isempty(points)
        return
    end
    if nargin==2
        style = 'r*';
    end
    if isempty(M)
        if length(style)==3
            plot3(points(:,1),points(:,2),points(:,3),'*','Color',style)
        else
            plot3(points(:,1),points(:,2),points(:,3),style)
        end
    else
        if length(style)==3
            plot3(M.VERT(points,1),M.VERT(points,2),M.VERT(points,3),'*','Color',style)
        else
            plot3(M.VERT(points,1),M.VERT(points,2),M.VERT(points,3),style)
        end
    end
    axis equal
    rotate3d on
end


%% rayleighpdf
% Below is a demonstration of the features of the |rayleighpdf| function

%%
clear; close all; clc;

%% Syntax
% |P=rayleighpdf(M,S);|

%% Description
% UNDOCUMENTED
%% Examples
%
%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program 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 program.  If not, see <http://www.gnu.org/licenses/>.


function ht = fix_xticklabels(handle,margins,textopts)

%FIX_XTICKLABELS will determine maximum allowed width
%   of long XTickLabels and convert them into multiple line
%   format to fit maximum allowed width
%
%
%   IN:
%       handle      [optional] - axes handle (defaults to gca)
%       margins     [optional] - relative margins width (defaults to 0.1)
%       texopts     [optional] - cell array of addtitional text formating
%                                options (defaults to {} )
%
%   OUT:
%       ht - column vector of handles for created text objects
%
% This code was derrived from MY_XTICKLABELS by Pekka Kumpulainen
% http://www.mathworks.com/matlabcentral/fileexchange/19059-myxticklabels
%   EXAMPLE:
%       figure;
%
%       bar(rand(1,4));
%       set(gca,'XTickLabel',{'Really very very long text', ...
%                             'One more long long long text', ...
%                             'Short one','Long long long text again'});
%       fix_xticklabels();
%
%       figure;
%
%       bar(rand(1,4));
%       set(gca,'XTickLabel',{'Really very very long text', ...
%                             'One more long long long text', ...
%                             'Short one','Long long long text again'});
%       fix_xticklabels(gca,0.1,{'FontSize',16});
%

% Mikhail Erofeev 07.06.2013
% Pekka Kumpulainen 12.2.2008

if(~exist('handle','var'))
    handle = gca;
end

if(~exist('textopts','var'))
   textopts={};
end
if(~exist('margins','var'))
    margins = 0.1;
end

xtickpos = get(handle,'XTick');
xtickstring = get(handle,'XTickLabel');

set(handle, 'XTickLabel','')
h_olds = findobj(handle, 'Tag', 'MUXTL');
if ~isempty(h_olds)
    delete(h_olds)
end

%% Make XTickLabels
NTick = length(xtickpos);
Ybot = min(get(handle,'YLim'));

Xbot = get(handle,'XLim');
max_w = ((max(Xbot) - min(Xbot) )/NTick)*(1-margins);

ht = zeros(NTick,1);

NLabels = length(xtickstring);

for ii = 1:NTick
    str_id = mod( ii - 1 , NLabels) + 1;
    ht(ii) = text('String',xtickstring{str_id}, ...
        'Units','data', ...
        'VerticalAlignment', 'top', ...
        'HorizontalAlignment', 'center ', ...
        'Position',[xtickpos(ii) Ybot], ...
        'Tag','MUXTL');
end
if ~isempty(textopts)
    set(ht,textopts{:})
end

for ii = 1:NTick
    auto_width(ht(ii),max_w);
end

%% squeeze axis if needed

set(handle,'Units','pixels')
Axpos = get(handle,'Position');
% set(Hfig,'Units','pixels')
% Figpos = get(Hfig,'Position');

set(ht,'Units','pixels')
TickExt = zeros(NTick,4);
for ii = 1:NTick
    TickExt(ii,:) = get(ht(ii),'Extent');
end

needmove = -(Axpos(2) + min(TickExt(:,2)));

if needmove>0;
    Axpos(2) = Axpos(2)+needmove+2;
    Axpos(4) = Axpos(4)-needmove+2;
    set(handle,'Position',Axpos);
end

set(handle,'Units','normalized')
set(ht,'Units','normalized')
end

function []=auto_width(h,maxw)
    str = get(h,'string');
    set(h,'string',{});
    words = regexp(str,' ','split');

    tail = words(2:end);
    res = words(1);
    ln = 1;

    while(~isempty(tail))
        lin = res{ln};
        lin_e = [lin ' ' tail{1}];
        set(h,'string',lin_e);
        ext = get(h,'Extent');
        width=ext(3);
        if(width>maxw)
            ln =ln+1;
            res{ln} = tail{1};
        else
            res{ln} = lin_e;
        end
        tail = tail(2:end);
    end
    set(h,'string',res);
    ext = get(h,'Extent');
    width=ext(3);
    if(width>maxw)
        warning('FIX_XTICKLABELS:over','Overflown box');
    end
end


function sMap = som_read_cod(filename)

%SOM_READ_COD Reads a SOM_PAK format codebook file.
%
% sMap = som_read_cod(filename);
%
%  sMap = som_read_cod('map1.cod');
%
%  Input and output arguments:
%   filename    (string) name of input file
%   sMap        (struct) self-organizing map structure
%
% The file must be in SOM_PAK format. Empty lines and lines starting
% with a '#' are ignored, except the ones starting with '#n'. The strings
% after '#n' are read to field 'comp_names' of the map structure.
%
% For more help, try 'type som_read_cod' or check out online documentation.
% See also SOM_WRITE_COD, SOM_READ_DATA, SOM_WRITE_DATA, SOM_MAP_STRUCT.

%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% som_read_cod
%
% PURPOSE
%
% Reads a Self-Organizing Map from an ascii file in SOM_PAK format.
%
% SYNTAX
%
%  sMap = som_read_cod(filename);
%
% DESCRIPTION
%
% This function is offered for compatibility with SOM_PAK, a SOM
% software package in C. It reads map files written in SOM_PAK format.
%
% The SOM_PAK map file format is as follows. The first line must contain
% the input space dimension, lattice type ('rect' or 'hexa'), map grid
% size in x-direction, map grid size in y-direction, and neighborhood
% function ('bubble' or 'gaussian'), in that order. The following lines
% are comment lines, empty lines or data lines.
%
% Each data line contains the weight vector of one map unit and its
% labels. From the beginning of the line, first are values of the vector
% components separated by whitespaces, then labels, again separated by
% whitespaces. The order of map units in the file are one row at a time
% from right to left, from the top to the bottom of the map (x-direction
% first, then y-direction).
%
% Comment lines start with '#'. Comment lines as well as empty lines are
% ignored, except if the comment line starts with '#n'. In that case the
% line should contain names of the vector components separated by
% whitespaces.
%
% In the returned map struct, several fields has to be set to default
% values, since the SOM_PAK file does not contain information on
% them. These include map shape ('sheet'), mask ([1 ... 1]),
% normalizations (none), trainhist (two entries, first with algorithm
% 'init' and the second with 'seq', both with data name 'unknown'),
% possibly also component names ('Var1',...).
%
% REQUIRED INPUT PARAMETERS
%
%  filename   (string) the name of the input file
%
% OUTPUT ARGUMENTS
%
%  sMap       (struct) the resulting SOM struct
%
% EXAMPLES
%
%  sMap = som_read_cod('map1.cod');
%
% SEE ALSO
%
%  som_write_cod    Writes a map struct into a file in SOM_PAK format.
%  som_read_data    Reads data from an ascii file.
%  som_write_data   Writes data struct into a file in SOM_PAK format.
%  som_map_struct   Creates map structs.

% Copyright (c) 1997-2000 by the SOM toolbox programming team.
% http://www.cis.hut.fi/projects/somtoolbox/

% Version 1.0beta ecco 221097
% Version 2.0beta juuso 151199 250400

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% check arguments

error(nargchk(1, 1, nargin))  % check no. of input args is correct

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% initialize variables

lnum           = 0;    % codebook vector counter
comment_start  = '#';  % the char a SOM_PAK command line starts with
comp_name_line = '#n'; % string used to start a special command line,
                       % which contains names of each component

% open input file

fid = fopen(filename);
if fid < 0, error(['Cannot open ' filename]); end

% read header line

ok_cnt = 0;
lin = fgetl(fid); li = lin;
[dim c err n]  = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
[lattice c err n] = sscanf(li,'%s%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
[msize(2) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
[msize(1) c err n] = sscanf(li, '%d%[^ \t]'); ok_cnt=ok_cnt+c; li = li(n:end);
[neigh c err n] = sscanf(li, '%s%[^ \t\n]'); ok_cnt=ok_cnt+c;

if ok_cnt ~= 5
  error([ 'Invalid header line: ' lin ]);
end

% create map struct and set its fields according to header line

munits = prod(msize);
sMap   = som_map_struct(dim, 'msize', msize, ...
			lattice, 'sheet', 'neigh', neigh);
[sT0, ok] = som_set('som_train','algorithm','init','data_name','unknown');
sT1       = som_set('som_train','algorithm','seq','data_name','unknown',...
                    'neigh',neigh,'mask',ones(dim,1));
[sMap, ok, msgs] = som_set(sMap,'name',filename,'trainhist',{sT0,sT1});

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% read codebook from the file

codebook   = zeros(munits,dim);
labels     = cell(munits,1);
comp_names = sMap.comp_names;
form       = [repmat('%f',[1 dim-1]) '%f%[^ \t]'];

while 1,
  li = fgetl(fid);                         % read next line
  if ~ischar(li), break, end;               % is this the end of file?

  [data, c, err, n] = sscanf(li, form);
  if c < dim % if there were less numbers than dim on the input file line
    if c == 0
      if strncmp(li, comp_name_line, 2) % component name line?
        li = li(3:end); i = 0; c = 1;
        while c
          [s, c, e, n] = sscanf(li, '%s%[^ \t]');
          if ~isempty(s), i = i + 1; comp_names{i} = s; li = li(n:end); end
        end

        if i ~= dim
          error(['Illegal number of component names: ' num2str(i) ...
                 ' (dimension is ' num2str(dim) ')']);
        end
      elseif ~strncmp(li, comment_start, 1) % not a comment, is it error?
        [s, c, e, n] = sscanf(li, '%s%[^ \t]');
        if c
          error(['Invalid vector on input file line ' ...
                 num2str(lnum+1) ': [' deblank(li) ']']),
        end
      end
    else
      error(['Only ' num2str(c) ' vector components on input file line ' ...
             num2str(lnum+1) ' (dimension is ' num2str(dim) ')']);
    end

  else

    lnum = lnum + 1;                % this was a line containing data vector
    codebook(lnum, 1:dim) = data'; % add data to struct

    % read labels

    if n < length(li)
      li = li(n:end);
      i = 0; n = 1; c = 1;
      while c
        [s, c, e, n_new] = sscanf(li(n:end), '%s%[^ \t]');
        if c, i = i + 1; labels{lnum, i} = s; n = n + n_new - 1; end
      end
    end
  end
end

% close the input file

if fclose(fid) < 0
  error(['Cannot close file ' filename]);
else
  fprintf(2, '\rmap read ok         \n');
end

% check that the number of lines read was correct

if lnum ~= munits
  error(['Illegal number of map units: ' num2str(lnum) ' (should be ' num2str(munits) ').']);
end

% set values

% in SOM_PAK the xy-indexing is used, while in Matlab ij-indexing
% therefore, the codebook vectors have to be reorganized

order = reshape([1:munits],msize);
order = reshape(order',[munits 1]);
codebook(order,:) = codebook;
labels(order,:) = labels;

sMap.codebook   = codebook;
sMap.labels     = labels;
sMap.comp_names = comp_names;

return;

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


%--------------------------------------------------------------------------
%
%                    %%%%%  %%%%%  %   %    %    %   %
%                    %        %    %%  %
%                    %  %%%   %    % % %   %%%    % %
%                    %   %    %    %  %%
%                    %%%%%  %%%%%  %   %  %   %    %
%
%
%--------------------------------------------------------------------------
%                            GINav v0.1.0
%
% Copyright (C) 2020-2025, by Kai Chen, All rights reserved.
%--------------------------------------------------------------------------
% This script is used to plot and analyze results.It should be noted that
% all file formats must follow GINav's format requirements. For more
% details, please refer to the GINav user manual.
%--------------------------------------------------------------------------

clc
clear all %#ok
close all
addpath(genpath(pwd))
global_variable;

GINavPlot;

%--------------------------------------------------------------------------


function tapas_hgf_whichworld_plotTraj(r)
% Plots trajectories estimated by fitModel for the hgf_whichworld perceptual model
% Usage:  est = tapas_fitModel(responses, inputs); tapas_hgf_plotTraj(est);
%
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2012-2013 Christoph Mathys, TNU, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% Check whether we have a configuration structure
if ~isfield(r,'c_prc')
    error('tapas:hgf:ConfigRequired', 'Configuration required: before calling tapas_hgf_whichworld_plotTraj, tapas_hgf_whichworld_config has to be called.');
end

% Number of worlds
nw = r.c_prc.nw;

% Define colors
colors = [1 0 0; 0.67 0 1; 0 0.67 1; 0.67 1 0];

% Set up display
scrsz = get(0,'screenSize');
outerpos = [0.2*scrsz(3),0.2*scrsz(4),0.8*scrsz(3),0.8*scrsz(4)];
figure(...
    'OuterPosition', outerpos,...
    'Name','HGF trajectories');

% Number of trials
t = size(r.u,1);

% Optional plotting of standard deviations (true or false)
plotsd2 = true;
plotsd3 = true;

% Subplots
subplot(3,1,1);

if plotsd3 == true
    upper3prior = r.p_prc.mu3_0 +sqrt(r.p_prc.sa3_0);
    lower3prior = r.p_prc.mu3_0 -sqrt(r.p_prc.sa3_0);
    upper3 = [upper3prior; r.traj.mu(:,3)+sqrt(r.traj.sa(:,3))];
    lower3 = [lower3prior; r.traj.mu(:,3)-sqrt(r.traj.sa(:,3))];

    plot(0, upper3prior, 'ob', 'LineWidth', 1);
    hold all;
    plot(0, lower3prior, 'ob', 'LineWidth', 1);
    fill([0:t, fliplr(0:t)], [(upper3)', fliplr((lower3)')], ...
         'b', 'EdgeAlpha', 0, 'FaceAlpha', 0.15);
end
plot(0:t, [r.p_prc.mu3_0; r.traj.mu(:,3)], 'b', 'LineWidth', 2);
hold all;
plot(0, r.p_prc.mu3_0, 'ob', 'LineWidth', 2); % prior
xlim([0 t]);
title('Posterior expectation \mu_3 of log-volatility of tendency x_3', 'FontWeight', 'bold');
xlabel('Trial number');
ylabel('\mu_3');

subplot(3,1,2);
if plotsd2 == true
    for j=1:nw
    upper2prior = r.p_prc.mu2_0(j) +sqrt(r.p_prc.sa2_0(j));
    lower2prior = r.p_prc.mu2_0(j) -sqrt(r.p_prc.sa2_0(j));
    upper2 = [upper2prior; r.traj.mu(:,2,j)+sqrt(r.traj.sa(:,2,j))];
    lower2 = [lower2prior; r.traj.mu(:,2,j)-sqrt(r.traj.sa(:,2,j))];

    plot(0, upper2prior, 'o', 'Color', colors(j,:), 'LineWidth', 1);
    hold all;
    plot(0, lower2prior, 'o', 'Color', colors(j,:), 'LineWidth', 1);
    fill([0:t, fliplr(0:t)], [(upper2)', fliplr((lower2)')], ...
         colors(j,:), 'EdgeAlpha', 0, 'FaceAlpha', 0.15);
    end
end
for j=1:nw
    plot(0:t, [r.p_prc.mu2_0(j); r.traj.mu(:,2,j)], 'Color', colors(j,:), 'LineWidth', 2);
    hold all;
    plot(0, r.p_prc.mu2_0(j), 'o', 'Color', colors(j,:), 'LineWidth', 2); % prior
end
xlim([0 t]);
title('Posterior expectations \mu_2 of tendencies x_2', 'FontWeight', 'bold');
xlabel({'Trial number', ' '}); % A hack to get the relative subplot sizes right
ylabel('\mu_2');
hold off;

subplot(3,1,3);
for j=1:nw
    plot(0:t, [tapas_sgm(r.p_prc.mu2_0(j), 1); tapas_sgm(r.traj.mu(:,2,j), 1)], 'Color', colors(j,:), 'LineWidth', 2);
    hold all;
    plot(0, tapas_sgm(r.p_prc.mu2_0(j), 1), 'o', 'Color', colors(j,:), 'LineWidth', 2); % prior
end
plot(1:t, r.u(:,1), '.', 'Color', [0 0 0]); % inputs
if ~isempty(find(strcmp(fieldnames(r),'y'))) && ~isempty(r.y)
    y = r.y(:,1);
    if ~isempty(find(strcmp(fieldnames(r),'irr')))
        y(r.irr) = NaN; % weed out irregular responses
        plot(r.irr,  1.08.*ones([1 length(r.irr)]), 'x', 'Color', [1 0.7 0], 'Markersize', 11, 'LineWidth', 2); % irregular responses
    end
    if ~any(y>1) && ~any(y<0)
        plot(1:t, y, '.', 'Color', [1 0.7 0]); % responses
    else
        for j=1:nw
            plot(find(y==j), 1.08*ones([1 length(find(y==j))]), '.', 'Color', colors(j,:)); % responses
        end
    end
    title(['Response y, input u (black), and posterior probability of worlds s(\mu_2) for \kappa=', ...
           num2str(r.p_prc.ka), ', \omega=', num2str(r.p_prc.om), ', \vartheta=', num2str(r.p_prc.th)], ...
          'FontWeight', 'bold');
    ylabel('y, u, s(\mu_2)');
    axis([0 t -0.1 1.15]);
else
    title(['Input u (black) and posterior probability of worlds s(\mu_2) for m_3=', ...
           num2str(r.p_prc.m), ', \phi_3=', num2str(r.p_prc.phi), ', \kappa=', ...
           num2str(r.p_prc.ka), ', \omega=', num2str(r.p_prc.om), ', \vartheta=', num2str(r.p_prc.th)], ...
      'FontWeight', 'bold');
    ylabel('u, s(\mu_2)');
    axis([0 t -0.1 1.1]);
end
plot(1:t, 0.5, 'k');
xlabel('Trial number');
hold off;


%SerialLink.friction Friction force
%
% TAU = R.friction(QD) is the vector of joint friction forces/torques for the
% robot moving with joint velocities QD.
%
% The friction model includes:
% - Viscous friction which is a linear function of velocity.
% - Coulomb friction which is proportional to sign(QD).
%
% Notes::
% - The friction value should be added to the motor output torque, it has a
%   negative value when QD>0.
% - The returned friction value is referred to the output of the gearbox.
% - The friction parameters in the Link object are referred to the motor.
% - Motor viscous friction is scaled up by G^2.
% - Motor Coulomb friction is scaled up by G.
% - The appropriate Coulomb friction value to use in the non-symmetric case
%   depends on the sign of the joint velocity, not the motor velocity.
% - The absolute value of the gear ratio is used.  Negative gear ratios are
%   tricky: the Puma560 has negative gear ratio for joints 1 and 3.
%
% See also Link.friction.

% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB 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.
%
% RTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function  tau = friction(robot, qd)

	L = robot.links;

    tau = zeros(1,robot.n);
    if robot.issym
        tau = sym(tau);
    end

	for j=1:robot.n
		tau(j) = L(j).friction(qd(j));
	end


function enabled = isEnabled(package)
%  enabled = isEnabled(package)
%
% Takes
%
% 1. package - a string representing an SBML L3 package
%
% Returns
%
% 1. enabled
%   - 1, if the package can be used by this instance of libSBML
%   - 0, otherwise

%<!---------------------------------------------------------------------------
% This file is part of libSBML.  Please visit http://sbml.org for more
% information about SBML, and the latest version of libSBML.
%
% Copyright (C) 2013-2018 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%     3. University of Heidelberg, Heidelberg, Germany
%
% Copyright (C) 2009-2013 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
%
% Copyright (C) 2006-2008 by the California Institute of Technology,
%     Pasadena, CA, USA
%
% Copyright (C) 2002-2005 jointly by the following organizations:
%     1. California Institute of Technology, Pasadena, CA, USA
%     2. Japan Science and Technology Agency, Japan
%
% This library 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.  A copy of the license
% agreement is provided in the file named "LICENSE.txt" included with
% this software distribution and also available online as
% http://sbml.org/software/libsbml/license.html
%----------------------------------------------------------------------- -->

% assume not enabled
enabled = 0;

supported = {'fbc', 'qual', 'groups'};
if ~ischar(package)
    disp('argument must be a string representing an SBML L3 package');
elseif ~ismember(supported, package)
    return;
end;

if (isoctave() == '0')
  filename = fullfile(tempdir, 'pkg.xml');
else
  filename = fullfile(pwd, 'pkg.xml');
end;
writeTempFile(filename, package);

version_field = strcat(package, '_version');
try
  [m, e] = TranslateSBML(filename, 1, 0);

  if (isempty(e) && isfield(m, version_field) == 1 )
    enabled = 1;
  end;

  delete(filename);

catch err
  disp(err.identifier)
  delete(filename);

  return
end;

function writeTempFile(filename, package)

fout = fopen(filename, 'w');

fprintf(fout, '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n');
fprintf(fout, '<sbml xmlns=\"http://www.sbml.org/sbml/level3/version1/core\" ');
fprintf(fout, strcat('xmlns:', package, '=\"http://www.sbml.org/sbml/level3/version1/', package, '/version1\"\n'));
fprintf(fout, 'level=\"3\" version=\"1\"\n');
fprintf(fout, strcat(package, ':required=\"false\">\n'));
fprintf(fout, '  <model/>\n</sbml>\n');

fclose(fout);


function test_ode_test ( )

%*****************************************************************************80
%
%% TEST_ODE_TEST tests the TEST_ODE library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST_ODE_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the TEST_ODE library.\n' );

  test_ode_test01 ( );
  test_ode_test02 ( );
  test_ode_test03 ( );
  test_ode_test04 ( );
  test_ode_test05 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST_ODE_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function hout=SupTitle(str)
% =======================================================================
% SUPTITLE Puts a title above all subplots
% =======================================================================
%	SUPTITLE('text') adds text to the top of the figure
%	above all subplots (a "super title"). Use this function
%	after all subplot commands.
%
% Drea Thomas 6/15/95 drea@mathworks.com
% Rev. by Guillaume Maze on 2011-02-08: also modify figure title
%
% Warning: If the figure or axis units are non-default, this
% will break.
% =======================================================================

% Rev. by Guillaume Maze on 2011-02-08: To modify figure's name
% Is their already a suptitle:
if ~isempty(findall(gcf,'tag','suptitleText'))
	oldsuptitle = get(findall(gcf,'tag','suptitleText'),'string');
else
	oldsuptitle = '';
end

% Parameters used to position the supertitle.

% Amount of the figure window devoted to subplots
plotregion = .92;

% Y position of title in normalized coordinates
titleypos  = .96;

% Fontsize for supertitle
aux = get(gca,'Title'); aux.FontSize;
fs = aux.FontSize+4;

% Fudge factor to adjust y spacing between subplots
fudge=1;

haold = gca;
figunits = get(gcf,'units');

% Get the (approximate) difference between full height (plot + title
% + xlabel) and bounding rectangle.

	if (~strcmp(figunits,'pixels')),
		set(gcf,'units','pixels');
		pos = get(gcf,'position');
		set(gcf,'units',figunits);
    else
		pos = get(gcf,'position');
	end
	ff = (fs-4)*1.27*5/pos(4)*fudge;

        % The 5 here reflects about 3 characters of height below
        % an axis and 2 above. 1.27 is pixels per point.

% Determine the bounding rectange for all the plots

% h = findobj('Type','axes');

% findobj is a 4.2 thing.. if you don't have 4.2 comment out
% the next line and uncomment the following block.

h  = findobj(gcf,'Type','axes');  % Change suggested by Stacy J. Hills

h2 = findobj(gcf,'tag','footnote');
h  = setdiff(h,h2);

% If you don't have 4.2, use this code instead
%ch = get(gcf,'children');
%h=[];
%for i=1:length(ch),
%  if strcmp(get(ch(i),'type'),'axes'),
%    h=[h,ch(i)];
%  end
%end

max_y=0;
min_y=1;

oldtitle =0;
for i=1:length(h),
	if (~strcmp(get(h(i),'Tag'),'suptitle')),
		pos=get(h(i),'pos');
		if (pos(2) < min_y), min_y=pos(2)-ff/5*3;end;
		if (pos(4)+pos(2) > max_y), max_y=pos(4)+pos(2)+ff/5*2;end;
    else
		oldtitle = h(i);
	end
end

if max_y > plotregion,
	scale = (plotregion-min_y)/(max_y-min_y);
	for i=1:length(h),
		pos = get(h(i),'position');
		pos(2) = (pos(2)-min_y)*scale+min_y;
		pos(4) = pos(4)*scale-(1-scale)*ff/5*3;
		set(h(i),'position',pos);
	end
end

np = get(gcf,'nextplot');
set(gcf,'nextplot','add');
% if (oldtitle),
% 	delete(oldtitle);
% end
ha=axes('pos',[0 1 1 1],'visible','off','Tag','suptitle');
ht=text(.5,titleypos-1,str);set(ht,'horizontalalignment','center','fontsize',fs,'Tag','suptitleText','fontweight','bold','Interpreter','None');
set(gcf,'nextplot',np);
axes(haold);
if nargout,
	hout=ht;
end

% Rev. by Guillaume Maze on 2011-02-08: Also Modify figure title
%stophere
% check if figure's name is already from suptitle string ? :
if ~isempty(oldsuptitle) && strcmp(oldsuptitle,get(gcf,'name'))
	overw = true; % Yes, so we over-write
elseif isempty(get(gcf,'name'))
	overw = true;
else
	overw = false; % No, this is probably a custom name, so we don't change it
end
if overw
	figname = str;
	set(gcf,'name',figname);
end
end%if simple case, parent is a figure handle


function test_ft_topoplotER

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_topoplotER ft_topoplotTFR ft_topoplotIC

% this script tests the functionality of ft_topoplotER with respect to the
% different input datatypes. no other functionality is tested.
% the script has been written in order to test a clean up of the code

filename = dccnpath('/home/common/matlab/fieldtrip/data/test/latest/raw/eeg/preproc_neuroscan16');
load(filename)

%there's an unresolved issue with duplicate labels 'FREE'
%FIXME
data.label{1} = 'FREE1';
data.label{2} = 'FREE2';
data.label{3} = 'FREE3';
data.label{4} = 'FREE4';

cfg = [];
cfg.preproc.demean = 'yes';
tlck = ft_timelockanalysis(cfg, data);

cfg = [];
cfg.layout = 'biosemi64.lay';
lay = ft_prepare_layout(cfg);

cfg        = [];
cfg.layout = lay;
cfg.interactive = 'yes';

%plot timelocked-data
figure; ft_topoplotER(cfg, tlck);drawnow

%reproduce bug 1239
cfgtmp = cfg;
cfgtmp.highlight = 'on';
cfgtmp.highlightchannel = {};
figure; ft_topoplotER(cfgtmp, tlck);drawnow

%plot subplots
cfg.xlim = (-1:0.25:1);
figure; ft_topoplotER(cfg, tlck);drawnow
cfg = rmfield(cfg, 'xlim');

%create component-data
cfgc = [];
cfgc.method = 'pca';
comp = ft_componentanalysis(cfgc, data);

%plot component-data
cfg.interactive = 'no';
cfg.component   = 1:10;
figure; ft_topoplotIC(cfg, comp);drawnow

cfg.component   = 5;
figure; ft_topoplotIC(cfg, comp);drawnow

%create frequency-data
cfgf = [];
cfgf.method = 'mtmfft';
cfgf.foilim = [0 100];
cfgf.taper  = 'hanning';
cfgf.output = 'pow';
freq = ft_freqanalysis(cfgf, data);

%plot frequency-data
cfg.interactive = 'yes';
%cfg = rmfield(cfg, 'component');
figure; ft_topoplotER(cfg, freq);drawnow

%create connectivity-data
cfgf.output = 'fourier';
freq2 = ft_freqanalysis(cfgf, data);

cfgc2 = [];
cfgc2.method = 'coh';
cfgc2.channel = freq2.label(5:end);
coh   = ft_connectivityanalysis(cfgc2, freq2);

%plot connectivity-data
cfg.refchannel = 'gui';
cfg.parameter = 'cohspctrm';
figure; ft_topoplotER(cfg, coh);drawnow % FIXME this causes a crash when a new reference is selected and the old one is not unselected
% FIXME it also crashes when more than one ref is selected

%create connectivity-data with sparse linear indexing
cfgc2.channelcmb = [repmat(freq2.label(5),[numel(freq2.label)-1 1]) freq2.label([1:4 6:end])];
coh2  = ft_connectivityanalysis(cfgc2, freq2);

%plot
cfg = [];
cfg.layout = 'biosemi64.lay';
cfg.parameter = 'cohspctrm';
% cfg.refchannel = 'gui';
cfg.refchannel = freq2.label{5};

coh2 = ft_checkdata(coh2, 'cmbstyle', 'full');
figure; ft_topoplotER(cfg, coh2);drawnow

coh2 = ft_checkdata(coh2, 'cmbstyle', 'sparse');
figure; ft_topoplotER(cfg, coh2);drawnow

%create connectivity-data with very sparse linear indexing
cfgc2.channelcmb = cfgc2.channelcmb(1:25,:);
coh3   = ft_connectivityanalysis(cfgc2, freq2);

%plot
figure; ft_topoplotER(cfg, coh3);drawnow

%create connectivity-data with even sparser linear indexing
cfgc2.channelcmb = [repmat(freq2.label(5),[10 1]) freq2.label(21:30);repmat(freq2.label(10),[10 1]) freq2.label(21:30)];
coh4 = ft_connectivityanalysis(cfgc2, freq2);

%plot
cfg.refchannel = freq2.label{5};

coh2 = ft_checkdata(coh2, 'cmbstyle', 'full');
figure; ft_topoplotER(cfg, coh4);drawnow

%plot: this works
coh2 = ft_checkdata(coh2, 'cmbstyle', 'sparse');
figure; ft_topoplotER(cfg, coh4);drawnow

%create connectivity-data with asymmetry
%the data are probably not full-rank creating a problem for the sf
%freq3 = ft_selectdata(freq2, 'channel', freq2.label(1:30));
%%subselection of channels does not help

cfgc2 = [];
cfgc2.method = 'granger';
granger = ft_connectivityanalysis(cfgc2, freq2);

cfg.refchannel = 'gui';
cfg.parameter = 'grangerspctrm';
figure; ft_topoplotER(cfg, granger);drawnow

%plot a stat structure, containing only 1 freq bin (so without freq-field)
stat = freq;
stat.stat = freq.powspctrm(:,10);
stat = rmfield(stat, 'freq');
if isfield(stat, 'cumtapcnt')
  stat = rmfield(stat, 'cumtapcnt');
end
stat = rmfield(stat, 'powspctrm');
stat.dimord = 'chan';

cfg = rmfield(cfg, 'refchannel');
cfg.parameter = 'stat';
cfg.interactive = 'no';
figure; ft_topoplotER(cfg, stat);drawnow


function result = nsga2(opt, varargin)
% Function: result = nsga2(opt, varargin)
% Description: The main flowchart of of NSGA-II. Note:
%   All objectives must be minimization. If a objective is maximization, the
%   objective should be multipled by -1.
%
% Syntax:
%   result = nsga2(opt): 'opt' is generated by function nsgaopt().
%   result = nsga2(opt, param): 'param' can be any data type, it will be
%       pass to the objective function objfun().
%
%   Then ,the result structure can be pass to plotnsga to display the
%   population:  plotnsga(result);
%
% Parameters:
%   opt : A structure generated by funciton nsgaopt().
%   varargin : Additional parameter will be pass to the objective functions.
%       It can be any data type. For example, if you call: nsga2(opt, param),
%       then objfun would be called as objfun(x,param), in which, x is the
%       design variables vector.
% Return:
%   result : A structure contains optimization result.
%
%         LSSSSWC, NWPU
%   Revision: 1.2  Data: 2011-07-26
%*************************************************************************

tStart = tic();
%*************************************************************************
% Verify the optimization model
%*************************************************************************
opt = verifyOpt(opt);

%*************************************************************************
% variables initialization
%*************************************************************************
nVar    = opt.numVar;
nObj    = opt.numObj;
nCons   = opt.numCons;
popsize = opt.popsize;

% pop : current population
% newpop : new population created by genetic algorithm operators
% combinepop = pop + newpop;
pop = repmat( struct(...
    'var', zeros(1,nVar), ...
    'obj', zeros(1,nObj), ...
    'cons', zeros(1,nCons),...
    'rank', 0,...
    'distance', 0,...
    'prefDistance', 0,...       % preference distance used in R-NSGA-II
    'nViol', 0,...
    'violSum', 0),...
    [1,popsize]);

% state: optimization state of one generation
state = struct(...
'currentGen', 1,...         % current generation number
'evaluateCount', 0,...      % number of objective function evaluation
'totalTime', 0,...          % total time from the beginning
'firstFrontCount', 0,...    % individual number of first front
'frontCount', 0,...         % number of front
'avgEvalTime', 0 ...        % average evaluation time of objective function (current generation)
);

result.pops     = repmat(pop, [opt.maxGen, 1]);     % each row is the population of one generation
result.states   = repmat(state, [opt.maxGen, 1]);   % each row is the optimizaiton state of one generation
result.opt      = opt;                              % use for output

% global variables
global STOP_NSGA;   %STOP_NSGA : used in GUI , if STOP_NSGA~=0, then stop the optimizaiton
STOP_NSGA = 0;

%*************************************************************************
% initialize the P0 population
%*************************************************************************
ngen = 1;
pop = opt.initfun{1}(opt, pop, opt.initfun{2:end});
[pop, state] = evaluate(opt, pop, state, varargin{:});
[opt, pop] = ndsort(opt, pop);

% state
state.currentGen = ngen;
state.totalTime = toc(tStart);
state = statpop(pop, state);

result.pops(1, :) = pop;
result.states(1)  = state;

% output
% plotnsga(result, ngen);
opt = callOutputfuns(opt, state, pop);

%*************************************************************************
% NSGA2 iteration
%*************************************************************************
while( ngen < opt.maxGen && STOP_NSGA==0)
    % 0. Display some information
	ngen = ngen+1;
    state.currentGen = ngen;
%     fprintf('\n\n************************************************************\n');
%     fprintf('*      Current generation %d / %d\n', ngen, opt.maxGen);
%     fprintf('************************************************************\n');

    % 1. Create new population
    newpop = selectOp(opt, pop);
    newpop = crossoverOp(opt, newpop, state);
    newpop = mutationOp(opt, newpop, state);
    [newpop, state] = evaluate(opt, newpop, state, varargin{:});

    % 2. Combine the new population and old population : combinepop = pop + newpop
    combinepop = [pop, newpop];

    % 3. Fast non dominated sort
    [opt, combinepop] = ndsort(opt, combinepop);

    % 4. Extract the next population
    pop = extractPop(opt, combinepop);

    % 5. Save current generation results
    state.totalTime = toc(tStart);
    state = statpop(pop, state);

    result.pops(ngen, :) = pop;
    result.states(ngen)  = state;

    % 6. plot current population and output
%     if( mod(ngen, opt.plotInterval)==0 )
%         plotnsga(result, ngen);
%     end
%     if( mod(ngen, opt.outputInterval)==0 )
%         opt = callOutputfuns(opt, state, pop);
%     end

end

% call output function for closing file
opt = callOutputfuns(opt, state, pop, -1);

% close worker processes
if( strcmpi(opt.useParallel, 'yes'))
    matlabpool close
end

toc(tStart);


classdef GeometricAngleEnum < matlab.mixin.SetGet
    %GeometricAngleEnum Summary of this class goes here
    %   Detailed explanation goes here

    enumeration
        AngleBetweenVectors('Angle Between Vectors');
        AngleBetweenVectorPlane('Angle Between Vector and Plane');
    end

    properties
        name(1,:) char
    end

    methods
        function obj = GeometricAngleEnum(name)
            obj.name = name;
        end
    end

    methods(Static)
        function listBoxStr = getListBoxStr()
            m = enumeration('GeometricAngleEnum');
            [~,I] = sort({m.name});
            listBoxStr = {m(I).name};
        end

        function [ind, enum] = getIndForName(name)
            m = enumeration('GeometricAngleEnum');
            [~,I] = sort({m.name});
            m = m(I);
            ind = find(ismember({m.name},name),1,'first');
            enum = m(ind);
        end

        function [enum, ind] = getEnumForListboxStr(nameStr)
            m = enumeration('GeometricAngleEnum');
            ind = find(ismember({m.name},nameStr),1,'first');
            enum = m(ind);
        end
    end
end


function test_suite=test_cross_neighborhood()
% tests for cosmo_cross_neighborhood
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_cross_neighborhood_time_freq()
    helper_test_cross_neighborhood(false);

function test_cross_neighborhood_chan_time_freq()
    if cosmo_skip_test_if_no_external('fieldtrip')
        return;
    end
    helper_test_cross_neighborhood(true);

function helper_test_cross_neighborhood(can_use_chan_nbrhood)
    ds_full=cosmo_synthetic_dataset('type','timefreq','size','big');
    msk=cosmo_match(ds_full.fa.chan,@(x)x<20);
    ds_full=cosmo_slice(ds_full,msk,2);
    ds_full=cosmo_dim_prune(ds_full);

    % make it sparse
    nfeatures=size(ds_full.samples,2);
    nkeep=round(nfeatures/4);
    fdim_values=ds_full.a.fdim.values;
    nchan=numel(fdim_values{1});
    nfreq=numel(fdim_values{2});
    ntime=numel(fdim_values{3});

    while true
        rp=randperm(nfeatures);
        ds=cosmo_slice(ds_full,rp(1:nkeep),2);
        ds=cosmo_dim_prune(ds);
        n=numel(ds.a.fdim.values{1});
        ds.a.fdim.values{1}=ds.a.fdim.values{1}(randperm(n));

        if numel(unique(ds.fa.chan))==nchan && ...
                    numel(unique(ds.fa.freq))==nfreq && ...
                    numel(unique(ds.fa.time))==ntime
            break
        end
    end

    nfeatures=size(ds.samples,2);

    % define neighborhoods
    freq_nbrhood=cosmo_interval_neighborhood(ds,'freq','radius',2);
    time_nbrhood=cosmo_interval_neighborhood(ds,'time','radius',1);
    if can_use_chan_nbrhood
        chan_nbrhood=cosmo_meeg_chan_neighborhood(ds,'count',5,...
                                'chantype','all','label','dataset');
    else
        chan_nbrhood='dummy';
    end

    all_nbrhoods={chan_nbrhood, freq_nbrhood, time_nbrhood};
    ndim=numel(all_nbrhoods);
    dim_labels={'chan';'freq';'time'};

    ntest=5;  % number of positions to test

    for i=7:-1:1
        use_chan=i<=4;
        use_freq=mod(i,2)==1;
        use_time=mod(ceil(i/2),2)==1;

        if ~can_use_chan_nbrhood && use_chan
            % no support for channel neighborhood, skip
            continue;
        end

        use_dim_msk=[use_chan;use_freq;use_time];
        nbrhood=cosmo_cross_neighborhood(ds,all_nbrhoods(use_dim_msk),...
                                                'progress',false);
        assertEqual(nbrhood.a.fdim.labels,dim_labels(use_dim_msk));
        assertEqual(fieldnames(nbrhood.fa),dim_labels(use_dim_msk));

        n=numel(nbrhood.neighbors);
        rp=randperm(n);

        for iter=1:min(n,ntest)
            pos=rp(iter);
            % verify neighborhoods in ds

            ds_fa=cosmo_slice(ds.fa,nbrhood.neighbors{pos},2,'struct');
            nbr_fa=cosmo_slice(nbrhood.fa,pos,2,'struct');

            nbr_msk=true(1,nfeatures);

            for dim=1:ndim
                dim_label=dim_labels{dim};
                if use_dim_msk(dim)
                    dim_nbrhood=all_nbrhoods{dim};

                    j=find(dim_nbrhood.fa.(dim_label)==nbr_fa.(dim_label));
                    assert(numel(j)==1);

                    m=false(1,nfeatures);
                    m(dim_nbrhood.neighbors{j})=true;
                else
                    assert(~isfield(nbrhood.fa,dim_label))
                    m=true(1,nfeatures);
                end

                nbr_msk=nbr_msk & m;

                fa=cosmo_slice(ds.fa.(dim_label),m,2);
                assert(isempty(setdiff(ds_fa.(dim_label),fa)));
            end

            assertEqual(nbrhood.neighbors{pos},find(nbr_msk));

            % test agreement between the crossed nbrhood and the
            % individual neighborhoods
            dim_nbr_msk=true(1,nfeatures);
            dim_pos=0;
            for dim=1:ndim
                if ~use_dim_msk(dim)
                    continue;
                end
                dim_pos=dim_pos+1;
                dim_label=dim_labels{dim};
                nbr_fa=nbrhood.fa.(dim_label);
                nbr_values=nbrhood.a.fdim.values{dim_pos}(nbr_fa(pos));

                dim_nbrhood=all_nbrhoods{dim};
                dim_nbr_values=dim_nbrhood.a.fdim.values{1};
                nbr_msk=cosmo_match(dim_nbr_values,nbr_values);

                m=false(size(dim_nbr_msk));
                m(dim_nbrhood.neighbors{nbr_msk})=true;
                dim_nbr_msk=dim_nbr_msk & m;
            end
            assertEqual(nbrhood.neighbors{pos},find(dim_nbr_msk));
        end
    end

function test_cross_neighborhood_transpose
    opt=struct();
    opt.progress=false;
    ds=cosmo_synthetic_dataset('type','timefreq','size','normal');
    ds=cosmo_dim_remove(ds,'chan');

    nh_time=cosmo_interval_neighborhood(ds,'time','radius',1);
    nh_freq=cosmo_interval_neighborhood(ds,'freq','radius',0);

    nh=cosmo_cross_neighborhood(ds,{nh_freq,nh_time},opt);

    cp=cosmo_cartprod(repmat({[false,true]},4,1));
    n=size(cp,1);

    for k=1:n
        t_label=cp{k,1};
        t_value=cp{k,2};
        t_elem1=cp{k,3};
        t_elem2=cp{k,4};

        ds2=ds;

        if t_label
            ds2.a.fdim.labels=ds2.a.fdim.labels';
        end

        if t_value
            ds2.a.fdim.values=ds2.a.fdim.values';
        end

        if t_elem1
            ds2.a.fdim.values{1}=ds2.a.fdim.values{1}';
        end

        if t_elem2
            ds2.a.fdim.values{2}=ds2.a.fdim.values{2}';
        end

        nh2_time=cosmo_interval_neighborhood(ds2,'time','radius',1);
        nh2_freq=cosmo_interval_neighborhood(ds2,'freq','radius',0);

        nh2=cosmo_cross_neighborhood(ds2,{nh2_freq,nh2_time},opt);
        assertEqual(nh2.a,nh.a);
        assertEqual(nh2.fa,nh.fa);
        assertEqual(nh2.neighbors,nh.neighbors);
    end

function test_cross_neighborhood_exceptions()
    ds=cosmo_synthetic_dataset('type','meeg','size','big');
    time_nbrhood=cosmo_interval_neighborhood(ds,'time','radius',1);

    % test exceptions
    aet=@(varargin)assertExceptionThrown(@()...
                        cosmo_cross_neighborhood(varargin{:}),'');

    aet(ds,{});
    aet(ds,struct);
    aet(ds,struct,time_nbrhood);
    aet(ds,time_nbrhood,time_nbrhood);
    aet(ds,ds);

    % should be fine
    assertEqual(cosmo_cross_neighborhood(ds,{time_nbrhood}),time_nbrhood);

    % no values too big
    time_nbrhood2=time_nbrhood;
    time_nbrhood2.neighbors{1}=1e9;
    aet(ds,{time_nbrhood2});

    % non-integers not supported
    time_nbrhood2=time_nbrhood;
    time_nbrhood2.neighbors{1}=1.5;
    aet(ds,{time_nbrhood2});

    % illegal labels
    time_nbrhood2=time_nbrhood;
    time_nbrhood2.a.fdim.labels{1}='foo';
    time_nbrhood2.fa.foo=time_nbrhood.fa.time;
    aet(ds,{time_nbrhood2});

    % duplicate labels
    aet(ds,{time_nbrhood,time_nbrhood});

function test_cross_neighborhood_unsorted_neighbors
    ds=cosmo_synthetic_dataset();
    nh=cosmo_interval_neighborhood(ds,'i','radius',1);

    nh_unsorted=nh;
    nh_unsorted.neighbors=cellfun(@(x)x(randperm(numel(x))),...
                                nh_unsorted.neighbors,...
                                'UniformOutput',false);
    assertEqual(nh,cosmo_cross_neighborhood(ds,{nh_unsorted}));

function test_cross_neighborhood_progress()
    if cosmo_skip_test_if_no_external('!evalc')
        return;
    end

    ds=cosmo_synthetic_dataset();
    nh1=cosmo_interval_neighborhood(ds,'i','radius',0);
    nh2=cosmo_interval_neighborhood(ds,'j','radius',0);
    f=@()cosmo_cross_neighborhood(ds,{nh1,nh2});
    res=evalc('f();');
    assert(~isempty(strfind(res,'[####################]')));
    assert(~isempty(strfind(res,'crossing neighborhoods')));

function test_warning_weird_dimension_order
    if cosmo_skip_test_if_no_external('fieldtrip')
        return;
    end

    ds=cosmo_synthetic_dataset('type','timefreq','size','big');
    keep=ds.fa.chan<20;
    ds=cosmo_slice(ds,keep,2);
    ds=cosmo_dim_prune(ds);

    nh_time=cosmo_interval_neighborhood(ds,'time','radius',0);
    nh_freq=cosmo_interval_neighborhood(ds,'freq','radius',0);
    nh_chan=cosmo_meeg_chan_neighborhood(ds,'count',4,...
                                    'chantype','meg_planar',...
                                    'label','dataset');

    nh_cell={nh_chan,nh_freq,nh_time};
    for ndim=1:3
        idxs=nchoosek(1:3,ndim);
        order=perms(1:ndim);

        for k=1:size(idxs,1)
            for j=1:size(order,1)

                idx=idxs(k,order(j,:));
                nh_sel=nh_cell(idx);

                is_weird_order=~issorted(idx);

                func=@()cosmo_cross_neighborhood(ds,nh_sel,...
                                    'progress',false);
                assert_warning_being_shown(func,is_weird_order);
            end
        end
    end

function assert_warning_being_shown(func, flag)
    warning_state=cosmo_warning();
    cleaner=onCleanup(@()cosmo_warning(warning_state));

    cosmo_warning('reset');
    cosmo_warning('off');

    % initially must be empty
    s=cosmo_warning();
    assertEqual(s.shown_warnings,{});

    func();

    s=cosmo_warning();
    if flag
        % must have warning added
        assertTrue(iscellstr(s.shown_warnings));
        assertTrue(numel(s.shown_warnings)>0);
    else
        % still without warning
        assertEqual(s.shown_warnings,{});
    end


function y = perms(x)
% Linearizes non-vector input, so that it gives the same result as in Matlab; except for order,
% which is different even for vector input
if ~isvector(x)
    x = reshape(x, 1, []);
end
y = builtin('perms', x);
end


function rect = convert_rect( reccell )
    rect = zeros(0, 4, 'int16');
    for i = 1 : length(reccell)
        rect(i, :) = round([reccell{i}.x, reccell{i}.y, reccell{i}.w, reccell{i}.h]);
    end

end