function [outputStruct]=febioStructTemplate(varargin)

% function [outputStruct]=febioStructTemplate(inputStruct)
% ------------------------------------------------------------------------
% This function creates a template for the febio_spec structure for FEBio.
% This structure is intended to be converted to an XML file using
% |febioStruct2xml|.
%
%
% Change log:
% 2020/12/01: KMM Changed to use febio_spec 3.0 by default
% 2021/04/29: KMM Removed strain energy output as this is not available for
% all materials (e.g. viscoelastic materials).
% 2023/03/06: KMM Updating for FEBio spec 4.0.
%
% To do:
% * Check if still plot_stride is still needed
% * Check if both 0 and 1 and "symemtric" and presumably
% "assymetric" are options for the solver
% * No documentation for check_zero_diagonal
%

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

%%

switch nargin
    case 0
        inputStruct=[];
    case 1
        inputStruct=varargin{1};
    otherwise
        error('Wrong number of input arguments');
end

%% Check for old FEBio version (febio2)

if contains(lower(getFEBioPath),'febio2')
    [outputStruct]=febioStructTemplate_v2p5(inputStruct);
elseif contains(lower(getFEBioPath),'febio3')
    [outputStruct]=febioStructTemplate_v3p0(inputStruct);
    return
end

%% Set febio_spec version
febio_spec.ATTR.version='4.0';

%% Module section
febio_spec.Module.ATTR.type='solid'; %Use default set

%% Control section

febio_spec.Control.analysis='STATIC';
febio_spec.Control.time_steps=10;
febio_spec.Control.step_size=0.1;

febio_spec.Control.plot_zero_state=1;
febio_spec.Control.plot_range=[0,-1];
febio_spec.Control.plot_level='PLOT_MAJOR_ITRS';
febio_spec.Control.plot_stride=1;
febio_spec.Control.output_level='OUTPUT_MAJOR_ITRS';

febio_spec.Control.adaptor_re_solve=1;

febio_spec.Control.time_stepper.ATTR.type='default';
febio_spec.Control.time_stepper.max_retries=5;
febio_spec.Control.time_stepper.opt_iter=6;
febio_spec.Control.time_stepper.dtmin=0.01;
febio_spec.Control.time_stepper.dtmax=0.1;
febio_spec.Control.time_stepper.aggressiveness=0;
febio_spec.Control.time_stepper.cutback=0.5;
febio_spec.Control.time_stepper.dtforce=0;

febio_spec.Control.solver.ATTR.type='solid';
febio_spec.Control.solver.symmetric_stiffness=1;%'symmetric';
febio_spec.Control.solver.equation_scheme='staggered';
febio_spec.Control.solver.equation_order='default';
febio_spec.Control.solver.optimize_bw=0;
febio_spec.Control.solver.lstol=0.9;

febio_spec.Control.solver.lsmin=0.01;
febio_spec.Control.solver.lsiter=5;

febio_spec.Control.solver.max_refs=25;
febio_spec.Control.solver.check_zero_diagonal=0;
febio_spec.Control.solver.zero_diagonal_tol=0;
febio_spec.Control.solver.force_partition=0;
febio_spec.Control.solver.reform_each_time_step=1;
febio_spec.Control.solver.reform_augment=0;
febio_spec.Control.solver.diverge_reform=1;
febio_spec.Control.solver.min_residual=1e-20;
febio_spec.Control.solver.max_residual=0;
febio_spec.Control.solver.dtol=0.001;
febio_spec.Control.solver.etol=0.01;
febio_spec.Control.solver.rtol=0;
febio_spec.Control.solver.rhoi=0;
febio_spec.Control.solver.alpha=1;
febio_spec.Control.solver.beta=0.25;
febio_spec.Control.solver.gamma=0.5;
febio_spec.Control.solver.logSolve=0;
febio_spec.Control.solver.arc_length=0;
febio_spec.Control.solver.arc_length_scale=0;

febio_spec.Control.solver.qn_method.ATTR.type='BFGS';
febio_spec.Control.solver.qn_method.max_ups=0; %Default 10
febio_spec.Control.solver.qn_method.max_buffer_size=0;
febio_spec.Control.solver.qn_method.cycle_buffer=1;
febio_spec.Control.solver.qn_method.cmax=1e5;

%% Globals section

febio_spec.Globals.Constants.R=8.314e-6;
febio_spec.Globals.Constants.T=298;
febio_spec.Globals.Constants.Fc=96485e-9;

%% Material section

%% LoadData section
% febio_spec.LoadData.load_controller{1}.ATTR.id=1;
% febio_spec.LoadData.load_controller{1}.ATTR.type='loadcurve';
% febio_spec.LoadData.load_controller{1}.interpolate='LINEAR';
% febio_spec.LoadData.load_controller{1}.extend='CONSTANT';
% febio_spec.LoadData.load_controller{1}.points.pt.VAL=[0 0; 1 1];

%% Output section

% Plot file
febio_spec.Output.plotfile.ATTR.type='febio';
febio_spec.Output.plotfile.var{1}.ATTR.type='displacement';
febio_spec.Output.plotfile.var{2}.ATTR.type='stress';
febio_spec.Output.plotfile.var{3}.ATTR.type='relative volume';
febio_spec.Output.plotfile.var{4}.ATTR.type='reaction forces';
febio_spec.Output.plotfile.var{5}.ATTR.type='contact pressure';
febio_spec.Output.plotfile.compression=0;

%% Fill in missing if input structure is provided

switch nargin
    case 0 %Make output the full default
        outputStruct=febio_spec;
    case 1 %Make output by complementing input with default
        [outputStruct]=structComplete(inputStruct,febio_spec,1); %Complement provided with default if missing
end

%%
% _*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 [data,times] = fiff_read_raw_segment(raw,from,to,sel)
%
% [data,times] = fiff_read_raw_segment(raw,from,to,sel)
%
% Read a specific raw data segment
%
% raw    - structure returned by fiff_setup_read_raw
% from   - first sample to include. If omitted, defaults to the
%          first sample in data
% to     - last sample to include. If omitted, defaults to the last
%          sample in data
% sel    - optional channel selection vector
%
% data   - returns the data matrix (channels x samples)
% times  - returns the time values corresponding to the samples (optional)
%

%
%   Author : Matti Hamalainen, MGH Martinos Center
%   License : BSD 3-clause
%
%   Revision 1.9  2007/11/22 05:04:25  msh
%   Fixed help text and some error checking
%
%   Revision 1.8  2006/04/23 15:29:40  msh
%   Added MGH to the copyright
%
%   Revision 1.7  2006/04/21 22:11:34  msh
%   Times calculation needed casting to double
%
%   Revision 1.6  2006/04/21 22:03:43  msh
%   Fixed time limit output.
%
%   Revision 1.5  2006/04/21 16:17:48  msh
%   Added handling of CTF compensation
%
%   Revision 1.4  2006/04/21 15:11:56  msh
%   Made the debug output optional.
%
%   Revision 1.3  2006/04/21 14:43:59  msh
%   Report projection operators.
%   Some more checks in raw data reading.
%
%   Revision 1.2  2006/04/21 14:23:16  msh
%   Further improvements in raw data reading
%
%

me='MNE:fiff_read_raw_segment';

if nargin == 3
    sel = [];
elseif nargin == 2
    to  = raw.last_samp;
    sel = [];
elseif nargin == 1
    from = raw.first_samp;
    to   = raw.last_samp;
    sel  = [];
elseif nargin ~= 4
    error(me,'Incorrect number of arguments');
end
%
%  Initial checks
%
from = double(from);
to   = double(to);
if from < raw.first_samp
    from = raw.first_samp;
end
if to > raw.last_samp
    to = raw.last_samp;
end
%
if from > to
    error(me,'No data in this range');
end
fprintf(1,'Reading %d ... %d  =  %9.3f ... %9.3f secs...', ...
    from,to,from/raw.info.sfreq,to/raw.info.sfreq);
%
%  Initialize the data and calibration vector
%
nchan = raw.info.nchan;
dest  = 1;
cal   = diag(raw.cals);
%
if isempty(sel)
    data = zeros(nchan,to-from+1);
    if isempty(raw.proj) && isempty(raw.comp)
        mult = [];
    else
        if isempty(raw.proj)
            mult = raw.comp*cal;
        elseif isempty(raw.comp)
            mult = raw.proj*cal;
        else
            mult = raw.proj*raw.comp*cal;
        end
    end
else
    data = zeros(length(sel),to-from+1);
    if isempty(raw.proj) && isempty(raw.comp)
        mult = [];
        cal  = diag(raw.cals(sel));
    else
        if isempty(raw.proj)
            mult = raw.comp(sel,:)*cal;
        elseif isempty(raw.comp)
            mult = raw.proj(sel,:)*cal;
        else
            mult = raw.proj(sel,:)*raw.comp*cal;
        end
    end
end
do_debug=false;
if ~isempty(cal)
    cal = sparse(cal);
end
if ~isempty(mult)
    mult = sparse(mult);
end

if isempty(fopen(raw.fid))
   fid = fopen(raw.info.filename,'rb','ieee-be');
   if (fid < 0)
      error(me,'Cannot open file %s',raw.info.filename);
   end
else
   fid = raw.fid;
end

for k = 1:length(raw.rawdir)
    this = raw.rawdir(k);
    %
    %  Do we need this buffer
    %
    if this.last > from
        if isempty(this.ent)
            %
            %  Take the easy route: skip is translated to zeros
            %
            if do_debug
                fprintf(1,'S');
            end
            doing_whole = false;
            if isempty(sel)
                one = zeros(nchan,this.nsamp);
            else
                one = zeros(length(sel),this.nsamp);
            end
        else
            tag = fiff_read_tag(fid,this.ent.pos);
            %
            %   Depending on the state of the projection and selection
            %   we proceed a little bit differently
            %
            if isempty(mult)
                if isempty(sel)
                    one = cal*double(reshape(tag.data,nchan,this.nsamp));
                else
                    one = double(reshape(tag.data,nchan,this.nsamp));
                    one = cal*one(sel,:);
                end
            else
                one = mult*double(reshape(tag.data,nchan,this.nsamp));
            end
        end
        %
        %  The picking logic is a bit complicated
        %
        if to >= this.last && from <= this.first
            %
            %    We need the whole buffer
            %
            first_pick = 1;
            last_pick  = this.nsamp;
            if do_debug
                fprintf(1,'W');
            end
        elseif from > this.first
            first_pick = from - this.first + 1;
            if to < this.last
                %
                %   Something from the middle
                %
                last_pick = this.nsamp + to - this.last;
                if do_debug
                    fprintf(1,'M');
                end
            else
                %
                %   From the middle to the end
                %
                last_pick = this.nsamp;
                if do_debug
                    fprintf(1,'E');
                end
            end
        else
            %
            %    From the beginning to the middle
            %
            first_pick = 1;
            last_pick  = to - this.first + 1;
            if do_debug
                fprintf(1,'B');
            end
        end
        %
        %   Now we are ready to pick
        %
        picksamp = last_pick - first_pick + 1;
        if picksamp >= 0
            data(:,dest:dest+picksamp-1) = one(:,first_pick:last_pick);
            dest = dest + picksamp;
        end
    end
    %
    %   Done?
    %
    if this.last >= to
        fprintf(1,' [done]\n');
        break;
    end
end

fclose(fid);

if nargout == 2
    times = [ from:to ];
    times = double(times)/raw.info.sfreq;
end

return;

end


function sL = Laue(s)
% return the corresponding Laue group

% maybe we have alread computed the Laue group
if ~isempty(s.LaueRef)

  sL = s.LaueRef;

elseif s.isLaue % if it is already a Laue group then there is nothing to do

  sL = s;

else % in the meantime isLaue has computed the Laue group :)

  sL = s.LaueRef;

end


function prob = brunbirthday ( nw )

% For this script the default configuration should be 'ithaca_2009b

% nw is the number of workers use 4 as the default

  if nargin < 1 || nw > 4 || nw < 1; nw = 4; end

% Since the batch command is inside a function, we wait for the job to
% complete before retrieving the results and setting the return value
% of prob.
% If you want to continue working in Matlab while the job runs, issue the
% my_job = batch(..); from the Command Window. Check for 'finished'
% by using state = get(my_job,'state')

% Create a batch job for the birthday simulation
%
  my_job = batch ( 'birthdayscript', ...
    'FileDependencies', 'birthday.m', ...
    'matlabpool', nw );
%
% birthdayscript.m uses a parfor loop (matlabpool)
% The job requires one worker to run the script and two
% additional workers for a matlabool
%
% Wait for the job to complete
%
  wait ( my_job );
%
%  Retrieve output from the job
%
  results = getAllOutputArguments(my_job);
  prob = results{1}.prob;
%
% If the cell array results is empty (say 1 x 0), the script submitted
% by 'batch' has failed.

% Could alternatively use the load command
% prob = load(my_job, 'prob')

%
% Clean up after the job
%
  destroy(my_job);


function [vertices, faces, facevertexcdata, renderer] = u3d_pre_surface(ax)
%U3D_PRE_SURFACE    Preprocess surface output to u3d.
%    U3D_PRE generates the input for the MESH_TO_LATEX function from
%    Alexandre Gramfort from your surface-graphs. The surface graphs 3d-model can be
%    displayed in u3d - format in pdf or if you don't delete the u3d-files
%    which are generated by MESH_TO_LATEX you can use deepview from
%    righthemisphere(http://www.righthemisphere.com/products/client-products/deep-view)
%    to embed the modell in Microsoft-Office products (Word, Excel, PowerPoint).
%
% usage
%   [vertices, faces, facevertexcdata] = U3D_PRE_SURFACE
%   [vertices, faces, facevertexcdata] = U3D_PRE_SURFACE(h)
%
% optional input
%   ax = axes object handle
%
% output
%   vertices = row vectors of point positions, as row cell array
%              for multiple surfaces
%            = {1 x #surfaces}
%            = {[#vertices x 3], ... }
%   faces = for each surface triangle face, indices of its 3 vertices,
%           these indices refer to the columns of matrix vertices,
%           as row cell array for multiple surfaces
%         = {1 x #surfaces}
%         = {[#faces x 3], ... }
%   facevertexcdata = RGB color information at each vertex,
%                     as row cell array for multiple surfaces
%                   = {1 x #surfaces}
%                   = {[#vertices x 3], ... }
%
% See also fig2idtf, u3d_pre_line, u3d_pre_patch, u3d_pre_quivergroup,
%          u3d_pre_contourgroup.
%
% File:      u3d_pre_surface.m
% Original Author: Sven Koerner, koerner(underline)sven(add)gmx.de
% Author:    Ioannis Filippidis, jfilippidis@gmail.com (added support for multiple surfaces)
% Date:      2012.06.10 -
% Language:  MATLAB R2012a
% Purpose:   preprocess surface children of axes for u3d export
% Copyright:
%
% License to use and modify this code is granted freely to all interested,
% as long as the original author is referenced and attributed as such.
% The original author maintains the right to be solely associated with this work.

%% input
if nargin < 1
    sh = findobj('type', 'surface');
else
    objs = get(ax, 'Children');
    sh = findobj(objs, 'type', 'surface');
end

if isempty(sh)
    disp('No surfaces found.');
    vertices            = [];
    faces               = [];
    facevertexcdata     = [];
    renderer = [];
    return
end

%% process each surface
N = size(sh, 1); % number of surfaces
vertices = cell(1, N);
faces = cell(1, N);
facevertexcdata = cell(1, N);
renderer = cell(1, N);
for i=1:N
    disp(['     Preprocessing surface No.', num2str(i) ] );
    h = sh(i, 1);

    [v, f, fvx, r] = single_surf_preprocessor(h);

    vertices{1, i} = v;
    faces{1, i} = f;
    facevertexcdata{1, i} = fvx;
    renderer{1, i} = r;
end

function [vertices, faces, facevertexcdata, renderer] = single_surf_preprocessor(h)
%% shading -> renderer in adobe reader
edgecolor = get(h, 'EdgeColor');
if strcmp(edgecolor, 'none')
    renderer = 'Solid';
else
    renderer = 'SolidWireframe';
end

%% get defined data-points
X = get(h, 'XData');
Y = get(h, 'YData');
Z = get(h, 'ZData');

realcolor = get_surf_color(h);

[faces, vertices, facevertexcdata] = surf2patch(X, Y, Z, realcolor, 'triangles');

%% remove nan vertices and faces
% remove faces using at least one vertex with some nan coordinate
nan_vertices = any(isnan(vertices), 2);
nan_faces = nan_vertices(faces);
nan_faces = any(nan_faces, 2);
nan_faces = ~nan_faces;
faces = faces(nan_faces, :);

% vertices with nan are not used anymore
% just make them contain numbers
% DO NOT REMOVE them! This would destroy face indexing
vertices(isnan(vertices) ) = 0;
vertices = vertices.';

%% surface concatenation (obsolete - although it reduces file size)
%{
[n, m] = size(X, 1);
Vi = n *m; % number of vertices
Fi = 2 *(n-1) *(m -1); % number of faces, due to wraping (closing of the surface)
disp(['     Object Vertex # = ', num2str(Vi) ] )
disp(['     Object Face # = ', num2str(Fi) ] )

tempfvc.faces = tempfvc.faces +V; % shift to account for previous vertices

% append to previous
fvc.vertices = [fvc.vertices; tempfvc.vertices];
fvc.faces = [fvc.faces; tempfvc.faces];
fvc.facevertexcdata = [fvc.facevertexcdata; tempfvc.facevertexcdata];

F = size(faces, 1);
[C1, C2] = size(facevertexcdata);

V = size(fvc.vertices, 1); %V = V +Vi;

disp(['     Vertex # = ', num2str(V) ] )
disp(['     Face # = ', num2str(F) ] )
disp(['     Vertex Colors = ', num2str(C1), ' x ', num2str(C2) ] )
%}

function [realcolor] = get_surf_color(h)
% texture mapping ?
facecolor = get(h, 'FaceColor');
if strcmp(facecolor, 'texturemap')
    realcolor = [];
    return
end

% texturemapping is when CData is an image and has different size than
% XData and the number of faces, so it is not treated here yet.

%% CData
cdata = get(h, 'CData');
k = size(cdata, 3);

% true color ?
if k == 3
    disp('CData is already True Color.')
    cdata(isnan(cdata) ) = 1;
    realcolor = cdata;
    return
end

% not indexed colors ?
if k ~= 1
    error('u3dsurf:cdata', 'size(CData, 3) \notin {1, 3}')
end

%% indexed color to RGB true color
ax = get(h, 'Parent');
realcolor = scaled_ind2rgb(cdata, ax);

function [realcolor] = scaled_ind2rgb(cdata, ax)
[n, m] = size(cdata);
cdata = double(cdata);

cmap = colormap(ax);
nColors = size(cmap, 1);
[cmin, cmax] = caxis(ax);

idx = (cdata -cmin) / (cmax -cmin) *nColors;
idx = ceil(idx);
idx(idx < 1) = 1;
idx(idx > nColors) = nColors;

%% handle nans in idx
nanmask = isnan(idx);
idx(nanmask) = 1; %temporarily replace w/ a valid colormap index

%% realcolor and output
realcolor = zeros(n, m);
for i = 1:3
    c = cmap(idx, i);
    c = reshape(c, n, m);
    realcolor(:, :, i) = c;
end


function [] = printLabeledList(fid, list, labels, perLine, indent)
% Output the values in list with labels for a specified number of values per line
count = 0;
fprintf(fid, '%s[ ', indent);
for k = 1:length(list)
    fprintf(fid, '%g(%s) ', list(k), labels{k});
    count = count + 1;
    if mod(count, perLine) == 0
        fprintf(fid, '\n%s', indent);
        count = 0;
    end
end
fprintf(']\n');


function[]=flipmap
%FLIPMAP Flips the current colormap upside-down.
%   _________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2002, 2004 J.M. Lilly --- type 'help jlab_license' for details
ZZmap=colormap;
colormap(flipud(ZZmap));
clear ZZmap


function r8mat_print ( m, n, a, title )

%*****************************************************************************80
%
%% R8MAT_PRINT prints an R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows in A.
%
%    Input, integer N, the number of columns in A.
%
%    Input, real A(M,N), the matrix.
%
%    Input, string TITLE, a title to be printed.
%
  r8mat_print_some ( m, n, a, 1, 1, m, n, title );

  return
end


function tests = test_imEuler1dEstimate(varargin)
%TEST_IMEULER1DESTIMATE  One-line description here, please.
%
%   output = test_imEuler1dEstimate(input)
%
%   Example
%   test_imEuler1dEstimate
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2010-10-18,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRA - Cepia Software Platform.

tests = functiontests(localfunctions);

function testHoriz(testCase)

img = logical([0 1 1 1 0 0]);
exp = 1;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([0 1 1 0 1 0]);
exp = 2;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([0 0 1 1 1 1]);
exp = .5;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([1 1 1 0]);
exp = .5;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([1 1 1 1 1 1]);
exp = 0;
assertEqual(testCase, exp, imEuler1dEstimate(img));

function testVertical(testCase)

img = logical([0 1 1 1 0 0])';
exp = 1;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([0 1 1 0 1 0]');
exp = 2;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([0 0 1 1 1 1]');
exp = .5;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([1 1 1 0]');
exp = .5;
assertEqual(testCase, exp, imEuler1dEstimate(img));

img = logical([1 1 1 1 1 1]');
exp = 0;
assertEqual(testCase, exp, imEuler1dEstimate(img));


function test_suite = test_graphRadius
%TEST_GRAPHRADIUS  One-line description here, please.
%
%   output = test_graphRadius(input)
%
%   Example
%   testGraphRadius
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-05-19,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

test_suite = functiontests(localfunctions);

function testGraph02(testCase) %#ok<*DEFNU>

[nodes, edges] = createTestGraph02;
r = graphRadius(nodes, edges);

exp = 3;
testCase.assertEqual(exp, r);


function hb_to_msm_test ( )

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

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

  return
end
function timestamp ( )

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

  return
end


function r = isnan(u)
%ISNAN        Array of 1's for NaN components
%
%   r = isnan(u)
%

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

  r = reshape( any(isnan(u.r),2) | any(isnan(u.s),2) , u.size );


function l4_uniform_test ( )

%*****************************************************************************80
%
%% L4_UNIFORM_TEST tests L4_UNIFORM.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 May 2008
%
%  Author:
%
%    John Burkardt
%

  fprintf ( 1, '\n' );
  fprintf ( 1, 'L4_UNIFORM_TEST\n' );
  fprintf ( 1, '  L4_UNIFORM computes pseudorandom logical values.\n' );

  seed = 123456789;

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

  for i = 1 : 10
    [ value, seed ] = l4_uniform ( seed );
    fprintf ( 1, '  %8d  %d\n', i, value );
  end

  return
end


function table = i4mat_data_read ( input_filename, m, n )

%*****************************************************************************80
%
%% I4MAT_DATA_READ reads data from an I4MAT file.
%
%  Discussion:
%
%    An I4MAT is an array of I4's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILENAME, the name of the input file.
%
%    Input, integer M, N, the number of rows and columns in the data.
%
%    Output, integer TABLE(M,N), the point coordinates.
%
  table = [];
%
%  Build up the format string for reading M real numbers.
%
  string = ' ';

  for i = 0 : m
    string = strcat ( string, ' %d' );
  end

  input_unit = fopen ( input_filename );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4MAT_DATA_READ - Error!\n' );
    fprintf ( 1, '  Could not open the input file.\n' );
    error ( 'I4MAT_DATA_READ - Error!' );
    return;
  end

  i = 0;

  while ( i < n )

    line = fgets ( input_unit );

    if ( line == -1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'I4MAT_DATA_READ - Error!\n' );
      fprintf ( 1, '  End of input while reading data.\n' );
      error ( 'I4MAT_DATA_READ - Error!' );
    end

    if ( line(1) == '#' )

    elseif ( s_len_trim ( line ) == 0 )

    else

      [ x, count ] = sscanf ( line, string );

      if ( count == m )
        i = i + 1;
        table(1:m,i) = x(1:m);
      end

    end

  end

  fclose ( input_unit );

  return
end


function problem = EmptyProblem()
%EmptyProblem - Create an empty problem
% Create an empty problem with all the required fields

% Basic elements (these are mandatory)
problem.type= 'none'; % What kind of problem is this?
problem.N = 0; % How many measurements this problem has?
problem.outliers = []; % Among the measurements, what are the indices of the outliers?
problem.priors = [];  % Amont the measurements, what are the indices of the element that will never be outliers?
problem.dof = 0; % Degrees of freedom of the noise process

% Problem specific data
% Add here any problem specific field ...

problem.time = now;
% Unique identifier
problem.uuid = java.util.UUID.randomUUID.toString;
end


function mm_io_test05 ( )

%*****************************************************************************80
%
%% MM_IO_TEST05 tests MM_SIZE_WRITE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2008
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'MM_IO_TEST05:\n' );
  fprintf ( 1, '  MM_SIZE_WRITE writes the size line \n' );
  fprintf ( 1, '  to a Matrix Market file.\n' );

  output_filename = 'mm_io_test05.mm';

  id = '%%MatrixMarket';
  type = 'matrix';
  rep = 'array';
  field = 'real';
  symm = 'general';

  nrow = 5;
  ncol = 4;
  nnz = 13;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here is the size information we intend to write\n' );
  fprintf ( 1, '  to a Matrix Market file:\n' );
  fprintf ( 1, '\n' );

  mm_size_print ( output_filename, rep, symm, nrow, ncol, nnz );

  output_unit = fopen ( output_filename, 'w' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MM_IO_TEST05 - Fatal error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'MM_IO_TEST05 - Fatal error!' );
  end

  mm_header_write ( output_unit, id, type, rep, field, symm );

  mm_comment_write ( output_unit, ' ' );
  mm_comment_write ( output_unit, 'This is the file mm_io_test05.mm' );
  mm_comment_write ( output_unit, ' ' );
  mm_comment_write ( output_unit, 'It is a partial Matrix Market file,' );
  mm_comment_write ( output_unit, 'containing a header line, comments, and sizes.' );
  mm_comment_write ( output_unit, ' ' );

  mm_size_write ( output_unit, rep, nrow, ncol, nnz );

  fclose ( output_unit );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'MM_IO_TEST05:\n' );
  fprintf ( 1, '  The partial MM file "%s" containing \n', output_filename );
  fprintf ( 1, '  the header, comments, and sizes has been created.\n' );
  fprintf ( 1, '\n' );

  return
end


function [xdata,ydata] = jdfigure2data(figurename)
%%%derive the xdata and ydata from a figure(2x dimension)

%%Input:
%%%%----figurename       :      name of the figure      [required]

%%Output:
%%%%----xdata            :      data on x axis
%%%%----ydata            :      data on y axis
%%=====================================================================
    open(figurename);
    h_line = get(gca,'Children');
    xdata = get(h_line,'Xdata');
    ydata = get(h_line,'Ydata');
end


function chrpak_test065 ( )

%*****************************************************************************80
%
%% TEST065 tests I4_TO_UNARY.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 June 2007
%
%  Author:
%
%    John Burkardt
%
  test_num = 3;

  i4_test = [ -5, 0, 7 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST065\n' );
  fprintf ( 1, '  I4_TO_UNARY converts an integer to unary.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '        I4     UNARY\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num

    i4 = i4_test(test);

    s = i4_to_unary ( i4 );

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

  end

  return
end


function masks = char2img( strings, h, pad )
% Convert ascii text to a binary image using pre-computed templates.
%
% Input strings can only contain standard characters (ascii character
% 32-126). First time char2img() is ever called with a given height h,
% txt2img() is used to create a template for each ascii character. All
% subsequent calls to to char2img() with the given height are very fast as
% the pre-computed templates are used and no display/screen capture is
% needed.
%
% USAGE
%  masks = char2img( strings, h, [pad] )
%
% INPUTS
%  strings  - {1xn} text string or cell array of text strings to convert
%  h        - font height in pixels
%  pad      - [0] amount of extra padding between chars
%
% OUTPUTS
%  masks    - {1xn} binary image masks of height h for each string
%
% EXAMPLE
%  mask=char2img('hello world',50); im(mask{1})
%  mask=char2img(num2str(pi),35); im(mask{1})
%
% See also TXT2IMG
%
% Piotr's Image&Video Toolbox      Version 2.65
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

% load or create character templates (or simply store persistently)
persistent chars h0
if(isempty(h0) || h0~=h)
  pth=fileparts(mfilename('fullpath'));
  fName=sprintf('%s/private/char2img_h%03i.mat',pth,h); h0=h;
  if(exist(fName,'file')), load(fName); else
    chars=char(32:126); chars=num2cell(chars);
    chars=txt2img(chars,h,{'Interpreter','none'});
    save(fName,'chars');
  end
end
% add padding to chars
if(nargin<3 || isempty(pad)), pad=0; end
charsPad=chars; if(pad), pad=ones(h,pad,'uint8');
  for i=1:length(chars), charsPad{i}=[pad chars{i} pad]; end; end
% create actual string using templates
if(~iscell(strings)), strings={strings}; end
n=length(strings); masks=cell(1,n);
for s=1:n, str=strings{s};
  str(str<32 | str>126)=32; str=uint8(str-31);
  M=[charsPad{str}]; masks{s}=M;
end


%% MD_FAST_RUN is a script to run MD_FAST with prescribed input.
%
  filename = 'md_fast_output.txt';

  delete ( filename );

  diary ( filename );

  nd = 3;
  np = 500;
  step_num = 500;

  md_fast ( nd, np, step_num );

  diary ( 'off' );

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


function fd_to_tec ( prefix )

%*****************************************************************************80
%
%% FD_TO_TEC converts an FD model into a TECPLOT ASCII file.
%
%  Usage:
%
%    fd_to_tec ( 'prefix' )
%
%    where 'prefix' is the common prefix for the FD files:
%
%    * 'prefix'_nodes.txt,    the node coordinates.
%    * 'prefix'_values.txt,   the values defined at each node.
%
%    reads the data from these files,
%    creates a Delaunay triangulation or tetrahedralization of the data,
%    creates an equivalent TECPLOT ASCII file named 'prefix'.dat
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 March 2010
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD_TO_TEC:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read an FD model consisting of:\n' );
  fprintf ( 1, '  * a nodes file (2D or 3D),\n' );
  fprintf ( 1, '  * a values file (1 or more values at each node);\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Write an equivalent TECPLOT ASCII "dat" file.\n' );
%
%  Get the file prefix.
%
  if ( nargin < 1 )

    fprintf ( 1, '\n' );
    prefix = input ( 'Enter the file prefix:' );

  end
%
%  Create the filenames.
%
  node_filename = strcat ( prefix, '_nodes.txt' );
  element_filename = strcat ( prefix, '_elements.txt' );
  value_filename = strcat ( prefix, '_values.txt' );
  tec_filename = strcat ( prefix, '.dat' );
%
%  Read the FD data (node coordinates, node values).
%
  [ dim_num, node_num ] = r8mat_header_read ( node_filename );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The spatial dimension is %d\n', dim_num );
  fprintf ( 1, '  The number of nodes is %d\n', node_num );

  node_coord = r8mat_data_read ( node_filename, dim_num, node_num );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read node data from "%s".\n', node_filename );

  [ value_num, node_num2 ] = r8mat_header_read ( value_filename );

  if ( node_num2 ~= node_num )
    fprintf ( 1, '\n' );
    fprintf ( 1, ...
      '  The number of nodes in the node coordinate file is %d.\n', ...
      node_num );
    fprintf ( 1, ...
      '  but the number in the node data file is %d\n', node_num2 );
    fprintf ( 1, '  Because of this, no node data will be stored.\n' );
    value_num = 0;
  else
    fprintf ( 1, '  The number of values per node is %d\n', value_num );
    values = r8mat_data_read ( value_filename, value_num, node_num );
    fprintf ( 1, '  Read node value data from "%s".\n', value_filename );
  end
%
%  Triangulate/Tetrahedralize the data.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Calling DELAUNAYN to create elements.\n' );

  element_node = delaunayn ( node_coord' );
  element_node = element_node';
  [ element_order, element_num ] = size ( element_node );

  fprintf ( 1, '  Number of elements is %d\n', element_num );

  i4mat_write ( element_filename, element_order, element_num, element_node );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Wrote element data to "%s"\n', element_filename );
%
%  Write the TEC data.
%
  tec_write ( tec_filename, dim_num, node_num, element_num, ...
    element_order, value_num, node_coord, element_node, values );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Wrote the TEC data to "%s".\n', tec_filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD_TO_TEC\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function value = ch_is_alpha ( c )

%*****************************************************************************80
%
%% CH_IS_ALPHA returns TRUE if C is an alphabetic character.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, a character to check.
%
%    Output, logical VALUE is TRUE if C is an alphabetic character.
%
  FALSE = 0;
  TRUE = 1;

  if ( ( 'a' <= c & c <= 'z' ) | ...
       ( 'A' <= c & c <= 'Z' ) )
    value = TRUE;
  else
    value = FALSE;
  end

  return
end
function [ dim_num, node_num, element_num, element_order, value_num, ...
  node_coord, element_node, values ] = fem_read ( node_filename, ...
  element_filename, value_filename )

%*****************************************************************************80
%
%% FEM_READ reads data files associated with a finite element solution.
%
%  Discussion:
%
%    This program reads the node, element and data files that define
%    a finite element geometry and data based on that geometry:
%    * a set of nodes,
%    * a set of elements based on those nodes,
%    * a set of data values associated with each node.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string NODE_FILENAME, the name of the node coordinate
%    file.  If this argument is not supplied, it will be requested.  If the interactive
%    response is blank, or otherwise defective, then the program terminates.
%
%    Input, string ELEMENT_FILENAME, the name of the element file.  If
%    this argument is not supplied, it will be requested.  If the interactive
%    response is blank, then the program will assume that no element information
%    is to be supplied.  (But the node coordinates must be available and may be plotted.
%    And if a node data file is supplied, then the data can be plotted against
%    the node coordinates without using any finite element structure.)
%
%    Input, string VALUES_FILENAME, the name of the node data file.  If
%    this argument is not supplied, it will be requested.  If the interactive
%    response is blank, then the program will assume that no node data information
%    is to be supplied.  (But the node coordinates will be available and may be plotted.
%    And if an element file is supplied, then the elements can also be displayed.)
%
%    Output, integer DIM_NUM, the spatial dimension, inferred from the
%    "shape" of the data in the node file.
%
%    Output, integer NODE_NUM, the number of nodes, inferred from the
%    number of lines of data in the node coordinate file.
%
%    Output, integer ELEMENT_NUM, the number of elements, inferred from the
%    number of lines of data in the element file.
%
%    Output, integer ELEMENT_ORDER, the order of the elements, inferred from
%    the number of items in the first line of the element file.
%
%    Output, integer VALUE_NUM, the number of data items per node,
%    inferred from the number of items in the first line of the node data file.
%
%    Output, real NODE_COORD(DIM_NUM,NODE_NUM), the coordinates of nodes.
%
%    Output, integer ELEMENT_NODE(ELEMENT_ORDER,ELEMENT_NUM);
%    the global index of local node I in element J.
%
%    Output, real VALUES(VALUE_NUM,NODE_NUM), the data values associated
%    with each node.
%

%
%  Read the node coordinate file.
%
  [ dim_num, node_num ] = r8mat_header_read ( node_filename );

  [ element_order, element_num ] = i4mat_header_read ( element_filename );

  [ value_num, node_num2 ] = r8mat_header_read ( value_filename );

  if ( node_num2 ~= node_num )
    fprintf ( 1, '\n' );
    fprintf ( 1, ...
      '  The number of nodes in the node coordinate file is %d.\n', ...
      node_num );
    fprintf ( 1, ...
      '  but the number in the node data file is %d\n', node_num2 );
    fprintf ( 1, '  Because of this, no node data will be stored.\n' );
    value_num = 0;
  end

  node_coord = r8mat_data_read ( node_filename, dim_num, node_num );

  element_node = i4mat_data_read ( element_filename, element_order, ...
    element_num );

  values = r8mat_data_read ( value_filename, value_num, node_num );

  return
end
function column_num = file_column_count ( input_filename )

%*****************************************************************************80
%
%% FILE_COLUMN_COUNT counts the columns in the first line of a file.
%
%  Discussion:
%
%    The file is assumed to be a simple text file.
%
%    Most lines of the file are presumed to consist of COLUMN_NUM words,
%    separated by spaces.  There may also be some blank lines, and some
%    comment lines, which have a "#" in column 1.
%
%    The routine tries to find the first non-comment non-blank line and
%    counts the number of words in that line.
%
%    If all lines are blanks or comments, it goes back and tries to analyze
%    a comment line.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILENAME, the name of the file.
%
%    Output, integer COLUMN_NUM, the number of columns in the file.
%
  FALSE = 0;
  TRUE = 1;
%
%  Open the file.
%
  input_unit = fopen ( input_filename );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_COLUMN_COUNT - Error!\n' );
    fprintf ( 1, '  Could not open the file "%s".\n', input_filename );
    error ( 'FILE_COLUMN_COUNT - Error!' );
  end
%
%  Read one line, but skip blank lines and comment lines.
%  Use FGETL so we drop the newline character!
%
  got_one = FALSE;

  while ( 1 )

    line = fgetl ( input_unit );

    if ( line == -1 )
      break;
    end

    if ( s_len_trim ( line ) == 0 )

    elseif ( line(1) == '#' )

    else
      got_one = TRUE;
      break;
    end

  end

  fclose ( input_unit );

  if ( got_one == FALSE )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_COLUMN_COUNT - Warning!\n' );
    fprintf ( 1, '  The file does not seem to contain any data.\n' );
    column_num = -1;
    return;
  end

  column_num = s_word_count ( line );

  return
end
function filename = file_name_inc ( filename )

%*****************************************************************************80
%
% FILE_NAME_INC generates the next filename in a series.
%
%  Discussion:
%
%    It is assumed that the digits in the name, whether scattered or
%    connected, represent a number that is to be increased by 1 on
%    each call.  If this number is all 9's on input, the output number
%    is all 0's.  Non-numeric letters of the name are unaffected..
%
%    If the name is empty, then the routine stops.
%
%    If the name contains no digits, the empty string is returned.
%
%  Example:
%
%      Input            Output
%      -----            ------
%      'a7to11.txt'     'a7to12.txt'  (typical case.  Last digit incremented)
%      'a7to99.txt'     'a8to00.txt'  (last digit incremented, with carry.)
%      'a9to99.txt'     'a0to00.txt'  (wrap around)
%      'cat.txt'        ' '           (no digits in input name.)
%      ' '              STOP!         (error.)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 September 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string FILENAME, the string to be incremented.
%
%    Output, string FILENAME, the incremented string.
%
  lens = length ( filename );

  if ( lens <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_NAME_INC - Fatal error!\n' );
    fprintf ( 1, '  The input filename is empty.\n' );
    error ( 'FILE_NAME_INC - Fatal error!' );
  end

  change = 0;

  for i = lens : -1 : 1

    c = filename(i);

    if ( '0' <= c & c <= '8' )

      change = change + 1;

      c = c + 1;

      filename(i) = c;

      return

    elseif ( c == '9' )

      change = change + 1;

      c = '0';

      filename(i) = c;

    end

  end

  if ( change == 0 )
    filename = ' ';
  end

  return
end
function row_num = file_row_count ( input_filename )

%*****************************************************************************80
%
%% FILE_ROW_COUNT counts the number of row records in a file.
%
%  Discussion:
%
%    Each input line is a "RECORD".
%
%    The records are divided into three groups:
%
%    * BLANK LINES (nothing but blanks)
%    * COMMENT LINES (begin with a '#')
%    * DATA RECORDS (anything else)
%
%    The value returned by the function is the number of data records.
%
%    By the way, if the MATLAB routine FGETS is used, instead of
%    FGETL, then the variable LINE will include line termination
%    characters, which means that a blank line would not actually
%    have zero characters.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 December 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILENAME, the name of the input file.
%
%    Output, integer ROW_NUM, the number of rows found.
%
  input_unit = fopen ( input_filename );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_ROW_COUNT - Error!\n' );
    fprintf ( 1, '  Could not open the file "%s".\n', input_filename );
    error ( 'FILE_ROW_COUNT - Error!' );
  end

  blank_num = 0;
  comment_num = 0;
  row_num = 0;

  record_num = 0;

  while ( 1 )

    line = fgetl ( input_unit );

    if ( line == -1 )
      break;
    end

    record_num = record_num + 1;
    record_length = s_len_trim ( line );

    if ( record_length <= 0 )
      blank_num = blank_num + 1;
    elseif ( line(1) == '#' )
      comment_num = comment_num + 1;
    else
      row_num = row_num + 1;
    end

  end

  fclose ( input_unit );

  return
end
function i4mat_write ( output_filename, m, n, table )

%*****************************************************************************80
%
%% I4MAT_WRITE writes an I4MAT file.
%
%  Discussion:
%
%    An I4MAT is an array of I4's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the output filename.
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input, integer TABLE(M,N), the points.
%
%    Input, logical HEADER, is TRUE if the header is to be included.
%

%
%  Open the file.
%
  output_unit = fopen ( output_filename, 'wt' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4MAT_WRITE - Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'I4MAT_WRITE - Error!' );
  end
%
%  Write the data.
%
  for j = 1 : n
    for i = 1 : m
      fprintf ( output_unit, '  %12d', round ( table(i,j) ) );
    end
    fprintf ( output_unit, '\n' );
  end
%
%  Close the file.
%
  fclose ( output_unit );

  return
end
function table = r8mat_data_read ( input_filename, m, n )

%*****************************************************************************80
%
%% R8MAT_DATA_READ reads data from an R8MAT file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILENAME, the name of the input file.
%
%    Input, integer M, N, the number of rows and columns of data.
%
%    Output, real TABLE(M,N), the point coordinates.
%
  table = zeros ( m, n );
%
%  Build up the format string for reading M real numbers.
%
  string = ' ';

  for i = 0 : m
    string = strcat ( string, ' %f' );
  end

  input_unit = fopen ( input_filename );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_DATA_READ - Error!\n' );
    fprintf ( 1, '  Could not open the file.\n' );
    error ( 'R8MAT_DATA_READ - Error!' );
  end

  i = 0;

  while ( i < n )

    line = fgets ( input_unit );

    if ( line == -1 )
      break;
    end

    if ( line(1) == '#' )

    elseif ( s_len_trim ( line ) == 0 )

    else

      [ x, count ] = sscanf ( line, string );

      if ( count == m )
        i = i + 1;
        table(1:m,i) = x(1:m);
      end

    end

  end

  fclose ( input_unit );

  return
end
function [ m, n ] = r8mat_header_read ( input_filename )

%*****************************************************************************80
%
%% R8MAT_HEADER_READ reads the header from an R8MAT file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILENAME, the name of the input file.
%
%    Output, integer M, the spatial dimension.
%
%    Output, integer N, the number of points.
%
  m = file_column_count ( input_filename );

  if ( m <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  There was some kind of I/O problem while trying\n' );
    fprintf ( 1, '  to count the number of data columns in\n' );
    fprintf ( 1, '  the file %s.\n', input_filename );
  end

  n = file_row_count ( input_filename );

  if ( n <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  There was some kind of I/O problem while trying\n' );
    fprintf ( 1, '  to count the number of data rows in\n' );
    fprintf ( 1, '  the file %s\n', input_filename );
  end

  return
end
function iloc = s_alpha_last ( s )

%*****************************************************************************80
%
%% S_ALPHA_LAST returns the location of the last alphabetic character.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be searched.
%
%    Output, integer ILOC, the location of the last alphabetic
%    character in the string.  If there are no alphabetic
%    characters, ILOC is returned as -1.
%
  s_len = s_len_trim ( s );

  for i = s_len : -1 : 1
    if ( ch_is_alpha ( s(i) ) )
      iloc = i;
      return
    end
  end

  iloc = -1;

  return
end
function [ s, ierror ] = s_inc ( s )

%*****************************************************************************80
%
%% S_INC "increments" a string.
%
%  Discussion:
%
%    The routine tries to produce the next string, in dictionary order,
%    following the input value of a string.  Digits, spaces, and other
%    nonalphabetic characters are ignored.  Case is respected; in other
%    words, the case of every alphabetic character on input will be the
%    same on output.
%
%    The following error conditions can occur:
%
%      There are no alphabetic characters in the string.  No
%      incrementing is possible.
%
%      All alphabetic characters are equal to 'Z' or 'z'.  In this
%      case, an error value is returned, but the string is also "wrapped
%      around" so that all alphabetic characters are "A" or "a".
%
%    If the word "Tax" were input, the successive outputs would be
%    "Tay", "Taz", "Tba", "Tbb", ...  If the input word "January 4, 1989"
%    were input, the output would be "Januarz 4, 1989".
%
%    This routine could be useful when trying to create a unique file
%    name or variable name at run time.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character ( len = * ) S, the string whose
%    alphabetic successor is desired.
%
%    Output, character ( len = * ) S, if IERROR = 0,
%    S has been replaced by its successor.  If IERROR = 2,
%    S will be "wrapped around" so that all alphabetic
%    characters equal "A" or "a".
%
%    Output, integer IERROR, an error flag.
%    0, no error.
%    1, no alphabetic characters occur in the string.
%    2, all alphabetic characters are "Z" or "z".  S is wrapped around so
%       that all alphabetic characters are "A" or "a".
%
  ierror = 0;
  ilo = 1;
  ihi = s_len_trim ( s );
%
%  Find the last alphabetic character in the string.
%
  while ( 1 )

    iloc = s_alpha_last ( s(ilo:ihi) );
%
%  If there is no alphabetic character, we can't help.
%
    if ( iloc == 0 )
      ierror = 1;
      break;
    end

    if ( s(iloc) == 'Z' )

      s(iloc) = 'A';
      ihi = iloc - 1;

      if ( ihi <= 0 )
        ierror = 2;
        break;
      end

    elseif ( s(iloc) == 'z' )

      s(iloc) = 'a';
      ihi = iloc - 1;

      if ( ihi <= 0 )
        ierror = 2;
        break;
      end

    else

      s(iloc) = s(iloc) + 1;
      break;

    end

  end

  return
end
function len = s_len_trim ( s )

%*****************************************************************************80
%
%% S_LEN_TRIM returns the length of a character string to the last nonblank.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be measured.
%
%    Output, integer LEN, the length of the string up to the last nonblank.
%
  len = length ( s );

  while ( 0 < len )
    if ( s(len) ~= ' ' )
      return
    end
    len = len - 1;
  end

  return
end
function word_num = s_word_count ( s )

%*****************************************************************************80
%
%% S_WORD_COUNT counts the number of "words" in a string.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 January 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be examined.
%
%    Output, integer WORD_NUM, the number of "words" in the string.
%    Words are presumed to be separated by one or more blanks.
%
  FALSE = 0;
  TRUE = 1;

  word_num = 0;
  s_length = length ( s );

  if ( s_length <= 0 )
    return;
  end

  blank = TRUE;

  for i = 1 : s_length

    if ( s(i) == ' ' )
      blank = TRUE;
    elseif ( blank == TRUE )
      word_num = word_num + 1;
      blank = FALSE;
    end

  end

  return
end
function tec_write ( tec_filename, dim_num, node_num, element_num, ...
  element_order, value_num, node_coord, element_node, values )

%*****************************************************************************80
%
%% TEC_WRITE writes finite element data to a TEC file.
%
%  Discussion:
%
%    This program writes the node, element and data files that define
%    a finite element geometry and data based on that geometry:
%    * a set of nodes,
%    * a set of elements based on those nodes,
%    * a set of data values associated with each node.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 March 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string NODE_FILENAME, the name of the node coordinate
%    file.  If this argument is empty, no node coordinate file will be written.
%
%    Input, string ELEMENT_FILENAME, the name of the element file.  If
%    this argument is empty, no element file will be written.
%
%    Input, string VALUES_FILENAME, the name of the node data file.  If
%    this argument is empty, no node data file will be written.
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer NODE_NUM, the number of nodes.
%
%    Input, integer ELEMENT_NUM, the number of elements.
%
%    Input, integer ELEMENT_ORDER, the order of the elements.
%
%    Input, integer VALUE_NUM, the number of data items per node.
%
%    Input, real NODE_COORD(DIM_NUM,NODE_NUM), the coordinates of nodes.
%
%    Input, integer ELEMENT_NODE(ELEMENT_ORDER,ELEMENT_NUM);
%    the global index of local node I in element J.
%
%    Input, real VALUES(VALUE_NUM,NODE_NUM), the data values associated
%    with each node.
%
  tec_file_unit = fopen ( tec_filename, 'wt' );
%
%  Write the title.
%
  fprintf ( tec_file_unit, 'TITLE = "%s"\n', tec_filename );
%
%  Write the variable names.
%
  fprintf ( tec_file_unit, 'VARIABLES = ' );

  name = 'X';
  for dim = 1 : dim_num
    if ( dim == 1 )
      fprintf ( tec_file_unit, '"%s"', name );
    else
      fprintf ( tec_file_unit, ', "%s"', name );
    end
    name = s_inc ( name );
  end

  name = 'data_001';
  for dim = 1 : value_num
    fprintf ( tec_file_unit, ', "%s"', name );
    name = file_name_inc ( name );
  end

  fprintf ( tec_file_unit, '\n' );
%
%  Write the ZONE record.
%
  if ( dim_num == 2 & element_order == 3 )
    zonetype = 'FETRIANGLE';
  elseif ( dim_num == 2 & element_order == 4 )
    zonetype = 'FEQUADRILATERAL';
  elseif ( dim_num == 3 & element_order == 4 )
    zonetype = 'FETETRAHEDRON';
  elseif ( dim_num == 3 & element_order == 8 )
    zonetype = 'FEBRICK';
  else
    zonetype = 'FEUNKNOWN';
  end

  fprintf ( tec_file_unit, 'ZONE N = %d, E = %d, ', node_num, element_num );
  fprintf ( tec_file_unit, 'DATAPACKING = POINT, ZONETYPE = %s\n', ...
    zonetype );
%
%  Write the node coordinates and node data.
%
  for node = 1 : node_num
    for dim = 1 : dim_num
      fprintf ( tec_file_unit, '  %10f', node_coord(dim,node) );
    end
    for data = 1 : value_num
      fprintf ( tec_file_unit, '  %10f', values(data,node) );
    end
    fprintf ( tec_file_unit, '\n' );
  end
%
%  Write the element-node connectivity.
%
  for element = 1 : element_num
    for order = 1 : element_order
      fprintf ( tec_file_unit, '  %6d', element_node(order,element) );
    end
    fprintf ( tec_file_unit, '\n' );
  end

  fclose ( tec_file_unit );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEC_WRITE wrote all data to "%s".\n', ...
    tec_filename );

  return
end
function timestamp ( )

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

  return
end


function write_descriptors(path, descriptors)
% WRITE_DESCRIPTORS - Write the descriptors to a binary file.
%   path:
%       Path to descriptor file.
%   descriptors:
%       Floating point descriptors, where each row represents one
%       descriptor and each column represents one dimension of the
%       descriptor. For example, size(descriptors) = (1000, 128) contains
%       1000 descriptors of dimensionality 128. The data type of
%       the descriptors must be a single-precision real matrix.
%
% Copyright 2017: Johannes L. Schoenberger <jsch at inf.ethz.ch>

assert(isreal(descriptors) & isfloat(descriptors));

fid = fopen(path, 'w');
fwrite(fid, size(descriptors), 'int32');
fwrite(fid, descriptors', 'single');
fclose(fid);

end


%EDGELIST Return list of edge pixels for region
%
% EG = EDGELIST(IM, SEED) is a list of edge pixels (Nx2) of a region in the
% image IM starting at edge coordinate SEED=[X,Y].  The edgelist has one row per
% edge point coordinate (x,y).
%
% EG = EDGELIST(IM, SEED, DIRECTION) as above, but the direction of edge
% following is specified.  DIRECTION == 0 (default) means clockwise, non
% zero is counter-clockwise.  Note that direction is with respect to y-axis
% upward, in matrix coordinate frame, not image frame.
%
% [EG,D] = EDGELIST(IM, SEED, DIRECTION) as above but also returns a vector
% of edge segment directions which have values 1 to 8 representing W SW S SE E
% NW N NW respectively.
%
% Notes::
% - Coordinates are given assuming the matrix is an image, so the indices are
%   always in the form (x,y) or (column,row).
% - IM is a binary image where 0 is assumed to be background, non-zero
%   is an object.
% - SEED must be a point on the edge of the region.
% - The seed point is always the first element of the returned edgelist.
% - 8-direction chain coding can give incorrect results when used with
%   blobs founds using 4-way connectivty.
%
% Reference::
% - METHODS TO ESTIMATE AREAS AND PERIMETERS OF BLOB-LIKE OBJECTS: A COMPARISON
%   Luren Yang, Fritz Albregtsen, Tor Lgnnestad and Per Grgttum
%   IAPR Workshop on Machine Vision Applications Dec. 13-15, 1994, Kawasaki
%
% See also ILABEL.

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

function [e,d] = edgelist(im, P, direction)

    % deal with direction argument
    if nargin == 2
        direction = 0;
    end

    if direction == 0
        neighbours = [1:8]; % neigbours in clockwise direction
    else
        neighbours = [8:-1:1];  % neigbours in counter-clockwise direction
    end

    P = P(:)';
    P0 = P;     % make a note of where we started
    pix0 = im(P(2), P(1));  % color of pixel we start at

    % find an adjacent point outside the blob
    Q = adjacent_point(im, P, pix0);
    if isempty(Q)
        error('no neighbour outside the blob');
    end

    e = P;  % initialize the edge list
    dir = []; % initialize the direction list

    % these are directions of 8-neighbours in a clockwise direction
    dirs = [-1 0; -1 1; 0 1; 1 1; 1 0; 1 -1; 0 -1; -1 -1];

    while 1
        % find which direction is Q
        dQ = Q - P;
        for kq=1:8
            if all(dQ == dirs(kq,:))
                break;
            end
        end

        % now test for directions relative to Q
        for j=neighbours
            % get index of neighbour's direction in range [1,8]
            k = j + kq;
            if k > 8
                k = k - 8;
            end
            dir = [dir; k];

            % compute coordinate of the k'th neighbour
            Nk = P + dirs(k,:);
            try
                if im(Nk(2), Nk(1)) == pix0
                    % if this neighbour is in the blob it is the next edge pixel
                    P = Nk;
                    break;
                end
            end
            Q = Nk;     % the (k-1)th neighbour
        end

        % check if we are back where we started
        if all(P == P0)
            break;
        end

        % keep going, add P to the edgelist
        e = [e; P];
    end

    if nargout > 1
        d = dir;
    end
end

function P = adjacent_point(im, seed, pix0)
    % find an adjacent point not in the region
    dirs = [1 0; 0 1; -1 0; 0 -1];
    for d=dirs'
        P = [seed(1)+d(1), seed(2)+d(2)];
        try
            if im(P(2), P(1)) ~= pix0
                return;
            end
        catch
            % if we get an exception then by definition P is outside the region,
            % since it's off the edge of the image
            return;
        end
    end
    P = [];
end


function [returnVal, txtReturnVal] = lvmThreeDPlot(X, lbl, symbol)

% LVMTHREEDPLOT Helper function for plotting the labels in 3-D.
% FORMAT
% DESC helper function for plotting an embedding in 3-D with symbols.
% ARG X : the data to plot.
% ARG lbl : the labels of the data point.
% ARG symbol : the symbols to use for the different labels.
%
% SEEALSO : lvmScatterPlot, lvmVisualise
%
% COPYRIGHT : Neil D. Lawrence, 2004, 2005, 2006, 2008

% MLTOOLS
if nargin < 2
  lbl = [];
end
if(strcmp(lbl, 'connect'))
  connect = true;
  lbl = [];
else
  connect = false;
end

if iscell(lbl)
  lblStr = lbl{2};
  lbl = lbl{1};
  labelsString = true;
else
  labelsString = false;
end

if nargin < 3
  if isempty(lbl)
    symbol = getSymbols(1);
  else
    symbol = getSymbols(size(lbl,2));
  end
end
axisHand = gca;
returnVal = [];
textReturnVal = [];
nextPlot = get(axisHand, 'nextplot');
for i = 1:size(X, 1)
  if i == 2
    set(axisHand, 'nextplot', 'add');
  end
  if ~isempty(lbl)
    labelNo = find(lbl(i, :));
  else
    labelNo = 1;
  end
  try
    returnVal = [returnVal; plot3(X(i, 1), X(i, 2), X(i, 3), symbol{labelNo})];
    if labelsString
      textReturnVal = [textReturnVal; text(X(i, 1), X(i, 2), X(i, 3), lblStr{i})];
    end
    if connect
      if i>1
        line([X(i-1, 1) X(i, 1)], [X(i-1, 2), X(i, 2)], [X(i-1, 3), X(i, 3)]);
      end
    end
  catch
    if strcmp(lasterr, 'Index exceeds matrix dimensions.')
      error(['Only ' num2str(length(symbol)) ' labels supported (it''s easy to add more!)'])
    end
  end
end
set(axisHand, 'nextplot', nextPlot);
set(returnVal, 'markersize', 10);
set(returnVal, 'linewidth', 2);


function title = p30_title ( )

%*****************************************************************************80
%
%% P30_TITLE returns a title for problem 30.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = 'The Branin RCOS Function';

  return
end


function pass = test_splitting(pref)

if ( nargin == 0 )
    pref = chebfunpref();
end

% Store current globlal state.
p = chebfunpref();
chebfunpref.setDefaults('factory')

warnState = warning('off', 'CHEBFUN:splitting:deprecated');

try
    % Testing takes place inside this TRY CATCH.

    pass(1) = strcmp(splitting(), 'off');

    pass(2) = strcmp(splitting('on'), 'off');

    pass(3) = strcmp(splitting(), 'on');

    F = @(x) cos(pi*x).*sign(x);
    f = chebfun(@(x) F(x), [-1 1]);
    x = linspace(-1, 1, 20);
    err = norm(f(x) - F(x), inf);
    pass(4) = numel(f.domain > 1) && err < 1e-5;

    pass(5) = strcmp(splitting('off'), 'on');

    pass(6) = strcmp(splitting(), 'off');

catch ME
    % Reset preferences and warning state
    chebfunpref.setDefaults(p);
    warning(warnState);

    % Rethrow error:
    rethrow(ME)
end

% Return to default settings:
chebfunpref.setDefaults(p);
warning(warnState);

end


function a = uplus(a)
%UPLUS        Gradient unary plus  + a
%

% written  10/16/98     S.M. Rump
% modified 12/18/02     S.M. Rump  performance improved
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
%


function p00_nvar_test ( problem_num )

%*****************************************************************************80
%
%% P00_NVAR_TEST prints the problem size.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM_NUM, the number of problems.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'P00_NVAR_TEST\n' );
  fprintf ( 1, '  List the problem size.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   Problem    Option      Size\n' );
  fprintf ( 1, '\n' );

  for problem = 1 : problem_num
    option_num = p00_option_num ( problem );
    fprintf ( 1, '\n' );
    for option = 1 : option_num
      nvar = p00_nvar ( problem, option );
      fprintf ( 1, '  %8d  %8d  %8d\n', problem, option, nvar );
    end
  end

  return
end


function test_example_sourcemodel_aligned2mni

% MEM 4gb
% WALLTIME 00:10:00

%
%% Create MNI-aligned grids in individual head-space
%
% When combining the source-level estimates of activity in multiple subjects, the activity can first be interpolated on the individuals MRI (using **[ft_sourceinterpolate](https://github.com/fieldtrip/fieldtrip/blob/release/ft_sourceinterpolate.m)**) and then spatially normalized to a template brain (using **[ft_volumenormalise](https://github.com/fieldtrip/fieldtrip/blob/release/ft_volumenormalise.m)**).
%
% It is also possible to define the source-reconstruction grid for each individual subject in such a way that all these grids are already aligned in MNI-space. The combination or statistic of source-level data across subjects can then directly be computed within the source-structure _without the need_ to interpolate and normalize each volume.
%
% The content of this page has moved to another location, and is dealt with **in context** in the tutorial about [the construction of different types of source models](/tutorial/sourcemodel#subject-specific_grids_that_are_equivalent_across_subjects_in_normalized_space).


function nam_mat = tif2mat(nam)
%% convert tiff files into mat files
% inputs:
%   nam: file names
% output:
%   nam_mat: name of the *.mat file
% Author: Pengcheng Zhou, Carnegie Mellon University

%% tiff file information
if isempty(nam)
    nam_mat = [];
    fprintf('empty tiff file');
    return;
else
    [tmp_dir, tmp_file, ~] = fileparts(nam);
    nam_mat = sprintf('%s%s%s.mat', tmp_dir, filesep, tmp_file);
end

info = imfinfo(nam);

if  isfield(info(1), 'ImageDescription') && ~isempty(strfind(info(1).ImageDescription,'ImageJ'))
    junk1=regexp(info(1).ImageDescription,'images=\d*','match');
    if isempty(junk1)
        junk1=regexp(info(1).ImageDescription,'frames=\d*','match');
    end
    junk2=strjoin(junk1);
    T=strread(junk2,'%*s %d','delimiter','=');
else
    T = length(info);   % number of frames
end
d1 = info.Height;   % height of the image
d2 = info.Width;    % width of the image
Ysiz = [d1, d2, T]';

fprintf('CNMF_E is converting TIFF file to *.mat file');
% create a mat file
Tchunk = min(T, round(2^29/d1/d2)); %each chunk uses at most 4GB
Y = smod_bigread2(nam, 1, Tchunk);  %#ok<*NASGU>
save(nam_mat, 'Y', 'Ysiz', '-v7.3');
if Tchunk==T
    return;
else
    data = matfile(nam_mat, 'Writable', true);
    t0 = Tchunk+1;
    while t0<=T
        num2read = min(t0+Tchunk-1, T) - t0 + 1;
        tmpY = smod_bigread2(nam, t0, num2read);
        data.Y(:, :, (1:num2read)+t0-1) = tmpY;
        t0 = t0 + num2read;
    end
end


function y=packr(x)
% PACKR
% PACKR(x) deletes all the rows of x that contain a MATLAB missing element (NaN)
t=isnan(x);
c=sum(t')'==0;
y=x(c==1,:);


function [selected] = ft_select_point3d(bnd, varargin)

% FT_SELECT_POINT3D helper function for selecting one or multiple points on a 3D mesh
% using the mouse. It returns a list of the [x y z] coordinates of the selected
% points.
%
% Use as
%   [selected] = ft_select_point3d(bnd, ...)
%
% Optional input arguments should come in key-value pairs and can include
%   'multiple'    = true/false, make multiple selections, pressing "q" on the keyboard finalizes the selection (default = false)
%   'nearest'     = true/false (default = true)
%   'marker'      = character or empty, for example '.', 'o' or 'x' (default = [])
%   'markersize'  = scalar, the size of the marker (default = 10)
%   'markercolor' = character, for example 'r', 'b' or 'g' (default = 'k')
%
% Example
%   [pos, tri] = mesh_sphere(162);
%   bnd.pos = pos;
%   bnd.tri = tri;
%   ft_plot_mesh(bnd)
%   camlight
%   ... do something here
%
% See also FT_SELECT_BOX, FT_SELECT_CHANNEL, FT_SELECT_POINT, FT_SELECT_RANGE, FT_SELECT_VOXEL

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

% get optional input arguments
nearest     = ft_getopt(varargin, 'nearest',  true);
multiple    = ft_getopt(varargin, 'multiple', false);
marker      = ft_getopt(varargin, 'marker', []);
markersize  = ft_getopt(varargin, 'markersize', 10);
markercolor  = ft_getopt(varargin, 'markercolor', 'k');

% ensure that it is boolean
nearest  = istrue(nearest);
multiple = istrue(multiple);

% get the object handles
h = get(gca, 'children');

% select the correct objects
iscorrect = false(size(h));
for i=1:length(h)
  try
    pos = get(h(i),'vertices');
    tri = get(h(i),'faces');
    if ~isempty(bnd) && isequal(bnd.pos, pos) && isequal(bnd.tri, tri)
      % it is the same object that the user has plotted before
      iscorrect(i) = true;
    elseif isempty(bnd)
      % assume that it is the same object that the user has plotted before
      iscorrect(i) = true;
    end
  end
end
h = h(iscorrect);

if isempty(h) && ~isempty(bnd)
  figure
  ft_plot_mesh(bnd);
  camlight
  selected = ft_select_point3d(bnd, varargin{:});
  return
end

if length(h)>1
  ft_warning('using the first patch object in the figure');
  h = h(1);
end

selected = zeros(0,3);

% everything is added to the current figure
holdflag = ishold;
if ~holdflag
  hold on
end

done = false;
az = 0;
el = 0;
view(az,el);

while ~done
  k = waitforbuttonpress;
  [p, v, vi, facev, facei] = select3d(h);
  if k == 1 %checks if waitforbuttonpress was a key
    key = get(gcf,'CurrentCharacter'); % which key was pressed (if any)?
    if strcmp(key, 'q')
      % finished selecting points
      done = true;
    elseif strcmp(key, 'r')
      % remove last point
      if ~isempty(selected)
        if ~isempty(marker)
          delete(findobj('marker', '*'));
          hs = plot3(selected(1:end-1,1), selected(1:end-1,2), selected(1:end-1,3), [markercolor marker]);
          set(hs, 'MarkerSize', markersize);
        end
        fprintf('removed latest point at [%f %f %f]\n', selected(end,1), selected(end,2), selected(end,3));
        selected = selected(1:end-1,:);
      end
    elseif strcmp(key,'+')
      zoom(1.1)
    elseif strcmp(key,'-')
      zoom(0.9)
    elseif strcmp(key,'w')
      az = az+6;
      view(az,el)
    elseif strcmp(key,'a')
      el = el+6;
      view(az,el)
    elseif strcmp(key,'s')
      az = az-6;
      view(az,el)
    elseif strcmp(key,'d')
      el = el-6;
      view(az,el)
    end

  elseif ~isempty(p)
    % a new point was selected
    if nearest
      selected(end+1,:) = v;
    else
      selected(end+1,:) = p;
    end % if nearest

    if multiple
      fprintf('selected points at\n');
      disp(selected);
    else
      fprintf('selected point at [%f %f %f]\n', selected(end,1), selected(end,2), selected(end,3));
    end

    if ~isempty(marker)
      hs = plot3(selected(end,1), selected(end,2), selected(end,3), [markercolor marker]);
      set(hs, 'MarkerSize', markersize);
    end
  end

  if ~multiple
    done = true;
  end
end

if ~holdflag
  hold off
end


function varargout = prtPlotUtilMatrixTable(X,cLim,cMap,num2strFormat,textCMap)
% prtPlotUtilMatrixTable displays a matrix as a table. The table is actually an
%   image with lines between each pixel.
%
% Syntax: [axesHandle, textHandles, verticleLineHandles, horizontalLineHandles]
%           = prtPlotUtilMatrixTable(X,cLim,cMap,num2strFormat,textCMap)
%
% Inputs:
%   X - 2-D Matrix to plot
%   cLim - The limits for image scaling default = [min(X(:)), max(X(:))]
%   cMap - The colormap for image default = gray;
%   num2strFormat - The string format for each matrix element
%       default = '%.2f'
%   textCMap - The colorMap to use for the text Color.
%       default - [cMap(end,:); cMap(1,:)];
%           If cMap has only 1 color the default = 1-cMap.
%
% Outputs: These names are all fairly descriptive
%   axesHandle
%   textHandles
%   verticleLineHandles
%   horizontalLineHandles
%
% Example:
%   prtPlotUtilMatrixTable(rand(5),[0 1],summer(128),'%.2f',[0 0 0])
%   prtPlotUtilMatrixTable(rand(5),[0 1],summer(128),'%.2f')
%   prtPlotUtilMatrixTable(rand(5),[0 1],[1 1 1],[],[0 0 0])
%
% Other m-files required: none
% Subfunctions: getBestFontSize
% MAT-files required: none
%
% See also: plotConfusionMatrix.m

if nargin < 2 || isempty(cLim)
    cLim = [min(X(:)) max(X(:))];
end

if nargin < 3 || isempty(cMap)
    cMap = gray;
end

if nargin < 4 || isempty(num2strFormat)
    num2strFormat = [];
end

if nargin < 5 || isempty(textCMap)
    if size(cMap,1) == 1;
        textCMap = 1-cMap;
    else
        textCMap = [cMap(end,:); cMap(1,:)];
    end
end

[nRows, nCols] = size(X);

imageAxes = gca;
imagesc(X,cLim);
colormap(cMap);
fontSize = max(getBestFontSize(imageAxes),1);
textHandles = prtUtilPreAllocateHandles(size(X));
verticleLineHandles = prtUtilPreAllocateHandles(nRows,1);
horizontalLineHandles = prtUtilPreAllocateHandles(nCols,1);
hold on;

[dontNeed, textCMapInds] = histc( (X-cLim(1))./(cLim(2)-cLim(1)) , linspace(0,1+eps,size(textCMap,1)+1)); %#ok<ASGLU>
textCMapInds(textCMapInds==0 | ~isfinite(textCMapInds)) = size(textCMap,1);
textCMapInds(textCMapInds==0 | ~isfinite(textCMapInds)) = 1;
textCMapInds(textCMapInds > size(textCMap,1)) = size(textCMap,1);

for iRow = 1:nRows
    for jCol = 1:nCols
        cNum = X(iRow,jCol);

        cTextColor = textCMap(textCMapInds(iRow,jCol),:);

        cTextString = num2str(cNum,num2strFormat);

        % Some decimal place pruning
        done = false;
        while ~done
            if length(cTextString) > 1 && strcmpi(cTextString(end),'0') && any(cTextString == '.')
                cTextString(end) = [];
            else
                done = true;
            end
        end
        % Remove last decimal if necessary
        if strcmpi(cTextString(end),'.')
            cTextString(end) = [];
        end

        textHandles(iRow,jCol) = text(jCol,iRow,cTextString,...
            'color',cTextColor,'horizontalAlignment','center',...
            'fontsize',fontSize,'clipping','on','visible','on');

        if iRow == 1
            horizontalLineHandles(jCol) = plot([jCol jCol]+0.5,[0.5 0.5+nRows],'k','linewidth',1);
        end
    end
    verticleLineHandles(iRow) = plot([0.5 0.5+nCols],[iRow, iRow]+0.5,'k','linewidth',1);
end
hold off;

set(imageAxes,'YTick',1:nRows,'XTick',1:nCols,...
    'XTickLabel',num2str((1:nCols)'),'YTickLabel',num2str((1:nRows)'),...
    'Xlim',[0.5 nCols+0.5],'Ylim',[0.5 nRows+0.5],...
    'TickLength',[0 0]);

varargout = {};
if nargout > 0
    varargout = {imageAxes, textHandles, verticleLineHandles, horizontalLineHandles};
end

f = ancestor(imageAxes,'figure');
set(f,'ResizeFcn',@(src,evt)setBestFontSize(imageAxes,textHandles));
setBestFontSize(imageAxes,textHandles);

function setBestFontSize(imAxes,textHandles)

if ~ishandle(imAxes)
    return
end
try
    fs = getBestFontSize(imAxes);
catch %#ok<CTCH>
    return
end

for iHandle = 1:numel(textHandles)
    if ishandle(textHandles(iHandle))
        if fs > 0
            set(textHandles(iHandle),'FontSize',fs);
            set(textHandles(iHandle),'visible','on');
        else
            set(textHandles(iHandle),'visible','off');
        end
    end
end

function fs = getBestFontSize(imAxes)
% I found this little gem in a MATLAB central file heatmaptext.m
% This should solve alot of our problems with this function
% It adjusts the font size relative to the number of col and rows.
%
% 31-Jan-2008 - I have modified this so it checks the extent of the axes
% instead of the figure. This allows the fontsize to change relative to a
% subplot. - KDM
%
% 17-May-2011 - I have modified this to check the minimumum of both ratios
% so that resized plots look good. Also added a listener above so that the
% resize will call this function again.
%
%
% Apparently this is copyright the MathWorks as is stated in the funciton.
%
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15877&objectType=file#
%

% Try to keep font size reasonable for text
nrows = diff(get(imAxes,'YLim'));
ncols = diff(get(imAxes,'XLim'));

set(imAxes,'units','pixels');
extent = get(imAxes,'Position');
set(imAxes,'units','normalized');
ratioNum = extent(3:4);

magicNumber = 80;
if ncols < magicNumber && nrows < magicNumber
    ratio = min(ratioNum./[nrows,ncols]);
elseif ncols < magicNumber
    ratio = ratioNum(2)/ncols;
elseif nrows < magicNumber
    ratio = ratioNum(1)/nrows;
else
    ratio = 1;
end

%fs = min(maxFontSize,ceil(ratio/4));    % the gold formula
fs = ceil(ratio/4);
if fs < 4 % Font sizes less than 4 still look like crap
    fs = 0;
end


%IMPEXP_GID Import/export grid in GID msh format.
%
%   [ GRID ] = IMPEXP_GID( FILE_NAME, MODE, GRID, FID_LOG ) Import or export of
%   a GiD mesh ASCII format .msh file. FILE_NAME is a string specifying the (root)
%   file name to process. MODE can either be a string indicating import (no boundary
%   reconstruction), import_bdr (boundary reconstruction with gridbdr), or export.
%   GRID is a grid struct input for export and output for import. FID_LOG is an
%   optional log file handle for message output (negative for gui output or empty
%   for no output).

% Copyright 2013-2022 Precise Simulation, Ltd.


%> @brief Return a set of indices separating contiguous segments of logical
%> values.
%> @author Eric Cousineau <eacousineau@gmail.com>
function [C] = contiguous_indices(B)

% Following: http://stackoverflow.com/q/2212201/170413
B = logical(B(:)');
count = length(B);

if all(B)
    % Special case for all values being high
    C = {1:count};
    return;
end

dB = diff(B);
starts = find(dB == 1) + 1;
ends = find(dB == -1);

% If we start high, then we need to insert an initial index
if length(ends) >= 1 && (isempty(starts) || ends(1) < starts(1))
    starts = [1, starts];
end

% The count for ends and starts may differ if there is a lone point at the
% end
if length(starts) > length(ends)
    if isempty(ends) || starts(end) > ends(end)
        % Means we ended at transition going from low to high
        ends(end + 1) = count;
    else
        % Augment ends with last starting point
        ends(end + 1) = starts(end);
    end
end

nranges = length(ends);
C = cell(1, nranges);
for i = 1:nranges
    C{i} = starts(i):ends(i);
end

end


% importevent() - Import experimental events from data file or Matlab
%                 array into a structure.
%
% Usage: >> eventstruct = importevent( event, oldevent, srate);
%        >> eventstruct = importevent( event, oldevent, srate, 'key1', 'value1', ...);
%
% Input:
%   event     - [ 'filename'|array ] Filename of a text file, or name of
%               Matlab array in the global workspace containing an
%               array of events in the folowing format: The first column
%               is the type of the event, the second the latency.
%               The others are user-defined. The function can read
%               either numeric or text entries in ascii files.
%   oldevent  - Old event structure. Used for aligning new events with old
%               ones. Enter [] is no such structure exist.
%   srate     - Sampling rate of the underlying data. Event latencies are
%               expressed in terms of latency in sample point with respect
%               to the data.
%
% Optional file or array input:
%  'fields'   - [Cell array] List of the name of each user-defined column,
%               optionally followed by a description. Ex: { 'type', 'latency' }
%  'skipline' - [Interger] Number of header rows to skip in the text file
%  'timeunit' - [ latency unit rel. to seconds ]. Default unit is 1 = seconds.
%               NaN indicates that the latencies are given in time points.
%  'delim'    - [string] String of delimiting characters in the input file.
%               Default is tab|space.
%
% Optional oldevent input:
%  'append'   - ['yes'|'no'] 'yes' = Append events to the current events in
%               the EEG dataset {default}: 'no' = Erase the previous events.
%  'indices'  - {integer vector] Vector indicating the indices of the events to
%               modify.
%  'align'    - [num] Align the first event latency to the latency of existing
%               event number (num), and check latency consistency.
%               A value of 0 indicates that the first events of the pre-defined
%               events and imported events will be aligned. A positive value (num)
%               aligns the first event to the num-th pre-existing event.
%               A negative value can also be used; then event number (-num)
%               is aligned to the first pre-existing event.  Default is 0.
%               (NaN-> no alignment).
%  'optimalign' - ['on'|'off'] Optimize the sampling rate of the new events so
%               they best align with old events. Default is 'on'.
%
% Outputs:
%   eventstruct - Event structure containing imported events
%
% Example: >> eventstruct = importevent( 'event_values.txt', [], 256, ...
%         'fields', {'type', 'latency','condition' }, ...
%         'append', 'no', 'align', 0, 'timeunit', 1E-3 );
%
%         This loads the ascii file 'event_values.txt' containing 3 columns
%         (event_type, latency, and condition). Latencies in the file are
%         in ms (1E-3). The first event latency is re-aligned with the
%         beginning of the dataset ('align', 0). Any previous events
%         are erased ('append', 'no').
%
% Author: Arnaud Delorme & Scott Makeig, CNL / Salk Institute, 2004
%
% See also: pop_importevent()

% Copyright (C) Arnaud Delorme, CNL / Salk Institute, 2004, arno@salk.edu
%
% 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 2 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, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

%% REVISION HISTORY
%% function definition, input check
function event = importevent(event, oldevent, srate, varargin)

if nargin < 1
   help importevent;
   return;
end;

I = [];

% remove the event field
% ----------------------
if ~isempty(oldevent), allfields = fieldnames(oldevent);
else                   allfields = {}; end;

g = finputcheck( varargin, { 'fields'    'cell'     []         {};
                         'skipline'  'integer'  [0 Inf]    0;
                         'indices'   'integer'  [1 Inf]    [];
                         'append'    'string'   {'yes' 'no' '''yes''' '''no''' }         'yes';
                         'timeunit'  'real'     []         1;
                         'event'     { 'cell' 'real' 'string' }     []    [];
                         'align'     'integer'  []         NaN;
                         'optimalign' 'string'  { 'on' 'off' }         'on';
                         'delim'     {'integer' 'string'}   []         char([9 32 44])}, 'importevent');
if isstr(g), error(g); end;
if ~isempty(g.indices), g.append = 'yes'; end;
g.delim = char(g.delim);

% call from pop_importevent
% -------------------------
if ~isempty(g.event)
    event = g.event;
    if ~isstr(event)
        if size(event,2) > size(event,1), event = event'; end;
    end;
end;
g.event = event;

% determine latency for old event alignment
% -----------------------------------------
tmpalign    = g.align;
g.align     = [];
g.align.val = tmpalign;
if ~isnan(g.align.val)
    if isempty(oldevent)
        error('Setevent: no pre-existing event, cannot perform alignment');
    end;
    if ~isfield(oldevent, 'latency')
        error('Setevent: pre-existing events do not have a latency field for re-alignment');
    end;
    switch g.append
        % What is the reasoning behind this warning? It seems misleading. TobyF
        % 3/28/2007
        case {'yes' '''yes'''}, disp('Setevent warning: using align, events should not be appended but erased');
    end;
    if g.align.val < 0
        g.align.event = oldevent(1).latency;
    else
        g.align.event = oldevent(g.align.val+1).latency;
    end
    g.align.nbevent = length(oldevent);
    g.oldevents = oldevent;
    g.align.txt = sprintf([ 'Check alignment between pre-existing (old) and loaded event' ...
                          ' latencies:\nOld event latencies (10 first): %s ...\n' ], ...
                          int2str([ oldevent(1:min(10, length(oldevent))).latency ]));
else
    g.oldevents = [];
end;

tmpfields = fieldnames(g);
event = oldevent;
%% scan all the fields of g
% ------------------------
for curfield = tmpfields'
    if ~isempty(event), allfields = fieldnames(event);
    else                    allfields = {}; end;
    switch lower(curfield{1})
        case {'append', 'fields', 'skipline', 'indices', 'timeunit', 'align', 'delim' }, ; % do nothing now
        case 'event', % load an ascii file
            switch g.append
                case { '''no''' 'no' } % ''no'' for backward compatibility
                      event = load_file_or_array( g.event, g.skipline, g.delim );
                      allfields = g.fields(1:min(length(g.fields), size(event,2)));
                      event = eeg_eventformat(event, 'struct', allfields);
					  % generate ori fields
					  % -------------------
                      if ~isnan(g.timeunit)
                          for index = 1:length(event)
                              event(index).init_index = index;
                              event(index).init_time  = event(index).latency*g.timeunit;
                          end;
                      end;
                      event = recomputelatency( event, 1:length(event), srate, ...
                                                    g.timeunit, g.align, g.oldevents, g.optimalign);
                case { '''yes''' 'yes' }
                      % match existing fields
                      % ---------------------
                      tmparray = load_file_or_array( g.event, g.skipline, g.delim );
                      if isempty(g.indices) g.indices = [1:size(tmparray,1)] + length(event); end;
                      if length(g.indices) ~= size(tmparray,1)
                            error('Set error: number of row in file does not match the number of event given as input');
                      end;

                      % add field
                      % ---------
                      g.fields = getnewfields( g.fields, size(tmparray,2)-length(g.fields));

                      % add new values
                      % ---------------------
                      for eventfield = 1:size(tmparray,2)
                          event = setstruct( event, g.fields{eventfield}, g.indices, { tmparray{:,eventfield} });
                      end;
					  % generate ori fields
					  % -------------------
                      offset = length(event)-size(tmparray,1);
                      for index = 1:size(tmparray,1)
                          event(index+offset).init_index = index;
                          event(index+offset).init_time  = event(index+offset).latency*g.timeunit;
                      end;
                      event = recomputelatency( event, g.indices, srate, g.timeunit, ...
                                                    g.align, g.oldevents, g.optimalign);
            end;
      end;
end;

if isempty(event) % usefull 0xNB empty structure
    event = [];
end;

%% remove the events wit out-of-bound latencies
% --------------------------------------------
if isfield(event, 'latency')
    try
        res = cellfun('isempty', { event.latency });
        res = find(res);
        if ~isempty(res)
            fprintf( 'importevent warning: %d/%d event(s) have invalid latencies and were removed\n', ...
                     length(res), length(event));
            event( res ) = [];
        end;
    end;
end;

%% interpret the variable name
% ---------------------------
function array = load_file_or_array( varname, skipline, delim );
    if isstr(varname) & exist(varname) == 2  % mean that it is a filename
                                             % --------------------------
        array = loadtxt( varname, 'skipline', skipline, 'delim', delim, 'blankcell', 'off' );

    else % variable in the global workspace
         % --------------------------
         if isstr(varname)
             array = evalin('base', varname);
             if ~iscell(array)
                 array = mattocell(array, ones(1, size(array,1)), ones(1, size(array,2)));
             end;
         else
             array = varname;
         end;
    end;
return;

%% update latency values
% ---------------------
function event = recomputelatency( event, indices, srate, timeunit, align, oldevents, optimalign);

    % update time unit
    % ----------------
    if ~isfield(event, 'latency'),
        if isfield(event, 'duration')
            error('A duration field cannot be defined if a latency field has not been defined');
        end;
        return;
    end;
    if ~isnan(timeunit)
        for index = indices
            event(index).latency  = event(index).latency*srate*timeunit;
            if isfield(event, 'duration')
                event(index).duration = event(index).duration*srate*timeunit;
            end;
        end;
    end;

    % alignment with old events
    % -------------------------
    if ~isnan( align.val )
        if align.val >= 0, alignlatency = event(1).latency;
        else               alignlatency = event(-align.val+1).latency;
        end;
        for index = indices
             event(index).latency = event(index).latency-alignlatency+align.event;
        end;
        if length(event) ~= align.nbevent
            disp('Setevent warning: the number of pre-existing events do not correspond to the number of events');
            disp('                  that were read, so their latencies may have been wrongly re-aligned');
        end;
        fprintf(align.txt);
        fprintf('New event latencies (10 first): %s ...\n', int2str(round([ event(1:min(10, length(event))).latency ])));
    end;
    if strcmpi(optimalign, 'on') & ~isempty(oldevents)
        newlat = [ event.latency     ];
        oldlat = [ oldevents.latency ];

        newlat = repmat(newlat, [length(oldlat) 1]);
        oldlat = repmat(oldlat', [1 size(newlat,2)]);
        if align.val >= 0
            newlat = newlat-newlat(1);
            oldlat = oldlat-oldlat(1+align.val);
        else
            newlat = newlat-newlat(1-align.val);
            oldlat = oldlat-oldlat(1);
        end;

        newfactor = fminsearch('eventalign',1,[],newlat, oldlat);
        fprintf('Best sampling rate ratio found is %1.7f. Below latencies after adjustment\n', newfactor);
        if newfactor > 1.01 | newfactor < 0.99
            disp('Difference is more than 1%, something is wrong; ignoring ratio');
            newfactor = 1;
        else
            difference1 = eventalign(1        ,newlat,oldlat);
            difference2 = eventalign(newfactor,newlat,oldlat);
            fprintf('The average difference before correction was %f sample points\n', difference1);
            fprintf('The average difference after correction is %f sample points\n', difference2);
        end;

        %diffarray = abs(newfactor*newlat-oldlat)';
        %[allmins poss] = min(diffarray);
        %figure; hist(allmins);
    else
        newfactor = 1;
    end;
    if ~isnan( align.val ) & newfactor ~= 1
        if align.val >= 0
            latfirstevent = event(1).latency;
        else
            latfirstevent = event(-align.val+1).latency;
        end;
        for index = setdiff(indices, 1)
            event(index).latency = round(event(index).latency-latfirstevent)*newfactor+latfirstevent;
        end;
        if ~isempty(oldevents)
            fprintf('Old event latencies (10 first): %s ...\n', int2str(round([ oldevents(1:min(10, length(oldevents))).latency ])));
            fprintf('New event latencies (10 first): %s ...\n', int2str(round([ event(1:min(10, length(event))).latency ])));
        end;
    else
        % must add one (because first sample point has latency 0
        % ------------------------------------------------------
        for index = indices
            event(index).latency = round((event(index).latency+1)*1000*newfactor)/1000;
        end;
    end;

%% create new field names
% ----------------------
function epochfield = getnewfields( epochfield, nbfields )
   count = 1;
   while nbfields > 0
       if isempty( strmatch([ 'var' int2str(count) ], epochfield ) )
               epochfield =  { epochfield{:} [ 'var' int2str(count) ] };
               nbfields = nbfields-1;
       else    count = count+1;
       end;
   end
return;

%%
% ----------------------
function var = setstruct( var, fieldname, indices, values )
    if exist('indices') ~= 1, indices = 1:length(var); end
    if ~isempty(values)
        for index = 1:length(indices)
            var = setfield(var, {indices(index)}, fieldname, values{index});
        end
    else
        for index = 1:length(indices)
            var = setfield(var, {indices(index)}, fieldname, '');
        end
    end
return;


function value = p34_param ( action, name, value )

%*****************************************************************************80
%
%% P34_PARAM defaults, sets, or gets the parameters for problem 34.
%
%  Discussion:
%
%    In typical use, the user calls
%      p34_param ( 'DEFAULT' )
%    Then, once the variables have been given default values, any
%    value can be retrieved, as for example by:
%      value = p34_param ( 'GET', 'G' )
%    or set to a new value, as in:
%      p34_param ( 'SET', 'G', 1 )
%
%    G is the gravitational force;
%    K is the damping coefficient;
%    L is the length of the string;
%    M is the mass of the pendulum bob.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 March 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string ACTION:
%    'DEFAULT' sets the variables to default values.
%    'SET' sets the variable chosen by NAME to have the value VALUE.
%    'GET' gets the variable chosen by NAME.
%
%    Input, string NAME, the name of the variable, which should
%    be 'G', 'K', 'L', 'M'.  NAME is ignored if the ACTION is 'DEFAULT'.
%
%    Input, real VALUE, the value to be assigned the variable NAME,
%    if the value of ACTION was 'SET'.  Otherwise VALUE is ignored.
%
%    Output, real VALUE, depends on the input value of ACTION:
%    'DEFAULT', returns the number of variables;
%    'SET', returns the input value of VALUE;
%    'GET', returns the value of the variable NAME.
%
  persistent g;
  persistent k;
  persistent l;
  persistent m;

  if ( s_eqi ( action, 'DEFAULT' ) )

    g = 32.0;
    k = 1.0;
    l = 1.0;
    m = 1.0;

    value = 4;

  elseif ( s_eqi ( action, 'SET' ) )

    if ( s_eqi ( name, 'G' ) )
      g = value;
    elseif ( s_eqi ( name, 'K' ) )
      k = value;
    elseif ( s_eqi ( name, 'L' ) )
      l = value;
    elseif ( s_eqi ( name, 'M' ) )
      m = value;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P34_PARAM - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized variable name: "%s".\n', name );
      error ( 'P34_PARAM - Fatal error!' );
    end

  elseif ( s_eqi ( action, 'GET' ) )

    if ( s_eqi ( name, 'G' ) )
      value = g;
    elseif ( s_eqi ( name, 'K' ) )
      value = k;
    elseif ( s_eqi ( name, 'L' ) )
      value = l;
    elseif ( s_eqi ( name, 'M' ) )
      value = m;
    else
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P34_PARAM - Fatal error!\n' );
      fprintf ( 1, '  Unrecognized variable name: "%s".\n', name );
      error ( 'P34_PARAM - Fatal error!' );
    end

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'P34_PARAM - Fatal error!\n' );
    fprintf ( 1, '  Unrecognized action: "%s".\n', action );
    error ( 'P34_PARAM - Fatal error!' );

  end

  return
end