function [a b c] = parseThreePoints(varargin)
%PARSETHREEPOINTS Parse three points from variable length input array
%
%   [A B C] = parseThreePoints(PTS);
%   [A B C] = parseThreePoints(P1, P2, P3);
%   [A B C] = parseThreePoints(VERTICES, INDS);
%
%   Example
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-12-09,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

% extract input args
if nargin == 1
    % inputs are 3 points packed into a 3-by-2 array
    var = varargin{1};
    a = var(1,:);
    b = var(2,:);
    c = var(3,:);

elseif nargin == 3
    % inputs are 3 separate points
    a = varargin{1};
    b = varargin{2};
    c = varargin{3};

elseif nargin == 2
    % inputs are a vertex array, and index array
    pts = varargin{1};
    inds = varargin{2};
    a = pts(inds(1), :);
    b = pts(inds(2), :);
    c = pts(inds(3), :);
end


function[]=ylin
% YLIN   Sets y-axis scale to linear.
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2004--2015 J.M. Lilly --- type 'help jlab_license' for details

set(gca,'yscale','linear')

%Update for compatibility with ZOOL
if isappdata(gcf,'ylimitslock')
   if getappdata(gcf,'ylimitslock')
      h=gca;
      hall=axeshandles;
      for i=1:length(hall)
         axes(hall(i))
         set(gca,'yscale','linear')
      end
      axes(h)
   end
end


function c8mat_print_some ( m, n, a, ilo, jlo, ihi, jhi, title )

%*****************************************************************************80
%
%% C8MAT_PRINT_SOME prints some of a C8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns in the matrix.
%
%    Input, complex A(M,N), the matrix.
%
%    Input, integer ILO, JLO, IHI, JHI, the first row and
%    column, and the last row and column to be printed.
%
%    Input, string TITLE, a title.
%
  incx = 4;

  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );
%
%  Print the columns of the matrix, in strips of INCX.
%
  for j2lo = jlo : incx : jhi

    j2hi = j2lo + incx - 1;
    j2hi = min ( j2hi, n );
    j2hi = min ( j2hi, jhi );

    inc = j2hi + 1 - j2lo;

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Col: ' );
    for j = j2lo : j2hi
      j2 = j + 1 - j2lo;
      fprintf ( 1, '%10d          ', j );
    end
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Row\n' );
    fprintf ( 1, '  ---\n' );
%
%  Determine the range of the rows in this strip.
%
    i2lo = max ( ilo, 1 );
    i2hi = min ( ihi, m );

    for i = i2lo : i2hi
%
%  Print out (up to) INCX entries in row I, that lie in the current strip.
%
      for j2 = 1 : inc

        j = j2lo - 1 + j2;

        if ( a(i,j) == 0.0 )
          fprintf ( 1, '       0.0          ' );
        elseif ( imag ( a(i,j) ) == 0.0 )
          fprintf ( 1, ' %9f          ', real ( a(i,j) ) );
        else
          fprintf ( 1, ' %9f %9f', real ( a(i,j) ), imag ( a(i,j) ) );
       end

      end

      fprintf ( 1, '\n' );

    end

  end

  fprintf ( 1, '\n' );

  return
end


function name = saveName(n, l)
name = num2str(n);
for i=1:l-length(name)
    name = ['0' name];
end;

end


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

%%
clear; close all; clc;

%% Syntax
% |[T]=abaqusStruct2inp(abaqus_spec,fileName,optionStruct);|

%% Description
% This function provides the basis for coding Abaqus .inp input files

%%
% See also: |abaqusStructTemplate|

%% About Abaqus INP input files
% Abaqus input files (.inp) are plain text files.

%% Coding INP files in MATLAB

%%
% Specify file heading
% Users may provide a heading which can be used to give a description of
% the input file.

% *Heading
% ** Job name: ABAQUS inp file creation demo
% ** Generated by: GIBBON

abaqus_spec.Heading.COMMENT{1}='Job name: ABAQUS inp file creation demo';
abaqus_spec.Heading.COMMENT{2}='Generated by: GIBBON';

%%
% The preprint section
%

% *Preprint, echo=NO, model=NO, history=NO, contact=NO
abaqus_spec.Preprint.ATTR.echo='NO';
abaqus_spec.Preprint.ATTR.model='NO';
abaqus_spec.Preprint.ATTR.history='NO';
abaqus_spec.Preprint.ATTR.contact='NO';

%%
% The part section

V=[ 1 1 1; 1 0 1;  1 1 0; 1 0 0; 0 1 1; 0 0 1; 0 1 0; 0 0 0];

nodeIds=(1:1:size(V,1));
E=[5 6 8 7 1 2 4 3];
elementIds=(1:1:size(E,1));

% Node
abaqus_spec.Part{1}.COMMENT='This section defines the part geometry in terms of nodes and elements';
abaqus_spec.Part{1}.ATTR.name='Cube';
abaqus_spec.Part{1}.Node={nodeIds(:),V};

% Element
abaqus_spec.Part{1}.Element{1}.ATTR.type='C3D8R';
abaqus_spec.Part{1}.Element{1}.VAL={elementIds(:),E};

%Element sets
abaqus_spec.Part{1}.Elset{1}.ATTR.elset='Set-1';
abaqus_spec.Part{1}.Elset{1}.VAL=1;

%Node sets
abaqus_spec.Part{1}.Nset{2}.ATTR.nset='Set-2';
abaqus_spec.Part{1}.Nset{2}.VAL=1:1:size(V,1);

%Node sets using "generate"
abaqus_spec.Part{1}.Nset{1}.ATTR.nset='Set-1';
abaqus_spec.Part{1}.Nset{1}.ATTR.generate='';
abaqus_spec.Part{1}.Nset{1}.VAL=[1 size(V,1) 1];

%Sections
abaqus_spec.Part{1}.Solid_section.ATTR.elset='Set-1';
abaqus_spec.Part{1}.Solid_section.ATTR.material='Elastic';

% abaqus_spec.Part{1}.Shell_section.ATTR.elset='Set-1';
% abaqus_spec.Part{1}.Shell_section.ATTR.material='Material-1';
% % abaqus_spec.Part{1}.Shell_section.VAL=[10 5]; %Use numerical data
% abaqus_spec.Part{1}.Shell_section.VAL='10., 5'; %Use custom text data

%%
% The assembly section

abaqus_spec.Assembly.ATTR.name='Assembly-1';

abaqus_spec.Assembly.Instance{1}.ATTR.name='Cube-1';
abaqus_spec.Assembly.Instance{1}.ATTR.part='Cube';

% abaqus_spec.Assembly.Instance{2}.ATTR.name='Clot-1';
% abaqus_spec.Assembly.Instance{2}.ATTR.part='Clot';

abaqus_spec.Assembly.Nset{1}.ATTR.nset='Set-1';
abaqus_spec.Assembly.Nset{1}.ATTR.instance='Cube-1';
abaqus_spec.Assembly.Nset{1}.ATTR.generate='';
abaqus_spec.Assembly.Nset{1}.VAL=[1 4 1];

abaqus_spec.Assembly.Nset{2}.ATTR.nset='Set-3';
abaqus_spec.Assembly.Nset{2}.ATTR.instance='Cube-1';
abaqus_spec.Assembly.Nset{2}.ATTR.generate='';
abaqus_spec.Assembly.Nset{2}.VAL=[5 7 1];

abaqus_spec.Assembly.Nset{3}.ATTR.nset='Set-4';
abaqus_spec.Assembly.Nset{3}.ATTR.instance='Cube-1';
abaqus_spec.Assembly.Nset{3}.ATTR.generate='';
abaqus_spec.Assembly.Nset{3}.VAL=[2 6 2];

abaqus_spec.Assembly.Nset{4}.ATTR.nset='Set-5';
abaqus_spec.Assembly.Nset{4}.ATTR.instance='Cube-1';
abaqus_spec.Assembly.Nset{4}.VAL=[3 4 7];

abaqus_spec.Assembly.Nset{5}.ATTR.nset='origin';
abaqus_spec.Assembly.Nset{5}.ATTR.instance='Cube-1';
abaqus_spec.Assembly.Nset{5}.VAL=8;

abaqus_spec.Assembly.Nset{6}.ATTR.nset='all';
abaqus_spec.Assembly.Nset{6}.ATTR.instance='Cube-1';
% abaqus_spec.Assembly.Nset{6}.ATTR.generate='';
abaqus_spec.Assembly.Nset{6}.VAL=1:size(V,1);

abaqus_spec.Assembly.Surface{1}.ATTR.type='ELEMENT';
abaqus_spec.Assembly.Surface{1}.ATTR.name='innerSurface';
elemSetsInner={[1 2 3 4],[4 5 6 7]};
elemSetSideInner=[1 2];
valCell=cell(numel(elemSetsInner),1);
for qs=1:1:numel(elemSetsInner)
    surfaceElementSetName=['elementSetInnerSurface',num2str(qs)];
    abaqus_spec.Assembly.Elset{qs}.ATTR.elset=surfaceElementSetName;
    abaqus_spec.Assembly.Elset{qs}.ATTR.internal=''; %Remains hidden uppon import
    abaqus_spec.Assembly.Elset{qs}.ATTR.instance='Cube-1';
    abaqus_spec.Assembly.Elset{qs}.VAL=elemSetsInner{qs};

    sidePick=elemSetSideInner(qs);
    valCell{qs}={[surfaceElementSetName,', S',num2str(sidePick)]};
end
abaqus_spec.Assembly.Surface{1}.VAL=valCell;

%%
% Equation constraint

% *Equation
% 2
% X(n-1), 1, 1.
% XControlN, 1, -1.

%%--> Constraints
abaqus_spec.Assembly.COMMENT='Constraint 1';
abaqus_spec.Assembly.Equation.VAL=['2' newline 'X(n-1), ',  '1, 1.' newline 'XContN, ' '1, -1.'];

%%
% The material section

% *Material, name=Material-1
% *Hyperelastic, neo hooke
%  0.03,1.

abaqus_spec.Material.ATTR.name='Neo-Hooke';
abaqus_spec.Material.Hyperelastic.VAL=[0.03 1];
abaqus_spec.Material.Hyperelastic.ATTR.neo_hooke='';
abaqus_spec.Material.ATTR.name='Elastic';
abaqus_spec.Material.Elastic=[0.5 0.49];

%%
% Orientation

% *Orientation, name=Ori-1, system=RECTANGULAR
% Ori-1-DiscOrient
% 2, 90.
abaqus_spec.Orientation.ATTR.name='Ori-1';
abaqus_spec.Orientation.ATTR.system='RECTANGULAR';
abaqus_spec.Orientation.VAL=['Ori-1-DiscOrient' newline vec2strIntDouble([2 90],'%i')];

%%
% Contact pair

%%--> Contact pair
abaqus_spec.contact_pair{1}.ATTR.interaction='user-1';
abaqus_spec.contact_pair{1}.ATTR.type='node to surface';
abaqus_spec.contact_pair{1}.ATTR.adjust='0.0';
abaqus_spec.contact_pair{1}.VAL='AORTA-ASSEMBLY.OUTER, AORTA1-ASSEMBLY.OUTERX';

% surface interaction
abaqus_spec.surface_interaction{1}.ATTR.name='user-1';
abaqus_spec.surface_interaction{1}.ATTR.user='';
abaqus_spec.surface_interaction{1}.ATTR.properties='7';
abaqus_spec.surface_interaction{1}.ATTR.unsymm='';
abaqus_spec.surface_interaction{1}.ATTR.DEPVAR='13';
abaqus_spec.surface_interaction{1}.CSTM=', '; %Line with just comma

%Wrap to max width of 8 entries
t=vec2strIntDouble([0.2, 0.2, 0.05, 0.05,150,1000,0.0],'%6.7e');
t=strwrap(t,8,', ');
abaqus_spec.surface_interaction{1}.VAL=t;

%%
% The step section
%

abaqus_spec.Step.ATTR.name='Step-1';
abaqus_spec.Step.ATTR.nlgeom='YES';
abaqus_spec.Step.Static=[0.1 1 1e-5 0.1];

% Boundary
abaqus_spec.Step.Boundary{1}.VAL={'Set-1',[1 1],0.1};
abaqus_spec.Step.Boundary{2}.VAL={repmat({'origin'},3,1) [1 1; 2 2; 3 3]};
abaqus_spec.Step.Boundary{3}.VAL={'Set-3',[1,1]};
abaqus_spec.Step.Boundary{4}.VAL={'Set-4',[2,2]};
abaqus_spec.Step.Boundary{5}.VAL={'Set-5',[3,3]};

% Loads
% ** LOADS
% **
% ** Name: Load-1   Type: Pressure
% *Dsload
% Surf-1, P, 0.00533
% **
abaqus_spec.Step.Dsload{1}.VAL={'Surf-1','P',0.00533};

%Output
abaqus_spec.Step.Restart.ATTR.write='';
abaqus_spec.Step.Restart.ATTR.frequency=0;

abaqus_spec.Step.Output{1}.ATTR.field='';
abaqus_spec.Step.Output{1}.ATTR.variable='PRESELECT';
abaqus_spec.Step.Output{2}.ATTR.history='';
abaqus_spec.Step.Output{2}.ATTR.variable='PRESELECT';
abaqus_spec.Step.Node_print.ATTR.nset='all';
abaqus_spec.Step.Node_print.ATTR.frequency = 1;
abaqus_spec.Step.Node_print.VAL='COORD';
abaqus_spec.Step.El_print.VAL='S';

% * NODE SET, set=yoursetname, frequency = 1
% U

%%

%% Creating the INP file
% You can use |abaqusStruct2inp| to write the structure data to a file.

%Create file name for INP file
defaultFolder = fileparts(fileparts(mfilename('fullpath')));
savePath=fullfile(defaultFolder,'data','temp');
fileName=fullfile(savePath,'tempModel.inp');
[~,fileNamePart,~]=fileparts(fileName);

%%

[T]=abaqusStruct2inp(abaqus_spec,fileName);

%% View the inp file
%
textView(fileName);

%%
%
% <<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 i4mat_transpose_print_some ( m, n, a, ilo, jlo, ihi, jhi, title )

%*****************************************************************************80
%
%% I4MAT_TRANSPOSE_PRINT_SOME prints some of an I4MAT, transposed.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 September 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns.
%
%    Input, integer A(M,N), an M by N matrix to be printed.
%
%    Input, integer ILO, JLO, the first row and column to print.
%
%    Input, integer IHI, JHI, the last row and column to print.
%
%    Input, string TITLE, a title.
%
  incx = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );

  if ( m <= 0 || n <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  (None)\n' );
    return
  end

  for i2lo = max ( ilo, 1 ) : incx : min ( ihi, m )

    i2hi = i2lo + incx - 1;
    i2hi = min ( i2hi, m );
    i2hi = min ( i2hi, ihi );

    inc = i2hi + 1 - i2lo;

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Row: ' );
    for i = i2lo : i2hi
      fprintf ( 1, '%7d  ', i );
    end
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Col\n' );
    fprintf ( 1, '\n' );

    j2lo = max ( jlo, 1 );
    j2hi = min ( jhi, n );

    for j = j2lo : j2hi

      fprintf ( 1, '%5d: ', j );
      for i2 = 1 : inc
        i = i2lo - 1 + i2;
        fprintf ( 1, '%7d  ', a(i,j) );
      end
      fprintf ( 1, '\n' );

    end

  end

  return
end


function [ know, x ] = p08_sol ( m, know )

%*****************************************************************************80
%
%% P08_SOL returns the solution for problem 08.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input/output, integer KNOW.
%    On input, KNOW is 0, or the index of the previously returned solution.
%    On output, KNOW is 0 if there are no more solutions, or it is the
%    index of the next solution.
%
%    Output, real X(M), the solution, if known.
%
  if ( know == 0 )
    know = 1;
    x(1:m,1) = 0.0;
  else
    know = 0;
    x(1:m,1) = 0.0;
  end

  return
end


function m = p03_m ( )

%*****************************************************************************80
%
%% P03_M returns the number of equations M for problem 3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 April 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer M, the number of equations.
%
  m = 5;

  return
end


function tstr=mktstr
%	return time string in hh:mm:ss format
%	by Hideki Kawahara
%	05/Jan./1995

anatime=fix(clock);
tstr=[num2str(anatime(4)) ':' num2str(anatime(5)) ':' num2str(anatime(6))];


function title = p05_title ( )

%*****************************************************************************80
%
%% P05_TITLE returns a title for problem 5.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = 'The piecewise linear function';

  return
end


%kkabsdiff 'Output = Absolute Value of (Input 1 - (Input 2 or Constant))'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kabsdiff.pane file
%
% Parameters:
% InputFile: i1 'Input 1', required: 'First input data object'
% OutputFile: o 'Output', required: 'Resulting output data object'
% InputFile: i2 'Input 2', optional: 'Second input data object'
%
% Example: o = kkabsdiff({i1, i2}, {'i1','';'o','';'i2',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kabsdiff - Output = Absolute Value of (Input 1 - (Input 2 or Constant))
%
%  DESCRIPTION
% Output = Absolute Value(Input 1 - (Input 2 or a Constant))
%
% The "Absolute Difference" operator computes the absolute value
% of the result of subtracting either \fBInput 2"
% or the \fBConstant" value, which ever is specified by the user,
% from \fBInput 1".
%
% Executing "Absolute Difference" runs the program \fIkarith2\fP
% with the -absdiff flag.
%
%
%  "Data Type - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Data Type - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_2input
%
%  "Map Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/map_1input
%
%  "Map Data - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/map_2input
%
%  "Validity Mask" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_2input
%
%  "Input Objects of Different Sizes" 5
% .cI $DATAMANIP/repos/shared/man/sections/resize_2input
% The values used to pad the data when input files are not the same size are
% (0.0, 0.0).
%
%  "Explicit Location and Time Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Explicit Location and Time Data - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_2input
%
%  "Failure Modes - Single Input"
% .cI $DATAMANIP/repos/shared/man/sections/fail_1input
%
%  "Failure Modes - Two Input Objects"
% .cI $DATAMANIP/repos/shared/man/sections/fail_2input
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
% DATAMANIP::karith2
%
%  RESTRICTIONS
% Operations on complex data are not supported at this time.  If the
% input object is complex, only the real component of the data is
% processed, and the output object is real.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkabsdiff(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,..] = kkabsdiff(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'o', '__output';'i2', '__input'};
maxval={0,0,1};
minval={0,0,1};
istoggle=[0,0,1];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','InputFile'};
% 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 'karith2"  -absdiff'],Inputs,narglist);


function r8vec_indicator1_test ( )

%*****************************************************************************80
%
%% R8VEC_INDICATOR1_TEST tests R8VEC_INDICATOR1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 March 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8VEC_INDICATOR1_TEST\n' );
  fprintf ( 1, '  R8VEC_INDICATOR1 returns a 1-based indicator vector.\n' );

  n = 10;
  a = r8vec_indicator1 ( n );
  r8vec_print ( n, a, '  The indicator1 vector:' );

  return
end


function c = typeadj(a,TYPE)
%TYPEADJ      typecast of  a  to type TYPE
%
%   c = typeadj(a,TYPE)
%
%For details, see intval\typeof and intval\typeadj.
%

% written  10/16/98     S.M. Rump
% written  12/06/98     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
%

% gradient\@gradient\typeadj:  a  must be gradient (superior to intval)
  switch TYPE
    case 'gradient',       c = mid(a);
    case 'gradientintval', c = a;
  otherwise
    error('invalid type in call of typeadj')
  end


% This code was originally written and distributed as part of the
% PASCAL VOC challenge
function ap = VOCap(rec,prec)

mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
    mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));


classdef Dataset < handle
%DATASET Parent class for datasets (e.g. datasets.CIFAR10)
%   The datasets.Dataset class makes it easier to partition a dataset into
%   training/validation sets, as well as in mini-batches.
%
%   It can be used either as a base class (e.g. datasets.CIFAR10), or on
%   its own for custom datasets, without creating a subclass. See the
%   'autonn/examples/cnn/' directory for different examples.
%
%   D = datasets.Dataset() creates an empty, default dataset.
%
%   D.train() returns a cell array with mini-batches, from the shuffled
%   training set. Each mini-batch consists of a set of indexes drawn from
%   the vector D.trainSet.
%
%   D.val() returns a cell array with mini-batches, from the validation set
%   (without shuffling). Each mini-batch consists of a set of indexes drawn
%   from the vector D.valSet.
%
%   D.partition(IDX) partitions a given set (vector) IDX into mini-batches.
%
%   datasets.Dataset('option', value, ...) sets the following properties:
%
%   `batchSize`:: 128
%     The batch size.
%
%   `partialBatches`:: false
%     Whether partial batches are returned (which can happen for the last
%     batch in a set, if the batch size does not divide the set size).
%
%   `trainSet`:: []
%     The training set. Note that subclasses (e.g. datasets.CIFAR10)
%     usually override this property with the default training set.
%
%   `valSet`:: []
%     The validation set. Note that subclasses (e.g. datasets.CIFAR10)
%     usually override this property with the default validation set.

% Copyright (C) 2018 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).

  properties
    batchSize = 128  % batch size
    trainSet = []  % indexes of training samples
    valSet = []  % indexes of validation samples
    partialBatches = false  % whether to return a partial batch (if the batch size does not divide the dataset size)
  end

  methods
    function dataset = Dataset(varargin)
      % parse generic Dataset arguments on non-subclassed construction.
      % allows Dataset to be used as a stand-alone class.
      varargin = dataset.parseGenericArgs(varargin) ;
      assert(isempty(varargin), 'Unknown arguments.') ;
    end

    function args = parseGenericArgs(o, args)
      % called by subclasses to parse generic Dataset arguments
      args = vl_parseprop(o, args, {'batchSize', 'trainSet', 'valSet', 'partialBatches'}) ;
    end

    function batches = train(o)
      % shuffle training set, and partition it into batches
      assert(~isempty(o.trainSet), ['To use the default dataset.train() ' ...
        'method, the training set must be specified (dataset.trainSet).']) ;

      batches = o.partition(o.trainSet(randperm(end))) ;
    end

    function batches = val(o)
      % partition validation set into batches
      assert(~isempty(o.valSet), ['To use the default dataset.val() ' ...
        'method, the validation set must be specified (dataset.valSet).']) ;

      batches = o.partition(o.valSet) ;
    end

    function batches = partition(o, idx, batchSz)
      % partition indexes into batches (stored in a cell array).
      % if IDX is a matrix, each column is a distinct sample.
      if nargin < 3  % allow overriding batch size
        batchSz = o.batchSize ;
      end
      if isvector(idx)
        idx = idx(:)' ;  % ensure row-vector
      end
      batchSz = min(batchSz, size(idx,2));  % guard against big batch size
      batches = cell(1, ceil(size(idx,2) / batchSz)) ;
      b = 1 ;
      for start = 1 : batchSz : size(idx,2)
        batches{b} = idx(:, start : min(start + batchSz - 1, end)) ;
        b = b + 1 ;
      end

      % delete last partial batch if needed
      if ~o.partialBatches && size(batches{end}, 2) < batchSz
        batches(end) = [] ;
      end
    end
  end

end


function createNonemptySolution_FuncGen(OCP)
    dim = OCP.dim;
    N = OCP.N;
    fileID = fopen('./funcgen/createNonemptySolution.m','w');

    fprintf(fileID, 'function solution = createNonemptySolution()\n');
    fprintf(fileID, '   solution.lambda = zeros(%d,%d);\n',dim.lambda,N);
    if dim.mu ~= 0
        fprintf(fileID, '   solution.mu = zeros(%d,%d);\n',dim.mu,N);
    end
    fprintf(fileID, '   solution.u = zeros(%d,%d);\n',dim.u,N);
    fprintf(fileID, '   solution.x = zeros(%d,%d);\n',dim.x,N);
    if dim.z ~= 0
        fprintf(fileID, '   solution.z = zeros(%d,%d);\n',dim.z,N);
    end
    fprintf(fileID, '   solution.LAMBDA = zeros(%d,%d,%d);\n',dim.x,dim.x,N);
    fprintf(fileID, 'end');

    fclose(fileID);

end


function calpak_test46 ( )

%*****************************************************************************80
%
%% CALPAK_TEST46 tests NOW_TO_JED, NOW_TO_YJF_COMMON, NOW_TO_YMDF_COMMON, NOW_TO_YMDHMS_COMMON.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 April 2013
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST46\n' );
  fprintf ( 1, '  For the current time and date, "NOW", \\n' );
  fprintf ( 1, '  NOW_TO_JED returns the JED,\n' );
  fprintf ( 1, '  NOW_TO_YJF_COMMON the YJF date,\n' );
  fprintf ( 1, '  NOW_TO_YMDF_COMMON returns the YMDF date,\n' );
  fprintf ( 1, '  NOW_TO_YMDHMS_COMMON the YMDHMS date.\n' );
  fprintf ( 1, '\n' );

  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '  "NOW" is %s\n', s );

  jed = now_to_jed ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  NOW_TO_JED_COMMON:    Now is: %11.1f\n', jed );

  [ y, j, f ] = now_to_yjf_common ( );
  s = yjf_to_s_common ( y, j, f );

  fprintf ( 1, '  NOW_TO_YJF_COMMON:    Now is: %s\n', s );

  [ y, m, d, f ] = now_to_ymdf_common ( );
  s = ymdf_to_s_common ( y, m, d, f );

  fprintf ( 1, '  NOW_TO_YMDF_COMMON:   Now is: %s\n', s );

  [ y, m, d, h, n, second ] = now_to_ymdhms_common ( );
  s = ymdhms_to_s_common ( y, m, d, h, n, second );

  fprintf ( 1, '  NOW_TO_YMDHMS_COMMON: Now is: %s\n', s );

  return
end


function Qa = aggfcn(Q)
%AGGFCN Aggregation function for a fuzzy system.
%   QA = AGGFCN(Q) creates an aggregation function, QA, from a set of
%   implication functions, Q. Q is a cell array of function handles as
%   returned by IMPLFCNS. QA is a function handle that can be called
%   with a single input V using the syntax: q = QA(V).
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

Qa = @aggregate;

    function q = aggregate(v)
        q = Q{1}(v);
        for i = 2:numel(Q)
            q = max(q, Q{i}(v));
        end
    end

end


function [refl, lambdaNm] = hyperGetEnviSignature(filename)
% HYPERGETENVISIGNATURE Reads an ENVI hyperspectral reflectance signature
%   hyperGetEnviSignature reads the RIT Target Detection Blind Test
% signature files.
%
% Usage
%   [refl, lambdaNm] = hyperGetEnviSignature(filename)
%
% Input
%   filename - Filename of signature.
% Output
%   refl - Reflectance values [0, 1].
%   lambdaNm - corresponding wavelengths in nanometers

fid = fopen(filename);

for k=1:3
    dummy = fgetl(fid);
end

num = 1;
while 1
    tmp = fgetl(fid);
    if (tmp == -1), break, end;
    v = sscanf(tmp, '%f');
    refl(num) = v(2);
    lambdaNm(num) = v(1);
    num = num + 1;
end

refl = refl / 100;


function out = issing(f)
%ISSING   Test if a FUN object is built upon SINGFUN.
%   out = ISSING(F) returns logical true if its ONEFUN is a SINGFUN and false
%   otherwise.

% [TODO]: Should the name of this function go camel case? So far, all is*
% function are named without camel case.

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

out = isa(f.onefun, 'singfun');

end


%% Runme!
% Coded by Manuel Diaz, f99543083
% NTU, IAM, 2012.04.01.

% Exercise 1.a
HWproblem1adIso

% Exercise 1.b
HWproblem1bdIso

% Exercise 2
HWproblem2dIso

% Exercise 3
HWproblem3dIso

% Exercise 4
HWproblem4dIso


function m = p02_m ( )

%*****************************************************************************80
%
%% P02_M returns the number of equations M for problem 2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 April 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer M, the number of equations.
%
  m = 6;

  return
end


function xyz_io_test02 ( )

%*****************************************************************************80
%
%% XYZ_IO_TEST02 tests XYZ_HEADER_READ, XYZ_DATA_READ.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 January 2009
%
%  Author:
%
%    John Burkardt
%
  file_name = 'xyz_io_prb_02.xyz';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'XYZ_IO_TEST02\n' );
  fprintf ( 1, '  XYZ_HEADER_READ reads the header of an XYZ file.\n' );
  fprintf ( 1, '  XYZ_DATA_READ reads the data of an XYZ file.\n' );

  xyz_write_test ( file_name );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  XYZ_WRITE_TEST created some data.\n' );

  point_num = xyz_header_read ( file_name );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  XYZ_HEADER_READ has read the header.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of points = %d\n', point_num );

  xyz = xyz_data_read ( file_name, point_num );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  XYZ_DATA_READ has read the data.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Sample data:\n' );
  fprintf ( 1, '\n' );

  for k = 1 : 11
    i = floor ( ( ( 11 - k     ) * 1 ...
                + (      k - 1 ) * point_num ) ...
                / ( 11     - 1 ) );
    fprintf ( 1, '  %4d  %10f  %10f  %10f\n', i, xyz(1:3,i) );
  end

  return
end


function fixed_num = p12_fixed_num ( )

%*****************************************************************************80
%
%% P12_FIXED_NUM returns the number of fixed points in problem 12.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer FIXED_NUM, the number of fixed points.
%
  fixed_num = 12;

  return
end


function [X,Time,Z] = load_data(datafile,Spec,sample,loadExcel)
%loadData Load vintage of data from file and format as structure
%
% Description:
%
%   Load data from file
%
% Input Arguments:
%
%   datafile - filename of Microsoft Excel workbook file
%
% Output Arguments:
%
% Data - structure with the following fields:
%   .    X : T x N numeric array, transformed dataset
%   . Time : T x 1 numeric array, date number with observation dates
%   .    Z : T x N numeric array, raw (untransformed) dataset

fprintf('Loading data... \n');

if nargin < 4
    loadExcel = 0;
end

ext = datafile(find(datafile=='.',1,'last'):end); % file extension

idx = strfind(datafile,filesep); idx = idx(2);
datafile_mat = fullfile(datafile(1:idx),'mat',[strtok(datafile(idx+1:end),'.') '.mat']);
if exist(datafile_mat,'file')==2 && ~loadExcel
    % Load raw data from MATLAB formatted binary (.mat) file
    d = load(datafile_mat);
    Z    = d.Z;
    Time = d.Time;
    Mnem = d.Mnem;
elseif any(strcmpi(ext,{'.xlsx','.xls'}))
    % Read raw data from Excel file
    [Z,Time,Mnem] = readData(datafile);
    save(datafile_mat,'Z','Time','Mnem');
    %    Z : raw (untransformed) observed data
    % Time : observation periods for the time series data
    % Mnem : series ID for each variable
else
    error('Only Microsoft Excel workbook files supported.');
end

% Sort data based on model specification
Z = sortData(Z,Mnem,Spec);
clear Mnem; % since now Mnem == Spec.SeriesID

% Transform data based on model specification
[X,Time,Z] = transformData(Z,Time,Spec);

% Drop data not in estimation sample
if nargin == 3
    [X,Time,Z] = dropData(X,Time,Z,sample);
end

end

function [Z,Time,Mnem] = readData(datafile)
%readData Read data from Microsoft Excel workbook file

[DATA,TEXT] = xlsread(datafile,'data');
Mnem = TEXT(1,2:end);
if ispc
    Time = datenum(TEXT(2:end,1),'mm/dd/yyyy');
    Z    = DATA;
else
    Time = DATA(:,1) + datenum(1899,12,31) - 1;
    Z    = DATA(:,2:end);
end

end

function [Z,Mnem] = sortData(Z,Mnem,Spec)
%sortData Sort series by order of model specification

% Drop series not in Spec
inSpec = ismember(Mnem,Spec.SeriesID);
Mnem(~inSpec) = [];
Z(:,~inSpec)  = [];

% Sort series by ordering of Spec
N = length(Spec.SeriesID);
permutation = NaN(1,N);
for i = 1:N
    idxSeriesSpec = find(strcmp(Spec.SeriesID{i},Mnem));
    permutation(i) = idxSeriesSpec;
end

Mnem = Mnem(permutation);
Z    = Z(:,permutation);

end

function [X,Time,Z] = transformData(Z,Time,Spec)
%transformData Transforms each data series based on Spec.Transformation
%
% Input Arguments:
%
%      Z : T x N numeric array, raw (untransformed) observed data
%   Spec : structure          , model specification
%
% Output Arguments:
%
%      X : T x N numeric array, transformed data (stationary to enter DFM)

T = size(Z,1);
N = size(Z,2);

X = NaN(T,N);
for i = 1:N
    formula = Spec.Transformation{i};
    freq    = Spec.Frequency{i};
    switch freq  % time step for different frequencies based on monthly time
        case 'm' % Monthly
            step = 1;
        case 'q' % Quarterly
            step = 3;
    end
    t1 = step;    % assume monthly observations start at beginning of quarter
    n  = step/12; % number of years, needed to compute annual % changes
    series  = Spec.SeriesName{i};
    switch formula
        case 'lin' % Levels (No Transformation)
            X(:,i) = Z(:,i);
        case 'chg' % Change (Difference)
            X(t1:step:T,i) = [NaN; Z(t1+step:step:T,i) - Z(t1:step:T-t1,i)];
        case 'ch1' % Year over Year Change (Difference)
            X(12+t1:step:T,i) = Z(12+t1:step:T,i) - Z(t1:step:T-12,i);
        case 'pch' % Percent Change
            X(t1:step:T,i) = 100*[NaN; Z(t1+step:step:T,i) ./ Z(t1:step:T-t1,i) - 1];
        case 'pc1' % Year over Year Percent Change
            X(12+t1:step:T,i) = 100*(Z(12+t1:step:T,i) ./ Z(t1:step:T-12,i) - 1);
        case 'pca' % Percent Change (Annual Rate)
            X(t1:step:T,i) = 100*[NaN; (Z(t1+step:step:T,i) ./ Z(t1:step:T-step,i)).^(1/n) - 1];
        case 'log' % Natural Log
            X(:,i) = log(Z(:,i));
        otherwise
            warning(['Transformation ''' formula ''' not found for ' series '. ' 'Using untransformed data.']);
            X(:,i) = Z(:,i);
    end
end

% Drop first quarter of observations
% since transformations cause missing values
Time = Time(4:end);
Z    = Z(4:end,:);
X    = X(4:end,:);

end

function [X,Time,Z] = dropData(X,Time,Z,sample)
%dropData Remove data not in estimation sample

idxDrop = Time < sample;

Time(idxDrop) = [];
X(idxDrop,:)  = [];
Z(idxDrop,:)  = [];

end


%% MD_RUN is a script to run MD with prescribed input.
%
  filename = 'md_output.txt';

  delete ( filename );

  diary ( filename );

  nd = 3;
  np = 500;
  step_num = 500;
  dt = 0.1;

  md ( nd, np, step_num, dt );

  diary ( 'off' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Output written to "%s"\n', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Normal end of execution.\n' );


function varargout = process_granger1( varargin )
% PROCESS_GRANGER1: Compute the Granger causality 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     = 'Bivariate Granger causality 1xN';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Connectivity';
    sProcess.Index       = 660;
    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);
    % === REMOVE EVOKED REPONSE
    sProcess.options.removeevoked.Comment = 'Remove evoked response from each trial';
    sProcess.options.removeevoked.Type    = 'checkbox';
    sProcess.options.removeevoked.Value   = 0;
    sProcess.options.removeevoked.Group   = 'input';
    % === DIRECTION
    sProcess.options.dirlabel.Comment  = 'Direction of the causality:';
    sProcess.options.dirlabel.Type     = 'label';
    sProcess.options.direction.Comment = {'From the selected node (out)', 'To the selected node (in)', 'Both (generates two files)'};
    sProcess.options.direction.Type    = 'radio';
    sProcess.options.direction.Value   = 3;
    % === GRANGER ORDER
    sProcess.options.grangerorder.Comment = 'Maximum Granger model order (default=10):';
    sProcess.options.grangerorder.Type    = 'value';
    sProcess.options.grangerorder.Value   = {10, '', 0};
    % === 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>
    Comment = sProcess.Comment;
end

%% ===== RUN =====
function OutputFiles = Run(sProcess, sInputA) %#ok<DEFNU>
    % Input options
    OPTIONS = process_corr1n('GetConnectOptions', sProcess, sInputA);
    if isempty(OPTIONS)
        OutputFiles = {};
        return
    end

    % Metric options
    OPTIONS.Method = 'granger';
    OPTIONS.RemoveEvoked = sProcess.options.removeevoked.Value;
    OPTIONS.GrangerOrder = sProcess.options.grangerorder.Value{1};
    OPTIONS.pThresh      = 0.05;
    OPTIONS.Freqs        = 0;

    % Computation depends on the direction
    OutputFiles = {};
    if ismember(sProcess.options.direction.Value, [1 3])
        OPTIONS.GrangerDir = 'out';
        OutputFiles = cat(2, OutputFiles, bst_connectivity({sInputA.FileName}, {sInputA.FileName}, OPTIONS));
    end
    if ismember(sProcess.options.direction.Value, [2 3])
        OPTIONS.GrangerDir = 'in';
        OutputFiles = cat(2, OutputFiles, bst_connectivity({sInputA.FileName}, {sInputA.FileName}, OPTIONS));
    end
end


% Sign is the enumeration class for negative and positive signs.
classdef Sign < Enumerated
	enumeration
		n('negative')
		p('positive')
	end

	methods (Static)
		function elems = elems(ind)
			elems = [Sign.n, Sign.p];
			if nargin > 0  % ind
				elems = elems(ind);
			end
		end

		function count = count()
			count = length(Sign.elems);
		end
	end

	methods
		function g = alter(this)
			% This function simply returned Sign.p if this == Sign.n and Sign.n
			% if this == Sign.p originally, but it is modified to handle
			% arguments given as arrays.
			chkarg(istypeof(this, 'Sign'), '"this" should have Sign as elements.');
			if isempty(this)  % alter([]) makes no sense, but alter(Sign.empty()) does
				g = [];
			else
				g = this.elems(GT.count + 1 - int(this));
			end
		end
	end
end


function r4_uniform_01_test ( )

%*****************************************************************************80
%
%% R4_UNIFORM_01_TEST tests R4_UNIFORM_01.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 July 2006
%
%  Author:
%
%    John Burkardt
%
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R4_UNIFORM_01_TEST\n' );
  fprintf ( 1, '  R4_UNIFORM_01 computes pseudorandom values\n' );
  fprintf ( 1, '  in the interval [0,1].\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The initial seed is %d\n', seed );
  fprintf ( 1, '\n' );

  for i = 1 : 10
    [ x, seed ] = r4_uniform_01 ( seed );
    fprintf ( 1, '  %6d  %14f\n', i, x );
  end

  return
end


function m = p01_m ( )

%*****************************************************************************80
%
%% P01_M returns the number of equations M for problem 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 April 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer M, the number of equations.
%
  m = 5;

  return
end


function value = f_1_2d ( x, y )

%*****************************************************************************80
%
%% F_1_2D evaluates the function 1 in 2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, Y, the arguments.
%
%    Output, real F_1_2D, the value of the function.
%
  value = 1.0;

  return
end


function [ know, x ] = p05_sol ( m, know )

%*****************************************************************************80
%
%% P05_SOL returns the solution for problem 05.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input/output, integer KNOW.
%    On input, KNOW is 0, or the index of the previously returned solution.
%    On output, KNOW is 0 if there are no more solutions, or it is the
%    index of the next solution.
%
%    Output, real X(M), the solution, if known.
%
  if ( know == 0 )
    know = 1;
    x(1:m,1) = 0.0;
  else
    know = 0;
    x(1:m,1) = 0.0;
  end

  return
end


function files = mrtrix_build_files(fname_trunk,lmax)
% Builds a structure with the names of the files that the MRtrix commands
% will generate and need.
%
% files = mrtrix_build_files(fname_trunk,lmax)
%
% Franco Pestilli, Ariel Rokem, Bob Dougherty Stanford University

% Convert the raw dwi data to the mrtrix format:
files.dwi = strcat(fname_trunk,'_dwi.mif');

% This file contains both bvecs and bvals, as per convention of mrtrix
files.b     = strcat(fname_trunk, '.b');

% Convert the brain mask from mrDiffusion into a .mif file:
files.brainmask = strcat(fname_trunk,'_brainmask.mif');

% Generate diffusion tensors:
files.dt = strcat(fname_trunk, '_dt.mif');

% Get the FA from the diffusion tensor estimates:
files.fa = strcat(fname_trunk, '_fa.mif');

% Generate the eigenvectors, weighted by FA:
files.ev = strcat(fname_trunk, '_ev.mif');

% Estimate the response function of single fibers:
files.sf = strcat(fname_trunk, '_sf.mif');
files.response = strcat(fname_trunk, '_response.txt');

% Create a white-matter mask, tracktography will act only in here.
files.wm    = strcat(fname_trunk, '_wm.mif');

% Compute the CSD estimates:
files.csd = strcat(fname_trunk, sprintf('_csd_lmax%i.mif',lmax));

end


function filum_test ( )

%*****************************************************************************80
%
%% FILUM_TEST tests the FILUM library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2011
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FILUM_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the FILUM library.\n' );

  filum_test02 ( );
  filum_test03 ( );
  filum_test06 ( );
  filum_test085 ( );

  filum_test11 ( );
  filum_test13 ( );
  filum_test14 ( );
  filum_test15 ( );
  filum_test165 ( );
  filum_test17 ( );

  filum_test22 ( );
  filum_test225 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FILUM_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function s = ymdhms_to_s_common ( y, m, d, h, n, second )

%*****************************************************************************80
%
%% YMDHMS_TO_S_COMMON "prints" a Common YMDHMS date into a string.
%
%  Format:
%
%    CE YYYY/MM/DD HH:MM:SS
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, M, D, H, N, SECOND, the YMDHMS date.
%
%    Output, string S, contains a representation of the date.
%
  if ( y < 0 )
    s = sprintf ( 'BCE %d/%02d/%02d %02d:%02d:%02d', -y, m, d, h, n, second );
  else
    s = sprintf ( 'CE %d/%02d/%02d %02d:%02d:%02d', y, m, d, h, n, second );
  end

  return
end


function progressbar(n,N,w)

% progressbar - display a progress bar
%
%    progressbar(n,N,w);
%
% displays the progress of n out of N.
% n should start at 1.
% w is the width of the bar (default w=20).
%
%   Copyright (c) Gabriel Peyre 2006

if nargin<3
    w = 20;
end

% progress char
cprog = '.';
cprog1 = '*';
% begining char
cbeg = '[';
% ending char
cend = ']';

p = min( floor(n/N*(w+1)), w);

global pprev;
if isempty(pprev)
    pprev = -1;
end

if not(p==pprev)
    ps = repmat(cprog, [1 w]);
    ps(1:p) = cprog1;
    ps = [cbeg ps cend];
    if n>1
        % clear previous string
        fprintf( repmat('\b', [1 length(ps)]) );
    end
    fprintf(ps);
end
pprev = p;
if n==N
    fprintf('\n');
end


function out = isempty( F )
%ISEMPTY empty boolean check for a CHEBFUN2V object.
%   ISEMPTY(F) returns 1 if every component of F is an empty CHEBFUN2, and
%   return 0 otherwise.

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

if ( isempty( F.components ) )
    out = 1;
    return
end

% Take isempty of each component:
out = cellfun( @isempty, F.components, 'UniformOutput', false );
out = all(cell2mat( out ) );

end


function line_monte_carlo_test ( )

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

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

  return
end


function [ y, m, d ] = deflate_common ( y, m, d )

%*****************************************************************************80
%
%% DEFLATE_COMMON "deflates" dates in the Common Calendar transition month.
%
%  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, the YMD date.
%
%    Output, integer Y, integer M, integer D, the YMD date.
%

  if ( y == 1582 )
    if ( m == 10 )
      if ( 15 <= d )
        d = d - 10;
      end
    end
  end

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

function mx = maxn(V)
% Max of V treated as a vector, equal to max(V(:))
mx = max(V(:));


function neqn = p06_neqn ( )

%*****************************************************************************80
%
%% P06_NEQN returns the number of equations for problem P06.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer NEQN, the number of equations.
%
  neqn = 2;

  return
end


function b=rowswap(a,i,j)
%i and j are row number%
a([i,j],:)=a([j,i],:);
b=a;


function [f,A,b,sdcone,xtype] = optiReadSDPA(filename,dense,print)
%OPTIREADSDPA  Read an SDPA (.dat-s or .dat) file and convert to Matlab Values
%
% [f,A,b,sdcone] = optiReadSDPA(filename) reads the sparse file specified by
% filename and return the semidefinite problem in OPTI format. If you do
% not specify a file a extension, it will default to .dat-s.
%
% [f,A,b,sdcone] = optReadSDPA(filename,dense) allows the user to specify
% whether the file is dense or not. dense = 1 indicates a dense SDPA file,
% and the file extensions will default to .dat if not provided. The default
% is sparse.
%
% [f,A,b,sdcone] = optiReadSDPA(filename,dense,print) allows print out of
% reading progress.
%
% [f,A,b,sdcone,xtype] = optiReadSDPA(..) returns variable integrality.
%
% *sdcone will be a cell array, where each cell is a sparse matrix of the
% form [C(:) A0(:) A1(:) ... ], containing symmetric matrices.

%   Copyright (C) 2013 Jonathan Currie (IPL)
%#ok<*AGROW>

if(nargin < 2), dense = 0; end
if(nargin < 3), print = 0; end

% Make sure we have file extension!
if(isempty(strfind(filename,'.')))
    filename = [filename '.dat-s'];
end

%Open File
fid = fopen(filename);
if(fid == -1)
    error('Error opening file %s',filename);
end

%States
sNCON = 1;
sNBLOCKS = 2;
sSIZES = 3;
sRHS = 4;
sDNDATA = 5;
sSPDATA = 6;
sINTEGER = 7;

%Default Internals
eof = 0;
state = sNCON; cind = 0; bind = 1; rind = 1;
f = []; A = []; b = []; sdcone = []; xtype = [];

if(print)
    ind = strfind(filename,filesep);
    if(isempty(ind))
        file = filename;
    else
        file = filename(ind(end)+1:end);
    end
    if(dense)
        fprintf('Reading Dense SDPA File ''%s''...\n',file);
    else
        fprintf('Reading Sparse SDPA File ''%s''...\n',file);
    end
end
try
    %Main Loop
    while(~eof)
        %Read DAT File String
        str = fgetl(fid);
        %Check for empty
        if(~ischar(str) && str == -1)
            eof = 1;
            continue;
        end
        %Check for comment, skip if found
        if(state ~= sINTEGER && (str(1) == '*' || str(1) == '"'))
            if(~isempty(strfind(str,'*INTEGER')))
                state = sINTEGER;
            end
            continue;
        end
        %Check for equals (Sonja files)
        idx = strfind(str,'=');
        if(~isempty(idx))
            str = str(1:idx-1);
        end
        %Replace { } ( ) [ ] , ; : with spaces
        try
            str = regexprep(str,{'[',']',',','{','}','(',')'},' ');
        catch
            error('Error in SDPA File with "%s"',str);
        end
        %Decode based on state
        switch(state)
            case sNCON
                M = sscanf(str,'%d',1);
                xtype = repmat('C',1,M);
                %Check for errors
                if(M < 1 || M > 1e9), error('The number of constraints is negative or > 1e9'); end
                %Print what we found
                if(print), fprintf('Variables:              %6d\n',M); end
                state = sNBLOCKS;
            case sNBLOCKS
                N = sscanf(str,'%d',1);
                %Check for errors
                if(N < 1 || N > 1e9), error('The number of blocks is negative or > 1e9'); end
                %Print what we found
                if(print), fprintf('Number of Blocks:       %6d\n',N); end
                state = sSIZES;
            case sSIZES
                blocksize = sscanf(str,'%d');
                %Check length = number of blocks
                if(length(blocksize) ~= N), error('The number of blocks does not match the number of entries of block sizes'); end
                if(any(blocksize == 0) || any(blocksize > 1e9)), error('A block size is 0 or > 1e9'); end
                %Print Total Dims
                if(print)
                    fprintf('  Linear:               %6d\n',length(blocksize(blocksize < 0)));
                    fprintf('  Semidefinite:         %6d\n',length(blocksize(blocksize > 0)));
                    fprintf('Total Block Dimension:  %6d\n',sum(abs(blocksize)));
                end
                %Allocate problem data
                sdcone = cell(sum(blocksize > 0),1); j = 1;
                for i = 1:N
                    if(blocksize(i) > 0)
                        if(dense)
                            sdcone{j} = zeros(blocksize(i)^2,M+1);
                        else
                            sdcone{j} = sparse(blocksize(i)^2,M+1); %not the greatest...
                        end
                        j = j + 1;
                    end
                end
                %Create linear part
                ind = blocksize < 0;
                if(any(ind))
                    if(dense)
                        A = zeros(sum(abs(blocksize(ind))),M);
                    else
                        A = sparse(sum(abs(blocksize(ind))),M);
                    end
                    b = zeros(sum(abs(blocksize(ind))),1);
                end
                %Create index vector
                blockindex = zeros(N,1);  lp = 1; sdp = 1;
                for i = 1:N
                    if(blocksize(i) < 0)
                        blockindex(i) = lp; lp  = lp + 1;
                    else
                        blockindex(i) = sdp; sdp = sdp + 1;
                    end
                end
                state = sRHS;
            case sRHS
                f = sscanf(str,'%f'); f = -f;
                %Check length = number of constraints
                if(length(f) ~= M), error('The number of RHS elements does not match the number of constraints'); end
                if(dense)
                    state = sDNDATA;
                else
                    state = sSPDATA;
                end
            %Sparse Data File
            case sSPDATA
                data = sscanf(str,'%d %d %d %d %f');
                if(~isempty(data)) %could be {}
                    %Check for C matrix
                    if(data(1) == 0)
                        %Check block for linear
                        if(blocksize(data(2)) < 0)
                            if(data(3) ~= data(4)), error('A diagonal entry in C is not on the diagonal!'); end
                            %Find start index by determining sizes of previous LP blocks encountered
                            bsizes = blocksize(1:data(2)-1);
                            stIndex = abs(sum(bsizes(bsizes < 0)));
                            b(stIndex + data(3)) = -data(5);
                        else %semidef
                            sdcone{blockindex(data(2))}(data(3) + (data(4) - 1)*blocksize(data(2)),1) = data(5);
                            %if off-diagonal, place in transposed position (build symmetric matrices)
                            if(data(3) ~= data(4))
                                sdcone{blockindex(data(2))}(data(4) + (data(3) - 1)*blocksize(data(2)),1) = data(5);
                            end
                        end
                    else
                        %Check block for linear
                        if(blocksize(data(2)) < 0)
                            if(data(3) ~= data(4)), error('A diagonal entry in A is not on the diagonal!'); end
                            %Find start index by determining sizes of previous LP blocks encountered
                            bsizes = blocksize(1:data(2)-1);
                            stIndex = abs(sum(bsizes(bsizes < 0)));
                            A(stIndex + data(3),data(1)) = data(5);
                        else %semidef
                            sdcone{blockindex(data(2))}(data(3) + (data(4) - 1)*blocksize(data(2)),data(1)+1) = -data(5);
                            %if off-diagonal, place in transposed position (build symmetric matrices)
                            if(data(3) ~= data(4))
                                sdcone{blockindex(data(2))}(data(4) + (data(3) - 1)*blocksize(data(2)),data(1)+1) = -data(5);
                            end
                        end
                    end
                end
            %Dense Data File
            case sDNDATA
                data = sscanf(str,'%f');
                if(~isempty(data)) %could be {}
                    %Check for C matrix
                    if(cind == 0)
                        %Check block for linear
                        if(blocksize(bind) < 0)
                            if(length(data) ~= abs(blocksize(bind))), error('Data read in dense entry C (diagonal) is not the correct length!'); end
                            %Find start index by determining sizes of previous LP blocks encountered
                            bsizes = blocksize(1:bind-1);
                            stIndex = abs(sum(bsizes(bsizes < 0)))+1;
                            b(stIndex:stIndex+abs(blocksize(bind))-1) = -data;
                        else
                            if(length(data) == blocksize(bind))
                                sdcone{blockindex(bind)}(rind:blocksize(bind):blocksize(bind)^2) = data;
                                rind = rind + 1;
                            elseif(length(data) == blocksize(bind)^2)
                                %Create matrix and transpose it
                                temp = reshape(data,blocksize(bind),blocksize(bind))';
                                sdcone{blockindex(bind)}(:,1) = temp(:);
                                rind = rind + blocksize(bind);
                            else
                                error('Data read in dense entry C matrix is not the correct length. Expected first row of a matrix, or the entire matrix (all rows and columns, row major).');
                            end
                        end
                    else
                        %Check block for linear
                        if(blocksize(bind) < 0)
                            if(length(data) ~= abs(blocksize(bind))), error('Data read in dense entry A%d (diagonal) is not the correct length!',cind); end
                            %Find start index by determining sizes of previous LP blocks encountered
                            bsizes = blocksize(1:bind-1);
                            stIndex = abs(sum(bsizes(bsizes < 0)))+1;
                            A(stIndex:stIndex+abs(blocksize(bind))-1,cind) = data;
                        else
                            if(length(data) == blocksize(bind))
                                sdcone{blockindex(bind)}(rind + (cind)*blocksize(bind)^2:blocksize(bind):blocksize(bind)^2 + (cind)*blocksize(bind)^2) = -data;
                                rind = rind + 1;
                            elseif(length(data) == blocksize(bind)^2)
                                %Create matrix and transpose it
                                temp = reshape(data,blocksize(bind),blocksize(bind))';
                                sdcone{blockindex(bind)}(:,cind+1) = -temp(:);
                                rind = rind + blocksize(bind);
                            else
                                error('Data read in dense entry A%d matrix is not the correct length. Expected first row of a matrix, or the entire matrix (all rows and columns, row major).',cind);
                            end
                        end
                    end
                    %Increment pointers
                    if(blocksize(bind) < 0 || rind > blocksize(bind))
                        rind = 1;
                        bind = bind + 1;
                    end
                    if(bind > N)
                        bind = 1;
                        cind = cind + 1;
                    end
                end
            case sINTEGER
                if(isempty(xtype))
                    error('Your integer declaration must come last!');
                end
                idx = sscanf(str,'*%d');
                xtype(idx) = 'I';

        end
        eof = feof(fid);
    end
catch ME
    fclose(fid);
    rethrow(ME);
end

%Ensure sparse return args
if(~isempty(sdcone))
    for i = 1:length(sdcone)
        if(~issparse(sdcone{i}))
            sdcone{i} = sparse(sdcone{i});
        end
    end
end
if(~isempty(A))
    if(~issparse(A)), A = sparse(A); end
end
if(print)
    nz = 0;
    if(~isempty(sdcone))
        for i = 1:length(sdcone)
            nz = nz + nnz(sdcone{i});
        end
    end
    fprintf('Total Semidefinite NZs: %6d\n',nz);
    fprintf('Finished Reading SDPA File\n\n');
end
%Close
fclose(fid);


%MATHCONVENTIONS specifying mathematical conventions for IMAEL m-files
%
% Angles are counted in degrees, unless specified otherwise.
% Many old functions use radians, so it is advised to always handle angle
% data with care.
%


function BF_AnnotatePoints(xy,TimeSeries,annotateParams)
% BF_AnnotatePoints     Annotates time series/metadata to a plot
%
%---INPUTS:
% xy, a vector (or cell) of x-y co-ordinates of points on the plot
% TimeSeries, a table of time series making up the plot
% annotateParams, structure of custom plotting parameters

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This work is licensed under the Creative Commons
% Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of
% this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send
% a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View,
% California, 94041, USA.
% ------------------------------------------------------------------------------

numTimeSeries = height(TimeSeries);

% ------------------------------------------------------------------------------
%% Set default plotting parameters:
% ------------------------------------------------------------------------------
if isfield(annotateParams,'n')
    numAnnotate = annotateParams.n;
else
    numAnnotate = 6;
end
if numAnnotate==0 % no need to go further
    return
end
% Cannot allow to annotate more points than time series
numAnnotate = min(numAnnotate,numTimeSeries);
if isfield(annotateParams,'maxL')
    maxL = annotateParams.maxL;
else
    maxL = 300; % length of annotated time series segments
end
if isfield(annotateParams,'userInput')
    userInput = annotateParams.userInput;
else
    userInput = true; % user input points rather than being randomly chosen
end
if isfield(annotateParams,'fdim')
    fdim = annotateParams.fdim;
else
    fdim = [0.30,0.08]; % width, height
end
% textAnnotation can be: 'Name' (annotate name),
% 'ID' (annotate ts_id), or 'none' (not annotation)
if isfield(annotateParams,'textAnnotation')
    if ismember(annotateParams.textAnnotation,{'Name','ID','none'})
        textAnnotation = annotateParams.textAnnotation;
    else
        warning('Unknown annotation type: %s',annotateParams.textAnnotation);
        textAnnotation = 'none'; % no annotations by default
    end
else
    textAnnotation = 'none'; % no annotations by default
end
if isfield(annotateParams,'theLineWidth')
    theLineWidth = annotateParams.theLineWidth;
else
    theLineWidth = 0.8; % % line width for time series
end
% Work through colors of the rainbow if only one class:
if isfield(annotateParams,'doRainbow')
    doRainbow = annotateParams.doRainbow;
else
    doRainbow = true;
end
plotCircle = true; % circle around annotated points

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

% Want on a common scale for finding neighbors:
% xy_std = std(xy);
% xy_mean = mean(xy);
% xy_zscore = zscore(xy);

% Initializing basic parameters/variables:
ax = gca;
pxlim = ax.XLim; % plot limits
pylim = ax.YLim; % plot limits
pWidth = diff(pxlim); % plot width
pHeight = diff(pylim); % plot height
alreadyPicked = zeros(numAnnotate,1); % record those already picked

% Groups:
[groupLabels,classLabels,groupLabelsInteger,numGroups] = TS_ExtractGroupLabels(TimeSeries);

% Colors:
if ~isfield(annotateParams,'groupColors')
    groupColors = GiveMeGroupColors(annotateParams,numGroups); % Set colors
else
    groupColors = annotateParams.groupColors;
end
if numGroups==1
    if doRainbow
        rainbowColors = [BF_GetColorMap('set1',5,1); BF_GetColorMap('dark2',6,1)];
    else
        % all black:
        rainbowColors = repmat([0,0,0],20,1);
        rainbowColors = mat2cell(rainbowColors,ones(20,1));
    end
end

%-------------------------------------------------------------------------------
% Don't use user input to select points to annotate: instead they are selected randomly
%-------------------------------------------------------------------------------
if ~userInput
    % Annotate a random set:
    alreadyPicked = randsample(numTimeSeries,numAnnotate);
end

% ------------------------------------------------------------------------------
% Go through and annotate selected points
%-------------------------------------------------------------------------------
fprintf(1,['Annotating time series segments to %u points in the plot, ' ...
                    'displaying %u samples from each...\n'],numAnnotate,maxL);

for j = 1:numAnnotate
    title(sprintf('%u points remaining to annotate',numAnnotate-j+1));

    % Get user to pick a point, then find closest datapoint to their input:
    if userInput % user input
        newPointPicked = false;
        numAttempts = 0;
        % Keep selecting until you get a new point (can't get stuck in infinite
        % loop because maximum annotations is number of datapoints). Still, you
        % get 3 attempts to pick a new point
        while ~newPointPicked && (numAttempts < 3)
            point = ginput(1);
            % point_z = (point - xy_mean)./xy_std;
            iPlot = BF_ClosestPoint_ginput(xy,point,true);
            if ~ismember(iPlot,alreadyPicked)
                alreadyPicked(j) = iPlot;
                newPointPicked = true;
            else
                beep
                numAttempts = numAttempts + 1;
            end
        end
        if numAttempts==3 % maxed out
            alreadyPicked(j) = NaN;
            continue
        end
    else
        % Use a previously-selected point (pre-selected at random)
        iPlot = alreadyPicked(j);
    end

    % (x,y) co-ords of the point to plot:
    plotPoint = xy(iPlot,:);

    % Get the group index of the selected time series:
    theGroupIndex = groupLabelsInteger(iPlot);

    % Crop the time series:
    if ~isempty(maxL)
        timeSeriesSegment = TimeSeries.Data{iPlot}(1:min(maxL,end));
    else
        timeSeriesSegment = [];
    end

    % When only one group, cycle through rainbow colors for each annotation:
    if numGroups==1
        % cycle through rainbow colors sequentially:
        groupColors{1} = rainbowColors{rem(j,length(rainbowColors)-1)+1};
    end

    % Plot a circle around the annotated point:
    if plotCircle
        plot(plotPoint(1),plotPoint(2),'o','MarkerEdgeColor',groupColors{theGroupIndex},...
                            'MarkerFaceColor',brighten(groupColors{theGroupIndex},0.5));
    end

    % Add text annotations:
    switch textAnnotation
    case 'Name'
        % Annotate text with names of datapoints:
        if ismember('Group',TimeSeries.Properties.VariableNames)
            text(plotPoint(1),plotPoint(2)-0.01*pHeight,sprintf('%s-%u',...
                    TimeSeries.Name{iPlot},TimeSeries.Group(iPlot)),...
                    'interpreter','none','FontSize',8,...
                    'color',brighten(groupColors{theGroupIndex},-0.6));
        else
            text(plotPoint(1),plotPoint(2)-0.01*pHeight,TimeSeries.Name{iPlot},...
                    'interpreter','none','FontSize',8,...
                    'color',brighten(groupColors{theGroupIndex},-0.6));
        end
    case 'ID'
        % Annotate text with ts_id:
        text(plotPoint(1),plotPoint(2)-0.01*pHeight,...
                num2str(TimeSeries.ID(iPlot)),...
                    'interpreter','none','FontSize',8,...
                    'color',brighten(groupColors{theGroupIndex},-0.6));
    case 'length'
        text(plotPoint(1),plotPoint(2)-0.01*pHeight,...
                num2str(length(TimeSeries.Data{iPlot})),...
                'interpreter','none','FontSize',8,...
                'color',brighten(groupColors{theGroupIndex},-0.6));
    end

    % Adjust if annotation goes off axis x-limits
    px = plotPoint(1)+[-fdim(1)*pWidth/2,+fdim(1)*pWidth/2];
    if px(1) < pxlim(1), px(1) = pxlim(1); end % can't plot off left side of plot
    if px(2) > pxlim(2), px(1) = pxlim(2)-fdim(1)*pWidth; end % can't plot off right side of plot

    % Adjust if annotation goes above maximum y-limits
    py = plotPoint(2)+[0,fdim(2)*pHeight];
    if py(2) > pylim(2)
        py(1) = pylim(2)-fdim(2)*pHeight;
    end

    % Annotate the time series
    if ~isempty(timeSeriesSegment)
        plot(px(1)+linspace(0,fdim(1)*pWidth,length(timeSeriesSegment)),...
                py(1)+fdim(2)*pHeight*(timeSeriesSegment-min(timeSeriesSegment))/(max(timeSeriesSegment)-min(timeSeriesSegment)),...
                    '-','color',groupColors{theGroupIndex},'LineWidth',theLineWidth);
    end

end

% Clear the title
title('')

%-------------------------------------------------------------------------------
function groupColors = GiveMeGroupColors(annotateParams,numGroups) % Set colors
    if isstruct(annotateParams) && isfield(annotateParams,'cmap')
        if ischar(annotateParams.cmap)
            groupColors = BF_GetColorMap(annotateParams.cmap,numGroups,1);
        else
            groupColors = annotateParams.cmap; % specify the cell itself
        end
    else
        if numGroups < 10
            groupColors = BF_GetColorMap('set1',numGroups,1);
        elseif numGroups <= 12
            groupColors = BF_GetColorMap('set3',numGroups,1);
        elseif numGroups <= 22
            groupColors = [BF_GetColorMap('set1',numGroups,1); ...
                        BF_GetColorMap('set3',numGroups,1)];
        elseif numGroups <= 50
            groupColors = mat2cell(jet(numGroups),ones(numGroups,1));
        else
            error('There aren''t enough colors in the rainbow to plot this many classes!')
        end
    end
    if (numGroups == 1)
        groupColors = {'k'}; % Just use black...
    end
end
%-------------------------------------------------------------------------------

end


function [ y, j, ierror ] = yj_check_common ( y, j )

%*****************************************************************************80
%
%% YJ_CHECK_COMMON checks a Common YJ date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y, J, the YJ date.
%
%    Output, integer IERROR, is 0 if no serious error was found in
%    the date, and 1 otherwise.
%

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

  if ( ierror ~= 0 )
    return
  end
%
%  Make sure J is not too small or too big.
%
  [ y, j ] = j_borrow_common ( y, j );

  [ y, j ] = j_carry_common ( y, j );

  return
end


function str = stripzeros(strin)
     %STRIPZEROS Strip trailing zeros, leaving one digit right of decimal point.
     % Remove trailing zeros while leaving at least one digit to the right of
     % the decimal place.

     %   Copyright 2010 The MathWorks, Inc.

     str = strin;
     n = regexp(str,'\.0*$');
    if ~isempty(n)
        % There is nothing but zeros to the right of the decimal place;
        % the value in n is the index of the decimal place itself.
        % Remove all trailing zeros except for the first one.
        str(n+2:end) = [];
    else
        % There is a non-zero digit to the right of the decimal place.
        m = regexp(str,'0*$');
        if ~isempty(m)
            % There are trailing zeros, and the value in m is the index of
            % the first trailing zero. Remove them all.
            str(m:end) = [];
        end
    end


function jed = epoch_to_jed_saka ( )

%*****************************************************************************80
%
%% EPOCH_TO_JED_SAKA returns the epoch of the Saka calendar as a JED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real JED, the Julian Ephemeris Date of the epoch.
%
  jed = 1749994.5;

  return
end


function mesh2off(OFFfilename, faces,vertices)
% output a mesh into an OFF file
% input:
% OFFfilename is the file name for the off file
% faces is Nx3 matrix for vertex index
% vertices is KxD matrix. D is the number of polygon size. =3 if triangles

file = fopen(OFFfilename,'w');
fprintf (file, 'OFF %d %d 0\n', size(vertices,1), size(faces,1));
for v=1:size(vertices,1)
    fprintf(file, '%f %f %f\n', vertices(v,1), vertices(v,2), vertices(v,3));
end

faces = faces -1; % matlab starts from 1, office starts from 0

for f=1:size(faces,1)
    fprintf(file, '%d', size(faces,2));
    for i=1:size(faces,2)
        fprintf(file, ' %f', faces(f,i));
    end
    fprintf(file, '\n');
end

fclose(file);


function s = s_sort_a ( s )

%*****************************************************************************80
%
%% S_SORT_A sorts a string into ascending order.
%
%  Discussion:
%
%    The string is assumed to be short, and so a simple bubble sort is used.
%
%    ALL the characters are sorted, including blanks and punctuation.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be sorted.
%
%    Output, string S, the sorted string.
%
  s_length = length ( s );

  for i = 1 : s_length - 1

    c = s(i);
    j = i;

    for k = i + 1 : s_length
      if ( s(k) < s(j) )
        j = k;
      end
    end

    s(i) = s(j);
    s(j) = c;

  end

  return
end


function varargout = funlogger(x,varargin)
%FUNLOGGER Record log of calls to a specific function.
%
%   FUNLOGGER([],FUN) initialize logger for function FUN. FUN must be either
%   a string with the function name or a function handle for function F(X).
%   F takes a numeric array as input and returns a single scalar as output.
%
%   FUNLOGGER([],FUN,N) stores up to N function calls (default N=1e4).
%
%   FUNLOGGER([],FUN,N,OUTSIZE) specifies that FUN returns a numeric array
%   with OUTSIZE elements (default OUTSIZE=1).
%
%   FVAL = FUNLOGGER(X) returns the value of the logged function at X,
%   where X is a numeric array.
%
%   [FVAL,FUNLOG] = FUNLOGGER(X) also returns the function log structure.
%
%   [...] = FUNLOGGER(X,ARG1,ARG2,...) passes a series of additional
%   arguments to the call of logged function.
%
%   FUNLOG = FUNLOGGER() returns the function log structure.
%
%
%   Author: Luigi Acerbi
%   Version: Sep/11/2015
%
persistent funlog;     % Record log of function calls

%% Case 1: No arguments ==> return function log
if nargin < 1
    varargout = {funlog};

    %if isstruct(x)  % Swapped variable order
    %    temp = probstruct;
    %    probstruct = x;
    %    x = temp;
    %end

%% Case 2: Empty X, no output, pass function name or handle ==> Re-initialize log struct
elseif isempty(x) && nargout == 0 && ...
        (ischar(varargin{1}) || isa(varargin{1},'function_handle'))
    funlog = [];
    fun = varargin{1};
    if nargin > 2; N = varargin{2}; else N = []; end
    if nargin > 3; outsize = varargin{3}; else outsize = []; end

    % Store function name and function handle
    if ischar(fun)
        funlog.FuncName = fun;
        funlog.FuncHandle = str2func(fun);
    else
        funlog.FuncName = func2str(fun);
        funlog.FuncHandle = fun;
    end

    % Number of stored function values
    if isempty(N); N = 1e4; end

    % Size of function output arguments
    if isempty(outsize); outsize = 1; end
    funlog.OutSize = outsize;

    funlog.Clock = tic;     % Time of initialization
    funlog.FuncCount = 0;
    funlog.X = [];
    funlog.Y = [];

    funlog.N = N;           % Size of X matrix, temporary
    funlog.last = 0;        % Last entry

%% Case 3: Pass X, get output ==> Standard function call
else
    if isempty(x) && nargin == 2 && isnumeric(varargin{1})
        % MCS call
        x = varargin{1}';
        varargin = [];
        mcs_flag = true;
    else
        mcs_flag = false;
    end

    % You need to initialize FUNLOGGER first
    if isempty(funlog)
        error('FUNLOGGER has not been initialized.');
    end

    % Call function
    func = funlog.FuncHandle;

    % if isfield(probstruct,'octstruct'); x = optimct(x,probstruct.octstruct,1); end

    % Check if need to pass probstruct
    try
        if nargin > 1 && ~mcs_flag
            fval = func(x,varargin{:});
        else
            fval = func(x);
        end
    catch funErr
        warning(['Error in executing the logged function ''' funlog.FuncName ''' with input:']);
        x
        rethrow(funErr);
        % fval = NaN(1,funlog.OutSize);
    end

    funlog.FuncCount = funlog.FuncCount + 1;

    % Record log
    if isempty(funlog.X)
        funlog.X = NaN(funlog.N,length(x));
        funlog.Y = NaN(funlog.N,funlog.OutSize);
    end

    funlog.last = max(1,mod(funlog.last+1, funlog.N+1));
    funlog.X(funlog.last,:) = x;
    try
        funlog.Y(funlog.last,:) = fval;
    catch
        pause
    end

    varargout{1} = fval;
    if nargout > 1; varargout{2} = funlog; end
end

end


function chrpak_test046 ( )

%*****************************************************************************80
%
%% TEST046 tests HEX_TO_I4 and I4_TO_HEX.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 June 2007
%
%  Author:
%
%    John Burkardt
%
  test_num = 3;

  i4_test = [ 21, -32, 1776 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST046\n' );
  fprintf ( 1, '  HEX_TO_I4, hexadecimal->integer.\n' );
  fprintf ( 1, '  I4_TO_HEX, integer->hexadecimal\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  I  I4_TO_HEX(I)  HEX_TO_I4(I4_TO_HEX(I))\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num

    i4 = i4_test(test);
    hex = i4_to_hex ( i4 );
    j4 = hex_to_i4 ( hex );

    fprintf ( 1, '  %8d  %8s  %8d\n', i4, hex, j4 );

  end

  return
end


function st_print_some ( row1, row2, col1, col2, nst, ist, jst, ast, title )

%*****************************************************************************80
%
%% ST_PRINT_SOME prints some of an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 July 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ROW1, ROW2, the first and last rows to print.
%
%    Input, integer COL1, COL2, the first and last columns to print.
%
%    Input, integer NST, the number of nonzeros.
%
%    Input, integer IST(NST), COL(NST), the row and column indices.
%
%    Input, real A(NST), the nonzero values.
%
%    Input, string TITLE, a title.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );
  fprintf ( 1, '\n' );

  for k = 1 : nst
    if ( row1 <= ist(k) & ist(k) <= row2 & col1 <= jst(k) & jst(k) <= col2 )
      fprintf ( 1, '  %8d  %8d  %8d  %16.8f\n', k, ist(k), jst(k), ast(k) );
    end
  end

  return
end


function output = createOutput
    output.iterInit    = 0;
    output.cost        = 0;
    output.KKTError       = 0;
    output.timeElapsed.searchDirection = 0;
    output.timeElapsed.lineSearch = 0;
    output.timeElapsed.KKTErrorCheck = 0;
    output.timeElapsed.total = 0;
    output.rho         = 0;
    output.iterTotal     = 0;
    output.exitflag    = 0;
end


function toeplitz_cholesky_test ( )

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

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

  return
end


function [d,c]=runenc(x);
ind=1;
d(ind)=x(1);
c(ind)=1;

for i=2 :length(x)
    if x(i-1)==x(i)
       c(ind)=c(ind)+1;
    else ind=ind+1;
         d(ind)=x(i);
         c(ind)=1;
    end
end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defop  Method   @@sym uplus (@var{x})
%% @defopx Operator @@sym {+@var{x}} {}
%% Symbolic unitary minus.
%%
%% A no-op.  Example:
%% @example
%% @group
%% syms x
%% +x
%%   @result{} (sym) x
%% @end group
%% @end example
%% @seealso{@@sym/uminus}
%% @end defop

function x = uplus(x)

  % no-op

end

%!test
%! syms x
%! assert (isa (+x, 'sym'))
%! assert (isequal (+x, x))

%!test
%! A = sym([0 -1 inf]);
%! assert( isequal ( +A, A))


% This file is part of the project NILM-Eval (https://github.com/beckel/nilm-eval).
% Licence: GPL 2.0 (http://www.gnu.org/licenses/gpl-2.0.html)
% Copyright: ETH Zurich, 2014
% Author: Romano Cicchetti

function [ houses ] = findHouseholds(appliance, dataset)

    % returns all household for which the plug-level data of the specified
    % appliance exists

     appliance_house_matrix = getApplianceHouseMatrix(dataset);
     houses = find(appliance_house_matrix(appliance,:)>0);

end


function F = transpose( F )
% .' transpose of a DISKFUN
%    F = TRANSPOSE(F) is the same as F.'. The orientation of the DISKFUNV
%    is transposed.
%
%    See also DISKFUNV/CTRANSPOSE

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

F.isTransposed = ~F.isTransposed;

end


function latin_cover_test ( )

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

  latin_cover_test01 ( );
  latin_cover_test02 ( );
  latin_cover_test03 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LATIN_COVER_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function twod_to_vtu_test ( )

%*****************************************************************************80
%
%% TWOD_TO_VTU_TEST tests the TWOD_TO_VTU library.
%
%  Discussion:
%
%    The data represents a flow solution in a 10 by 3 channel.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 December 2010
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( '\n' );
  fprintf ( 1, 'TWOD_TO_VTU_TEST:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the TWOD_TO_VTU library.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read in TWOD finite element data.\n' );
  fprintf ( 1, '  Write it out as a VTU file.\n' );
%
%  Load the data from text files.
%
  nodes = load ( 'channel_nodes.txt' );
  elements = load ( 'channel_elements.txt' );
  uvp = load ( 'channel_values.txt' );

  output_filename = 'channel.vtu';

  title = 'UVP for 10x3 2D channel problem';
%
%  Have the data written to a file.
%
  twod_to_vtu ( nodes, elements, uvp, output_filename, title );
%
%  Terminate.
%
  fprintf ( '\n' );
  fprintf ( 1, 'TWOD_TO_VTU_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( '\n' );
  timestamp ( );

  return
end


function hole_point = p06_hole_point ( hole_index, m )

%*****************************************************************************80
%
%% P06_HOLE_POINT returns a point inside a given hole in problem 6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer HOLE_INDEX, the index of the hole.
%
%    Input, integer M, the spatial dimension.
%
%    Output, real HOLE_POINT(M), a point in the hole
%
  hole_point(1:2) = [ 0.0, 0.0 ];

  return
end


function a = i4row_swap ( m, n, a, irow1, irow2 )

%*****************************************************************************80
%
%% I4ROW_SWAP swaps two rows of an I4ROW.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns.
%
%    Input, integer A(M,N), an array of data.
%
%    Input, integer IROW1, IROW2, the two rows to swap.
%
%    Output, integer A(M,N), the array of data, with two rows swapped.
%

%
%  Check.
%
  if ( irow1 < 1 || m < irow1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4ROW_SWAP - Fatal error!\n' );
    fprintf ( 1, '  IROW1 is out of range.\n' );
    error ( 'I4ROW_SWAP - Fatal error!' );
  end

  if ( irow2 < 1 || m < irow2 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4ROW_SWAP - Fatal error!\n' );
    fprintf ( 1, '  IROW2 is out of range.\n' );
    error ( 'I4ROW_SWAP - Fatal error!' );
  end

  if ( irow1 == irow2 )
    return
  end

  row(1:n) = a(irow1,1:n);
  a(irow1,1:n) = a(irow2,1:n);
  a(irow2,1:n) = row(1:n);

  return
end


function [outputlabel, outputindex] = inputlabel2outputlabel(cfg, freq)

% INPUTLABEL2OUTPUTLABEL is a subfunction which outputs the cell-arrays
% outputlabel and the corresponding outputindex, and defines how the
% channels in the original data have to be combined, to provide the
% wished for combination of the channels, as defined in cfg.combinechan
%
% Configuration-options are:
%   cfg.combinechan = 'planar' combines the horizontal and vertical planar-gradients
%                     'pseudomeg' one gradiometer versus the rest
%   TODO: more flexible way of combining, e.g. by providing a cell-array

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

if ~isfield(cfg, 'combinechan'), cfg.combinechan = 'no'; end

if strcmp(cfg.combinechan, 'no')
  % the output labels are similar to the input labels
  outputlabel = {};
  outputindex = {};
  for i=1:length(freq.label)
    outputindex{i} = i;
    outputlabel(i) = freq.label(i);
  end
elseif strcmp(cfg.combinechan, 'planar')
  % find the combination of horizontal and vertical channels that should be combined
  planar      = planarchannelset(freq);
  [sel_dH, H] = match_str(freq.label, planar(:,1));  % indices of the horizontal channels
  [sel_dV, V] = match_str(freq.label, planar(:,2));  % indices of the vertical   channels
  lab_dH      = freq.label(sel_dH);
  lab_dV      = freq.label(sel_dV);

  if length(sel_dH)~=length(sel_dV)
    [int,ih,iv] = intersect(H,V);
    sel_dH = sel_dH(ih);
    sel_dV = sel_dV(iv);
    %error('not all planar channel combinations are complete')
  else
    ih  = 1:length(sel_dH);
    iv  = 1:length(sel_dV);
    int = 1:length(ih);
  end

  % find the other channels that are present in the data
  sel_other = setdiff(1:length(freq.label), [sel_dH(:)' sel_dV(:)']);
  lab_other = freq.label(sel_other);

  % define the channel names after combining the planar combinations
  % they should be sorted according to the order of the horizontal planar channels in the data
  [dum, sel_planar] = match_str(freq.label, planar(:,1));
  if exist('ih', 'var'), sel_planar = sel_planar(int); end
  lab_comb          = planar(sel_planar,3);
  [dum, sel_comb]   = match_str(planar(H(ih),3),planar(V(iv),3));

  outputlabel = {};
  outputindex = {};

  outputlabel = [outputlabel; lab_other];
  outputindex = [outputindex; mat2cell(sel_other', ones(length(sel_other),1), 1)];

  outputlabel = [outputlabel; lab_comb];
  outputindex = [outputindex; mat2cell([sel_dH sel_dV(sel_comb)], ones(length(sel_dH),1), 2)];

elseif strcmp(cfg.combinechan, 'pseudomeg'),
  outputlabel = {};
  outputindex = {};
  for i=1:length(freq.label)
    outputlabel{i} = ['all-',freq.label{i}];
    outputindex{i} = [setdiff(1:length(freq.label),i)];
  end
  for i=1:length(freq.label)
    outputlabel{end+1} = freq.label{i};
    outputindex{end+1} = i;
  end
elseif iscell(cfg.combinechan(1)),
  for i=1:length(cfg.combinechan)
    outputindex{i} = match_str(freq.label, cfg.combinechan{i});
    outputindex{i} = outputindex{i}(:)';
    outputlabel{i} = cell2mat(freq.label(outputindex{i})');
  end
else
  ft_error('unknown combination method');
end


function x = p03_start ( i, x )

%*****************************************************************************80
%
%% P03_START returns a starting point for problem 3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer I, the index of the starting point.
%
%    Output, real X, the starting point.
%
  if ( i == 1 )
    x = -1.0;
  elseif ( i == 2 )
    x =  0.5;
  elseif ( i == 3 )
    x =  2.0;
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P03_START - Fatal error!\n' );
    fprintf ( 1, '  Illegal starting point index = %d\n', i );
    error ( 'P03_START - Fatal error!' );
  end

  return
end


%int2zstr - Convert integer to zero-padded string.
%
%  USAGE
%
%    s = int2zstr(n,digits)
%
%    n              integer to convert
%    digits         optional total number of digits
%

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

function s = int2zstr(n,digits)

% Check number of parameters
if nargin < 1,
  error('Incorrect number of parameters (type ''help wrap'' for details).');
end

% Convert to string
s = int2str(n);

% Pad if necessary
if nargin < 2, return; end
l = digits-length(s);
if l <= 0, return; end
s = [ones(1,l)*'0' s];


function chrpak_test067 ( )

%*****************************************************************************80
%
%% TEST067 tests I4_TO_XXDECODE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 April 2011
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST067\n' );
  fprintf ( 1, '  I4_TO_XXDECODE: I => XXDECODE character\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The XXDECODE alphabet\n' );
  fprintf ( 1, '\n' );

  fprintf ( 1, '    "' );
  for i4 = 1 : 64
    c = i4_to_xxdecode ( i4 );
    fprintf ( 1, '%c', c );
  end
  fprintf ( 1, '"\n' );

  return
end


function count = persistent_variables(n)
    if nargin == 0
        n = 1;
    end

    persistent acc;
    if isempty(acc)
        acc = 1;
    else
        acc = acc + n;
    end
    count = acc;
end