function gpcf = gpcf_noise(varargin)
%GPCF_NOISE  Create a independent noise covariance function
%
%  Description
%    GPCF = GPCF_NOISE('PARAM1',VALUE1,'PARAM2,VALUE2,...) creates
%    independent noise covariance function structure in which the
%    named parameters have the specified values. Any unspecified
%    parameters are set to default values.
%
%    GPCF = GPCF_NOISE(GPCF,'PARAM1',VALUE1,'PARAM2,VALUE2,...)
%    modify a covariance function structure with the named
%    parameters altered with the specified values.
%
%    Parameters for independent noise covariance function [default]
%      noiseSigma2       - variance of the independent noise [0.1]
%      noiseSigma2_prior - prior for noiseSigma2 [prior_logunif]
%
%    Note! If the prior is 'prior_fixed' then the parameter in
%    question is considered fixed and it is not handled in
%    optimization, grid integration, MCMC etc.
%
%  See also
%    GP_SET, GPCF_*, PRIOR_*

% Copyright (c) 2007-2010 Jarno Vanhatalo
% Copyright (c) 2010 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

  ip=inputParser;
  ip.FunctionName = 'GPCF_NOISE';
  ip.addOptional('gpcf', [], @isstruct);
  ip.addParamValue('noiseSigma2',0.1, @(x) isscalar(x) && x>0);
  ip.addParamValue('noiseSigma2_prior',prior_logunif, @(x) isstruct(x) || isempty(x));
  ip.parse(varargin{:});
  gpcf=ip.Results.gpcf;

  if isempty(gpcf)
    init=true;
    gpcf.type = 'gpcf_noise';
  else
    if ~isfield(gpcf,'type') && ~isequal(gpcf.type,'gpcf_noise')
      error('First argument does not seem to be a valid covariance function structure')
    end
    init=false;
  end

  % Initialize parameter
  if init || ~ismember('noiseSigma2',ip.UsingDefaults)
    gpcf.noiseSigma2=ip.Results.noiseSigma2;
  end

  % Initialize prior structure
  if init
    gpcf.p=[];
  end
  if init || ~ismember('noiseSigma2_prior',ip.UsingDefaults)
    gpcf.p.noiseSigma2=ip.Results.noiseSigma2_prior;
  end

  if init
    % Set the function handles to the subfunctions
    gpcf.fh.pak = @gpcf_noise_pak;
    gpcf.fh.unpak = @gpcf_noise_unpak;
    gpcf.fh.lp = @gpcf_noise_lp;
    gpcf.fh.lpg = @gpcf_noise_lpg;
    gpcf.fh.cfg = @gpcf_noise_cfg;
    gpcf.fh.ginput = @gpcf_noise_ginput;
    gpcf.fh.cov = @gpcf_noise_cov;
    gpcf.fh.trcov  = @gpcf_noise_trcov;
    gpcf.fh.trvar  = @gpcf_noise_trvar;
    gpcf.fh.recappend = @gpcf_noise_recappend;
  end

end

function [w, s] = gpcf_noise_pak(gpcf)
%GPCF_NOISE_PAK  Combine GP covariance function parameters into
%                one vector.
%
%  Description
%    W = GPCF_NOISE_PAK(GPCF) takes a covariance function data
%    structure GPCF and combines the covariance function
%    parameters and their hyperparameters into a single row
%    vector W. This is a mandatory subfunction used for example
%    in energy and gradient computations.
%
%       w = [ log(gpcf.noiseSigma2)
%             (hyperparameters of gpcf.magnSigma2)]'
%
%
%  See also
%    GPCF_NOISE_UNPAK

  w = []; s = {};
  if ~isempty(gpcf.p.noiseSigma2)
    w(1) = log(gpcf.noiseSigma2);
    s = [s 'log(noise.noiseSigma2)'];
    % Hyperparameters of noiseSigma2
    [wh sh] = gpcf.p.noiseSigma2.fh.pak(gpcf.p.noiseSigma2);
    w = [w wh];
    s = [s sh];
  end

end

function [gpcf, w] = gpcf_noise_unpak(gpcf, w)
%GPCF_NOISE_UNPAK  Sets the covariance function parameters
%                     into the structure
%
%  Description
%    [GPCF, W] = GPCF_NOISE_UNPAK(GPCF, W) takes a covariance
%    function data structure GPCF and a hyper-parameter vector W,
%    and returns a covariance function data structure identical
%    to the input, except that the covariance hyper-parameters
%    have been set to the values in W. Deletes the values set to
%    GPCF from W and returns the modified W. This is a mandatory
%    subfunction used for example in energy and gradient computations.
%
%    Assignment is inverse of
%       w = [ log(gpcf.noiseSigma2)
%             (hyperparameters of gpcf.magnSigma2)]'
%
%  See also
%    GPCF_NOISE_PAK

  if ~isempty(gpcf.p.noiseSigma2)
    gpcf.noiseSigma2 = exp(w(1));
    w = w(2:end);

    % Hyperparameters of lengthScale
    [p, w] = gpcf.p.noiseSigma2.fh.unpak(gpcf.p.noiseSigma2, w);
    gpcf.p.noiseSigma2 = p;
  end
end

function lp = gpcf_noise_lp(gpcf)
%GPCF_NOISE_LP  Evaluate the log prior of covariance function parameters
%
%  Description
%    LP = GPCF_NOISE_LP(GPCF) takes a covariance function
%    structure GPCF and returns log(p(th)), where th collects the
%    parameters. This is a mandatory subfunction used for example
%    in energy computations.
%
%  See also
%   GPCF_NOISE_PAK, GPCF_NOISE_UNPAK, GPCF_NOISE_G, GP_E

% Evaluate the prior contribution to the error. The parameters that
% are sampled are from space W = log(w) where w is all the
% "real" samples. On the other hand errors are evaluated in the
% W-space so we need take into account also the Jacobian of
% transformation W -> w = exp(W). See Gelman et.al., 2004,
% Bayesian data Analysis, second edition, p24.

  lp = 0;
  gpp=gpcf.p;

  if ~isempty(gpcf.p.noiseSigma2)
    % Evaluate the prior contribution to the error.
    lp = gpp.noiseSigma2.fh.lp(gpcf.noiseSigma2, gpp.noiseSigma2) +log(gpcf.noiseSigma2);
  end
end

function lpg = gpcf_noise_lpg(gpcf)
%GPCF_NOISE_LPG  Evaluate gradient of the log prior with respect
%                to the parameters.
%
%  Description
%    LPG = GPCF_NOISE_LPG(GPCF) takes a covariance function
%    structure GPCF and returns LPG = d log (p(th))/dth, where th
%    is the vector of parameters. This is a mandatory subfunction
%    used for example in gradient computations.
%
%  See also
%    GPCF_NOISE_PAK, GPCF_NOISE_UNPAK, GPCF_NOISE_LP, GP_G

  lpg = [];
  gpp=gpcf.p;

  if ~isempty(gpcf.p.noiseSigma2)
    lpgs = gpp.noiseSigma2.fh.lpg(gpcf.noiseSigma2, gpp.noiseSigma2);
    lpg = [lpg lpgs(1).*gpcf.noiseSigma2+1 lpgs(2:end)];
  end
end

function DKff = gpcf_noise_cfg(gpcf, x, x2, mask, i1)
%GPCF_NOISE_CFG  Evaluate gradient of covariance function
%                with respect to the parameters
%
%  Description
%    DKff = GPCF_NOISE_CFG(GPCF, X) takes a covariance function
%    data structure GPCF, a matrix X of input vectors and returns
%    DKff, the gradients of covariance matrix Kff = k(X,X) with
%    respect to th (cell array with matrix elements). This is a
%    mandatory subfunction used in gradient computations.
%
%    DKff = GPCF_NOISE_CFG(GPCF, X, X2) takes a covariance
%    function data structure GPCF, a matrix X of input vectors
%    and returns DKff, the gradients of covariance matrix Kff =
%    k(X,X2) with respect to th (cell array with matrix
%    elements). This subfunction is needed when using sparse
%    approximations (e.g. FIC).
%
%    DKff = GPCF_NOISE_CFG(GPCF, X, [], MASK) takes a covariance
%    function data structure GPCF, a matrix X of input vectors
%    and returns DKff, the diagonal of gradients of covariance
%    matrix Kff = k(X,X2) with respect to th (cell array with
%    matrix elements). This subfunction is needed when using
%    sparse approximations (e.g. FIC).
%
%  See also
%    GPCF_NOISE_PAK, GPCF_NOISE_UNPAK, GPCF_NOISE_E, GP_G

  DKff = {};

  if ~isempty(gpcf.p.noiseSigma2)
    gpp=gpcf.p;
    DKff{1}=gpcf.noiseSigma2;
  end
  if nargin==4
    % Use memory save option
    if i1==0
      % Return number of hyperparameters
      DKff=1;
      return
    end
    DKff=DKff{1};
  end

end

function DKff = gpcf_noise_ginput(gpcf, x, t, i1)
%GPCF_NOISE_GINPUT  Evaluate gradient of covariance function with
%                   respect to x
%
%  Description
%    DKff = GPCF_NOISE_GINPUT(GPCF, X) takes a covariance
%    function data structure GPCF, a matrix X of input vectors
%    and returns DKff, the gradients of covariance matrix Kff =
%    k(X,X) with respect to X (cell array with matrix elements).
%    This subfunction is needed when computing gradients with
%    respect to inducing inputs in sparse approximations.
%
%    DKff = GPCF_NOISE_GINPUT(GPCF, X, X2) takes a covariance
%    function data structure GPCF, a matrix X of input vectors
%    and returns DKff, the gradients of covariance matrix Kff =
%    k(X,X2) with respect to X (cell array with matrix elements).
%    This subfunction is needed when computing gradients with
%    respect to inducing inputs in sparse approximations.
%
%  See also
%    GPCF_NOISE_PAK, GPCF_NOISE_UNPAK, GPCF_NOISE_E, GP_G

end

function C = gpcf_noise_cov(gpcf, x1, x2)
% GP_NOISE_COV     Evaluate covariance matrix between two input vectors
%
%  Description
%    C = GP_NOISE_COV(GP, TX, X) takes in covariance function of
%    a Gaussian process GP and two matrixes TX and X that contain
%    input vectors to GP. Returns covariance matrix C. Every
%    element ij of C contains covariance between inputs i in TX
%    and j in X. This is a mandatory subfunction used for example in
%    prediction and energy computations.
%
%  See also
%    GPCF_NOISE_TRCOV, GPCF_NOISE_TRVAR, GP_COV, GP_TRCOV

  if isempty(x2)
    x2=x1;
  end
  [n1,m1]=size(x1);
  [n2,m2]=size(x2);

  if m1~=m2
    error('the number of columns of X1 and X2 has to be same')
  end

  C = sparse([],[],[],n1,n2,0);
end

function C = gpcf_noise_trcov(gpcf, x)
%GP_NOISE_TRCOV  Evaluate training covariance matrix of inputs
%
%  Description
%    C = GP_NOISE_TRCOV(GP, TX) takes in covariance function of a
%    Gaussian process GP and matrix TX that contains training
%    input vectors. Returns covariance matrix C. Every element ij
%    of C contains covariance between inputs i and j in TX. This is
%    a mandatory subfunction used for example in prediction and
%    energy computations.
%
%
%  See also
%    GPCF_NOISE_COV, GPCF_NOISE_TRVAR, GP_COV, GP_TRCOV

  [n, m] =size(x);
  n1=n+1;

  C = sparse([],[],[],n,n,0);
  C(1:n1:end)=C(1:n1:end)+gpcf.noiseSigma2;

end

function C = gpcf_noise_trvar(gpcf, x)
% GP_NOISE_TRVAR     Evaluate training variance vector
%
%    Description
%    C = GP_NOISE_TRVAR(GPCF, TX) takes in covariance function
%    of a Gaussian process GPCF and matrix TX that contains
%    training inputs. Returns variance vector C. Every
%    element i of C contains variance of input i in TX. This is
%    a mandatory subfunction used for example in prediction and
%    energy computations.
%
%
%    See also
%    GPCF_NOISE_COV, GP_COV, GP_TRCOV

  [n, m] =size(x);
  C=ones(n,1)*gpcf.noiseSigma2;

end

function reccf = gpcf_noise_recappend(reccf, ri, gpcf)
%RECAPPEND Record append
%
%  Description
%    RECCF = GPCF_NOISE_RECAPPEND(RECCF, RI, GPCF) takes a
%    covariance function record structure RECCF, record index RI
%    and covariance function structure GPCF with the current MCMC
%    samples of the hyperparameters. Returns RECCF which contains
%    all the old samples and the current samples from GPCF.
%    This subfunction is needed when using MCMC sampling (gp_mc).
%
%  See also
%    GP_MC and GP_MC -> RECAPPEND

  if nargin == 2
    % Initialize the record
    reccf.type = 'gpcf_noise';

    % Initialize parameters
    reccf.noiseSigma2 = [];

    % Set the function handles
    reccf.fh.pak = @gpcf_noise_pak;
    reccf.fh.unpak = @gpcf_noise_unpak;
    reccf.fh.e = @gpcf_noise_lp;
    reccf.fh.lpg = @gpcf_noise_lpg;
    reccf.fh.cfg = @gpcf_noise_cfg;
    reccf.fh.cov = @gpcf_noise_cov;
    reccf.fh.trcov  = @gpcf_noise_trcov;
    reccf.fh.trvar  = @gpcf_noise_trvar;
    %  gpcf.fh.sampling = @hmc2;
    reccf.sampling_opt = hmc2_opt;
    reccf.fh.recappend = @gpcf_noise_recappend;
    reccf.p=[];
    reccf.p.noiseSigma2=[];
    if ~isempty(ri.p.noiseSigma2)
      reccf.p.noiseSigma2 = ri.p.noiseSigma2;
    end
  else
    % Append to the record
    gpp = gpcf.p;

    % record noiseSigma2
    reccf.noiseSigma2(ri,:)=gpcf.noiseSigma2;
    if isfield(gpp,'noiseSigma2') && ~isempty(gpp.noiseSigma2)
      reccf.p.noiseSigma2 = gpp.noiseSigma2.fh.recappend(reccf.p.noiseSigma2, ri, gpcf.p.noiseSigma2);
    end
  end
end


function tetrahedron_monte_carlo ( )

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

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

  return
end


function percent = parfor_progress(N)
%PARFOR_PROGRESS Progress monitor (progress bar) that works with parfor.
%   PARFOR_PROGRESS works by creating a file called parfor_progress.txt in
%   your working directory, and then keeping track of the parfor loop's
%   progress within that file. This workaround is necessary because parfor
%   workers cannot communicate with one another so there is no simple way
%   to know which iterations have finished and which haven't.
%
%   PARFOR_PROGRESS(N) initializes the progress monitor for a set of N
%   upcoming calculations.
%
%   PARFOR_PROGRESS updates the progress inside your parfor loop and
%   displays an updated progress bar.
%
%   PARFOR_PROGRESS(0) deletes parfor_progress.txt and finalizes progress
%   bar.
%
%   To suppress output from any of these functions, just ask for a return
%   variable from the function calls, like PERCENT = PARFOR_PROGRESS which
%   returns the percentage of completion.
%
%   Example:
%
%      N = 100;
%      parfor_progress(N);
%      parfor i=1:N
%         pause(rand); % Replace with real code
%         parfor_progress;
%      end
%      parfor_progress(0);
%
%   See also PARFOR.

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

error(nargchk(0, 1, nargin, 'struct'));

if nargin < 1
    N = -1;
end

percent = 0;
w = 50; % Width of progress bar

if N > 0
    f = fopen('parfor_progress.txt', 'w');
    if f<0
        error('Do you have write permissions for %s?', pwd);
    end
    fprintf(f, '%d\n', N); % Save N at the top of progress.txt
    fclose(f);

    if nargout == 0
        disp(['  0%[>', repmat(' ', 1, w), ']']);
    end
elseif N == 0
    delete('parfor_progress.txt');
    percent = 100;

    if nargout == 0
        disp([repmat(char(8), 1, (w+9)), char(10), '100%[', repmat('=', 1, w+1), ']']);
    end
else
    if ~exist('parfor_progress.txt', 'file')
        error('parfor_progress.txt not found. Run PARFOR_PROGRESS(N) before PARFOR_PROGRESS to initialize parfor_progress.txt.');
    end

    f = fopen('parfor_progress.txt', 'a');
    fprintf(f, '1\n');
    fclose(f);

    f = fopen('parfor_progress.txt', 'r');
    progress = fscanf(f, '%d');
    fclose(f);
    percent = (length(progress)-1)/progress(1)*100;

    if nargout == 0
        perc = sprintf('%3.0f%%', percent); % 4 characters wide, percentage
        disp([repmat(char(8), 1, (w+9)), char(10), perc, '[', repmat('=', 1, round(percent*w/100)), '>', repmat(' ', 1, w - round(percent*w/100)), ']']);
    end
end


function out = iszero(f)
%ISZERO    True for zero TRIGTECH objects.
%   ISZERO(F) returns logical TRUE is F.VALUES has only zero entries and logical
%   FALSE otherwise.

out = ~any(f.values, 1);

if ( any(out) )
    % We need this as any(NaN) = 0, which will pass the test above.
    out = out & ~any(isnan(f.values), 1);
    return
end

end


function test_errors
%TEST_ERRORS tests error handling for the factorize object methods
%
% Example
%   test_errors
%
% See also test_all, factorize1, factorize.

% Copyright 2009, Timothy A. Davis, University of Florida

% the matrix A must be square for factorize1
fprintf ('\nTesting error-handling, error messages expected:\n') ;
ok = true ;
A = rand (3,2) ;
try
    F = factorize1 (A) ;                                                %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% the matrix A must be 2D for factorize
A = ones (2,2,2) ;
try
    F = factorize (A) ;                                                 %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% the matrix A must be full-rank
A = ones (3) ;
try
    F = factorize (A) ;                                                 %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

try
    F = factorize1 (A) ;                                                %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

A = ones (3,2) ;
try
    F = factorize (A) ;                                                 %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

A = ones (2,3) ;
try
    F = factorize (A) ;                                                 %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% cannot use cell indexing
A = rand (3,2) ;
F = factorize (A) ;
try
    C = F {1} ;                                                         %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% cannot use linear indexing of the inverse
S = inverse (A) ;
try
    C = S (1) ;                                                         %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% invalid indexing
try
    C = F (1,1).L ;                                                     %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% invalid indexing
try
    C = F.L (1,1).stuff ;                                               %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% non-existent field
try
    C = F.junk ;                                                        %#ok
    ok = false ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

% can only update/downdate a dense Cholesky factorization
A = rand (2) ;
F = factorize (A) ;
w = rand (2,1) ;
try
    F = F + w ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end
try
    F = F - w ;
catch me
    fprintf ('Expected error: [%s]\n', me.message) ;
end

if (~ok)
    error ('error-handling failed') ;
end
fprintf ('\nAll error-handing tests passed\n') ;


function C = cs_transpose (A)                                               %#ok
%CS_TRANSPOSE transpose a sparse matrix.
%   C = cs_transpose(A), computes C = A'
%   C = cs_transpose(A,-1) computes C=A.'
%   C = cs_transpose(A,1) computes C=A'
%
%   Example:
%       Prob = UFget ('HB/ibm32') ; A = Prob.A ;
%       C = cs_transpose (A) ;
%       C-A'
%
%   See also TRANSPOSE, CTRANSPOSE.

%   Copyright 2006-2007, Timothy A. Davis.
%   http://www.cise.ufl.edu/research/sparse

error ('cs_transpose mexFunction not found') ;


function flag = areBinaryWeights(weights)
% Check the input vector is (approximately) a binary vectory
flag = true;
th = 1e-12;
for i = length(weights):-1:1
    if weights(i) > th && abs(1 - weights(i)) > th
        flag = false;
        break
    end
end
end


function [anybad] = check_spm_matfiles(P)
% Check a list of SPM-style images to see if they all have the same
% space, dims.
%
% :Usage:
% ::
%
%     [anybad] = check_spm_matfiles(P)
%

V=spm_vol(P);
for i=2:length(V),
    chk = V(1).mat - V(i).mat; chk = chk(:);
    chk = chk(1:end-1);             % eliminate SPM scale factor
    chk = any(chk);
    notok(i) = chk;
end

if any(notok)
    wh = find(notok);

    disp(['The following images'' mat files differend from the first:'])
    disp(num2str(wh));

    disp(['First mat:']);
    disp(V(1).mat);

    disp(['Bad mats:']);
    for i = wh
        disp(V(i).fname);
        disp(V(i).mat);
    end
end

anybad = any(notok);
return


% ?Rahul Kala, IIIT Allahabad, Creative Commons Attribution-ShareAlike 4.0 International License.
% The use of this code, its parts and all the materials in the text; creation of derivatives and their publication; and sharing the code publically is permitted without permission.
% Please cite the work in all materials as: R. Kala (2014) Code for Robot Path Planning using Bidirectional Rapidly-exploring Random Trees, Indian Institute of Information Technology Allahabad, Available at: http://rkala.in/codes.html

function feasible=feasiblePoint(point,map)
feasible=true;
% check if collission-free spot and inside maps
if ~(point(1)>=1 && point(1)<=size(map,1) && point(2)>=1 && point(2)<=size(map,2) && map(point(1),point(2))==1)
    feasible=false;
end


function data = read_data()

fprintf('Reading data ...\n');
fid = fopen('TrainingData.csv');
fgetl(fid);

data = zeros(37821,95);
days = {'"Saturday"','"Sunday"','"Monday"','"Tuesday"','"Wednesday"','"Thursday"','"Friday"'};
row_cnt = 0;

while ~feof(fid)
    row_cnt = row_cnt + 1;
    line = fgetl(fid);
    C = strread(line,'%s','delimiter',',');
    for i=1:95
        if i==5
            data(row_cnt,5) = find(strcmp(days,C{5}));
        else
            if strcmp(C{i},'NA')
                data(row_cnt,i) = -1000000;
            else
                data(row_cnt,i) = str2num(C{i});
            end
        end
    end
end

fprintf('Read in %d rows\n', row_cnt);


function st_io_test02 ( )

%*****************************************************************************80
%
%% ST_IO_TEST02 tests ST_HEADER_READ, ST_DATA_READ.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 July 2014
%
%  Author:
%
%    John Burkardt
%
  input_filename = 'kershaw.st';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'ST_IO_TEST02\n' );
  fprintf ( 1, '  ST_HEADER_READ reads the header from an ST file.\n' );
  fprintf ( 1, '  ST_DATA_READ reads the data from an ST file.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read the data from "%s".\n', input_filename );

  [ i_min, i_max, j_min, j_max, m, n, nst ] = st_header_read ( input_filename );

  st_header_print ( i_min, i_max, j_min, j_max, m, n, nst );

  [ ist, jst, ast ] = st_data_read ( input_filename, m, n, nst );

  st_print ( m, n, nst, ist, jst, ast, '  Sparse Triplet (ST) data from file' );

  return
end


function [b,ndx,pos] = uniquesafe(a,flag)
% Ripped unique
% For safety, we use 7.0 (6.1 sort differently...)

nIn = nargin;

if nIn < 1
  error('MATLAB:UNIQUE:NotEnoughInputs', 'Not enough input arguments.');
elseif nIn > 2
  error('MATLAB:UNIQUE:TooManyInputs', 'Too many input arguments.');
end

if nIn == 1
  flag = [];
end

rows = size(a,1);
cols = size(a,2);

rowvec = (rows == 1) & (cols > 1);

numelA = prod(size(a));
nOut = nargout;

if isempty(flag)

  % Handle empty: no elements.

  if (numelA == 0)
    % Predefine b to be of the correct type.
    b = a([]);
    if max(size(a)) > 0
      b = reshape(b,0,1);
      ndx = zeros(0,1);
      pos = zeros(0,1);
    else
      ndx = [];
      pos = [];
    end
    return

  elseif (numelA == 1)
    % Scalar A: return the existing value of A.
    b = a; ndx = 1; pos = 1;
    return

    % General handling.
  else

    % Convert to columns
    a = a(:);

    % Convert to double array for purposes of faster sorting.
    % Additionally, UNIQUE calls DIFF, which requires double input.

    whichclass = class(a);
    isdouble = strcmp(whichclass,'double');

    if ~isdouble
      a = double(a);
    end

    % Sort if unsorted.  Only check this for long lists.

    checksortcut = 1000;

    if numelA <= checksortcut | ~(issorted(a))
      if nOut <= 1
        b = sort(a);
      else
        [b,ndx] = sort(a);
      end
    else
      b = a;
      if nOut > 1
        ndx = (1:numelA)';  % If presorted, indices are 1,2,3,...
      end
    end

    % d indicates the location of non-matching entries.

    db = diff(b);

    % Since DIFF returns NaN in both Inf and NaN cases,
    % use slower method of detection if NaN's detected in DIFF(b).
    % After sort, Infs or NaNs will be at ends of list only.

    if (isnan(db(1)) | isnan(db(numelA-1)))
      d = b(1:numelA-1) ~= b(2:numelA);
    else
      d = db ~= 0;
    end

    d(numelA,1) = 1;    % Final element is always member of unique list.

    b = b(d);         % Create unique list by indexing into sorted list.

    if nOut == 3
      pos = cumsum([1;full(d)]);  % Lists position, starting at 1.
      pos(numelA+1) = [];         % Remove extra element introduced by d.
      pos(ndx) = pos;             % Re-reference POS to indexing of SORT.
    end

    % Create indices if needed.
    if nOut > 1
      ndx = ndx(d);
    end

    % Re-convert to correct output data type using FEVAL.
    if ~isdouble
      b = feval(whichclass,b);
    end
  end

  % If row vector, return as row vector.
  if rowvec
    b = b.';
    if nOut > 1
      ndx = ndx.';
      if nOut > 2
        pos = pos.';
      end
    end
  end

else    % 'rows' case
  if ~strcmpi(flag,'rows')
    error('MATLAB:UNIQUE:UnknownFlag', 'Unknown flag.');
  end

  % Handle empty: no rows.

  if (rows == 0)
    % Predefine b to be of the correct type.
    b = a([]);
    ndx = [];
    pos = [];
    b = reshape(b,0,cols);
    if cols > 0
      ndx = reshape(ndx,0,1);
    end
    return

    % Handle scalar: one row.

  elseif (rows == 1)
    b = a; ndx = 1; pos = 1;
    return
  end

  % General handling.
  % Conversion to double not done: SORTROWS is slower for doubles
  % than other types.

  if nOut > 1
    [b,ndx] = sortrows(a);
  else
    b = sortrows(a);
  end

  % d indicates the location of non-matching entries.

  d = b(1:rows-1,:)~=b(2:rows,:);

  % d = 1 if differences between rows.  d = 0 if the rows are equal.

  d = any(d,2);
  d(rows,1) = 1;      % Final row is always member of unique list.

  b = b(d,:);         % Create unique list by indexing into sorted list.

  % Create position mapping vector using CUMSUM.

  if nOut == 3
        pos = cumsum([1;full(d)]);  % Lists position, starting at 1.
        pos(rows+1) = [];           % Remove extra element introduced by d.
        pos(ndx) = pos;             % Re-reference POS to indexing of SORT.
  end

  % Create indices if needed.
  if nOut > 1
    ndx = ndx(d);
  end
end


function jed = epoch_to_jed_jelali ( )

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

  return
end


function [ torque ] = getExternalTorqueAtJoint( tKuka,k )
%% This function is used to get the external torque at some joint, for the KUKA iiwa robot.

%% Syntax:
% [ torque ] = getExternalTorqueAtJoint( tKuka,k )

%% About:
% This function is used to get external torque (due to external forces) at
% some joint of the robot.

%% Arreguments:
% tKuka: is the TCP/IP connection
% k: is joint index. A number from 1 to 7.
% torque: is the value of the torque measured at joint (k) due to external
% force/moment acting on the robot. Unit (Newton.meter)

% Copyright, Mohammad SAFEEA, 11th of May 2017

	if(k>7)
	    disp('Error KUKA has only 7 joints');
	    return;
	end

	if(k<1)
	disp('Error, joint number shall be more than zero and less than eight');
	    return;
	end

	[ torques ] = getJointsExternalTorques( tKuka );
	torque=torques{k};
end


classdef polyMesh
% POLYMESH Class for 3d polygon meshes.

    properties (SetAccess = public, GetAccess = public)
        % Vertices
        vertices

        % Faces
        faces
    end

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

    methods

        function obj = polyMesh(meshData)
        % POLYMESH Import of mesh data.
        % ----------------------------------------------------------------------
        % INPUT
        % [meshData]
        % Mesh input data as ply file. Currently no other formats are
        % supported.
        % ----------------------------------------------------------------------
        % OUTPUT
        % [obj]
        % Object instance of class polyMesh.
        % ----------------------------------------------------------------------
        % philipp.glira@gmail.com
        % ----------------------------------------------------------------------

        % Input parsing --------------------------------------------------------

        p = inputParser;
        p.addRequired('meshData', @(x) ischar(x));
        p.parse(meshData);
        p = p.Results;
        % Clear required inputs to avoid confusion
        clear meshData

        % Check if input file exists -------------------------------------------

        if ischar(p.meshData)
            if exist(p.meshData) ~= 2
                error('File ''%s'' does not exist!', p.meshData);
            end
        end

        % Start ----------------------------------------------------------------

        procHierarchy = {'POLYMESH' 'IMPORT'};
        msg('S', procHierarchy);

        % Import of mesh -------------------------------------------------------

        data = plyread(p.meshData);

        obj.vertices = [data.vertex.x data.vertex.y data.vertex.z];
        obj.faces    = vertcat(data.face.vertex_indices{:}) + 1; % increase IDs by one!

        % End ------------------------------------------------------------------

        procHierarchy = {'POLYMESH' 'IMPORT'};
        msg('E', procHierarchy);

        end

    end

end


function dat = read_egis_data(filename, hdr, begtrial, endtrial, chanindx)

% READ_EGIS_DATA reads the data from an EGI EGIS format file
%
% Use as
%   dat = read_egis_data(filename, hdr, begtrial, endtrial, chanindx);
% where
%   filename       name of the input file
%   hdr            header structure, see FT_READ_HEADER
%   begtrial       first trial to read, mutually exclusive with begsample+endsample
%   endtrial       last trial to read,  mutually exclusive with begsample+endsample
%   chanindx       list with channel indices to read
%
% This function returns a 3-D matrix of size Nchans*Nsamples*Ntrials.
% Note that EGIS session files are defined as always being epoched.
% For session files the trials are organized with the members of each cell grouped
% together.  For average files the "trials" (subjects) are organized with the cells
% also grouped together (e.g., "cell1sub1, cell1sub2, ...).
%_______________________________________________________________________
%
%
% Modified from EGI's EGI Toolbox with permission 2007-06-28 Joseph Dien

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

fh=fopen_or_error([filename],'r');
fclose(fh);

[fhdr,chdr,ename,cnames,fcom,ftext] = read_egis_header(filename);
fh=fopen_or_error([filename],'r');
fhdr(1)=fread(fh,1,'int32'); %BytOrd
[str,maxsize,cEndian]=computer;
if fhdr(1)==16909060
    if cEndian == 'B'
        endian = 'ieee-be';
    elseif cEndian == 'L'
        endian = 'ieee-le';
    end
elseif fhdr(1)==67305985
    if cEndian == 'B'
        endian = 'ieee-le';
    elseif cEndian == 'L'
        endian = 'ieee-be';
    end
else
    ft_error('This is not an EGIS average file.');
end

if fhdr(2) == -1
    fileType = 'ave';
elseif fhdr(2) == 3
    fileType = 'ses';
else
    ft_error('This is not an EGIS file.');
end

dat=zeros(hdr.nChans,hdr.nSamples,endtrial-begtrial+1);

%read to end of file header
status=fseek(fh,(130+(2*fhdr(18))+(4*fhdr(19))),'bof');
status=fseek(fh,2,'cof');
for loop=1:fhdr(18)
  temp=fread(fh,80,'uchar');
  theName=strtok(temp);
  theName=strtok(theName,char(0));
  cnames{loop}=deblank(char(theName))';
  status=fseek(fh,fhdr(24+(loop-1))-80,'cof');
end
fcom=fread(fh,fhdr(20),'uchar');
ftext=fread(fh,fhdr(21),'uchar');
fpad=fread(fh,fhdr(22),'uchar');
status=fseek(fh,-2,'cof');

%read to start of desired data
fseek(fh, ((begtrial-1)*hdr.nChans*hdr.nSamples*2), 'cof');

for segment=1:(endtrial-begtrial+1)
    dat(:,:,segment) = fread(fh, [hdr.nChans, hdr.nSamples],'int16',endian);
end
dat=dat(chanindx, :,:);

if fileType == 'ave'
    dat=dat/fhdr(12); %convert to microvolts
elseif fileType == 'ses'
    dat=dat/5; %convert to microvolts (EGIS sess files created by NetStation use a 5 bins per microvolt scaling)
end

fclose(fh);


function[x]=cellreal(x)
%CELLREAL  Real part of each element in a cell array.
%
%   XR=CELLREAL(X) where X is a cell array of N arrays, is equivalent to
%
%      XR{1}=REAL(X{1}), XR{2}=REAL(X{2}), ..., XR{N}=REAL(X{N})
%
%   thus returning the real part of each element in the cell array.
%
%   See also JCELL.
%
%   Usage: xr=cellreal(x);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2009--2019 J.M. Lilly --- type 'help jlab_license' for details

if ~iscell(x)
    error('X must be a cell array.')
end
for i=1:length(x)
    x{i}=real(x{i});
end


function [X,Y,Z] = unplot(filename)
%%To unplot data from a matlab figure (.fig) files generated
% using version 7 or later. It can be used for both 2D and 3D plots
% Example usage:
% To unplot 2D graphs
% [x,y] = unplot('example2D.fig')
% To unplot 3D graphs
% [x,y,z] = unplot('example3D.fig')

% Pradyumna
% January 2012

if nargin==1
    fig1 = load (filename,'-mat');
    a = fig1.hgS_070000.children.children(1,1).properties;
    if isfield(a,'ZData')
        % unploting 3D plot
        Y = fig1.hgS_070000.children.children(1,1).properties.YData;
        X = fig1.hgS_070000.children.children(1,1).properties.XData;
        Z = fig1.hgS_070000.children.children(1,1).properties.ZData;
    else
        % unploting 2D plot
        Y = fig1.hgS_070000.children.children(1,1).properties.YData;
        X = fig1.hgS_070000.children.children(1,1).properties.XData;
    end
else
    disp('Usage unplot(''filename.fig''). See ''help unplot'' for more details');
end


function alpha = p00_alpha ( problem )

%*****************************************************************************80
%
%% P00_ALPHA returns the value of ALPHA for any problem.
%
%  Discussion:
%
%    ALPHA is the lower, finite limit of integration in the integral.
%
%    The typical or default value is 0.0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the index of the problem.
%
%    Output, real ALPHA, the value of ALPHA.
%
  if ( problem == 1 )
    alpha = p01_alpha ( );
  elseif ( problem == 2 )
    alpha = p02_alpha ( );
  elseif ( problem == 3 )
    alpha = p03_alpha ( );
  elseif ( problem == 4 )
    alpha = p04_alpha ( );
  elseif ( problem == 5 )
    alpha = p05_alpha ( );
  elseif ( problem == 6 )
    alpha = p06_alpha ( );
  elseif ( problem == 7 )
    alpha = p07_alpha ( );
  elseif ( problem == 8 )
    alpha = p08_alpha ( );
  elseif ( problem == 9 )
    alpha = p09_alpha ( );
  elseif ( problem == 10 )
    alpha = p10_alpha ( );
  elseif ( problem == 11 )
    alpha = p11_alpha ( );
  elseif ( problem == 12 )
    alpha = p12_alpha ( );
  elseif ( problem == 13 )
    alpha = p13_alpha ( );
  elseif ( problem == 14 )
    alpha = p14_alpha ( );
  elseif ( problem == 15 )
    alpha = p15_alpha ( );
  elseif ( problem == 16 )
    alpha = p16_alpha ( );
  elseif ( problem == 17 )
    alpha = p17_alpha ( );
  elseif ( problem == 18 )
    alpha = p18_alpha ( );
  elseif ( problem == 19 )
    alpha = p19_alpha ( );
  elseif ( problem == 20 )
    alpha = p20_alpha ( );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_ALPHA - Fatal error!\n' );
    fprintf ( 1, '  Illegal problem number = %d\n', problem );
    error ( 'P00_ALPHA - Fatal error!' );
  end

  return
end


function nodesIdxs = nodeBForder(nodeNo,wt)
%NODEBFORDER Nodes in the Breadth-First search order
%  Usage:  nodesIdxs = nodeBForder(nodeNo,wt)
%
%   Input parameters:
%         nodeNo : Id of a node.
%         wt     : Structure containing description of the filter tree.
%
%   Output parameters:
%         nodesIdxs   : Node indexes in the Breadth-First search order.
%
%   `nodeBForder(nodeNo,wt)` For definition of the structure see
%   `wfbinit`. `nodeNo` defaults to the root node if it is empty or equal
%   to 0.
%
%
%   See also: wfbtinit
%

if isempty(nodeNo) || nodeNo==0
   %find root
   nodeNo = find(wt.parents==0);
end

complainif_notposint(nodeNo,'NODEBFORDER');

nodesIdxs = [nodeNo,nodeSubtreeBF(nodeNo,wt)];

function nodesIdxs = nodeSubtreeBF(nodeNo,wt)
%NODESUBTREEBF Node subtree nodes in Breath-First order
%   Usage:  noOut = nodeSubtreeBF(nodeNo,wt);
%
%   Input parameters:
%         nodeNo  : Node index.
%         wt      : Structure containing description of the filter tree.
%
%   Output parameters:
%         noOut   : Nodes in a Breath-First order.
%

% subtreeIdx = [];
%
% children = treeStruct.children{nodeNo}(find(treeStruct.children{nodeNo}~=0));
% subtreeIdx(end+1:end+length(children)) = children;
%
% for ii=1:length(children)
%    tmpSbIdx = nodeSubtreeBF(children(ii),treeStruct);
%    subtreeIdx(end+1:end+length(tmpSbIdx)) = tmpSbIdx;
% end

toGoTrough = [nodeNo];
nodesIdxs = [];
while ~isempty(toGoTrough)
  % chtmp = find(wt.children{toGoTrough(1)}~=0);
   chIdxtmp = wt.children{toGoTrough(1)}(wt.children{toGoTrough(1)}~=0);
   nodesIdxs = [nodesIdxs,chIdxtmp];
   toGoTrough = [toGoTrough(2:end),chIdxtmp];
end


function varargout = im2metaimage( str, res, scale, crop, ext, file )
% IM2METAIMAGE  Read a batch of image files, collate them and save as a
% single MetaImage "file" (actually, one .mha and one .raw file)
%
% IM2METAIMAGE(STR)
%
%   STR is a string with the path and output mha header file name. For
%   example,
%
%     STR='/home/john/data/study01/study01.mha'; % linux
%     STR='C:\data\study01\study01.mha';         % windows
%
%   It is assumed that the MetaImage file (.mha) will be created
%   from the image files found in the target directory.
%
% IM2METAIMAGE(STR, RES, SCALE, CROP, EXT, FILE)
%
%   RES is a 3-vector with the pixel size in the x-, y- and z-coordinates.
%   By default RES=[1 1 1];
%
%   SCALE is a scalar factor to reduce the size of each frame (the number
%   of frames doesn't change). By default, SCALE=1.
%
%   CROP is a vector with values [xmin, xmax, ymin, ymax, zmin, zmax].
%   These values allow to crop the data volume. It follows the same
%   convention as Seg3D [1]. For example, if xmin=0, xmax=3, then voxels 1,
%   2 and 3 are selected.
%   Note that the output MetaImage file will have an offset header so that
%   the data retains its true coordinates.
%
%   EXT is a string with the file extension of the images. By default,
%   EXT='tif'.
%
%   FILE is the list of image files. By default, all the files in the
%   target directory are read, but FILE allows to change the system listing
%   order, select a subset of files, etc. This is useful, for example, when
%   the system listing order does not correspond to the order in which you
%   want to collate the slices. FILE is expected to have the same struct
%   format as the output of function DIR().
%
%   If you have filenames like
%
%    MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.10.2009.10.23.16.02.38.562500.9699412.BMP
%    MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.11.2009.10.23.16.02.38.562500.9699451.BMP
%    MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.1.2009.10.23.16.02.38.562500.9699056.BMP
%    MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.12.2009.10.23.16.02.38.562500.9699490.BMP
%
%   where the slice order is given by the field between the "6" and the
%   "2009", then you can use Gerardus function sortdirbynum() to order the
%   slices correctly. Example:
%
%   >> str1 = 'MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.*.BMP';
%   >> str2 = 'MISAS_DT_22_10_2009.MR.HEAD_GENERAL.6.mha';
%   >> file = sortdirbynum( str1, 5, '.' );
%   >> im2metaimage( str2, [], [], [], 'BMP', file );
%
% IM = IM2METAIMAGE(...);
%
%   IM is the image volume.
%
% [1] http://www.sci.utah.edu/cibc/software/seg3d.html

% Author: Ramon Casero <rcasero@gmail.com>
% Copyright © 2009 University of Oxford
% Version: 0.1.1
%
% University of Oxford means the Chancellor, Masters and Scholars of
% the University of Oxford, having an administrative office at
% Wellington Square, Oxford OX1 2JD, UK.
%
% This file is part of Gerardus.
%
% 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. The offer of this
% program under the terms of the License is subject to the License
% being interpreted in accordance with English Law and subject to any
% action against the University of Oxford being under the jurisdiction
% of the English Courts.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

% check arguments
error( nargchk( 1, 6, nargin, 'struct' ) );
error( nargoutchk( 0, 1, nargout, 'struct' ) );

% defaults
if ( nargin < 2 || isempty( res ) )
    res = [ 1, 1, 1 ];
end
if ( nargin < 3 || isempty( scale ) )
    scale = 1;
end
if ( nargin < 4 || isempty( crop ) )
    crop = [];
end
if ( nargin < 5 || isempty( ext ) )
    ext = 'tif';
end
if ( nargin < 6 || isempty( file ) )
    file = [];
end

% check arguments
if ( scale <= 0 || scale > 1 )
    error( 'SCALE must be in (0, 1]' );
end

% get path to the data files
[ dirdata, name ] = fileparts( str );

% get list of image files
if isempty( file )
    file = dir( [ dirdata filesep '*.' ext ] );
end

% adjust the image resolution to the scaling factor
res( 1:2 ) = res( 1:2 ) / scale;

% load first slice
frame = imread( [ dirdata filesep file( 1 ).name ] );

% remove alpha channel or other layers if present
frame = frame( :, :, 1 );

% init volume to load data
im = zeros( [ size( frame )*scale length( file ) ], class( frame ) );

% load slices of whole volume
im( :, :, 1 ) = imresize( frame, scale, 'bilinear' );
for I = 2:length( file )
    frame = imread( [ dirdata filesep file( I ).name ] );
    frame = frame( :, :, 1 );
    % resize frames
    im( :, :, I ) = imresize( frame, scale, 'bilinear' );
end

% crop volume (this is less efficient than initialising the volume as
% cropped, and then cropping each frame, but it makes the code simpler)
%
% The "+1" is necessary to follow the Seg3D convention
if ~isempty( crop )
    im = im( ...
        crop( 1 )+1:crop( 2 ), ...
        crop( 3 )+1:crop( 4 ), ...
        crop( 5 )+1:crop( 6 ) ...
        );
end

% compute offset in the coordinates of the cropped volume
if isempty( crop )
    offset = [ 0.0 0.0 0.0 ];
else
    offset = crop( [ 1 3 5 ] ) .* res;
end

% write mha file
writemetaimagefile([dirdata filesep name '.mha'], im, res, offset);

% avoid outputing the image volume unless the user has requested it
% explicitly
if ( nargout == 0 )
    varargout = [];
else
    varargout = { im };
end


function SVF = normal
% the normal vector field
%

SVF = S2VectorFieldHandle(@(v) v);

end


function [imgStats] = computeImageFeatures(inputImages, varargin)
	% [imgStats] = computeImageFeatures(inputImages, varargin)
	%
	% Filters large and small objects in an set of images, returns filtered matricies along with vector with decisions and sizes.
	%
	% Biafra Ahanonu
	% 2013.10.31
	% based on SpikeE code
	%
	% inputs
	%   inputImages - [x y nSignals]
	%
	% outputs
	%   imgStats -
	%
	% options
	%   minNumPixels
	%   maxNumPixels
	%   thresholdImages

	% changelog
		% updated: 2013.11.08 [09:24:12] removeSmallICs now calls a filterImages, name-change due to alteration in function, can slowly replace in codes
		% 2017.01.14 [20:06:04] - support switched from [nSignals x y] to [x y nSignals]
		% 2019.07.17 [00:29:16] - Added support for sparse input images (mainly ndSparse format).
		% 2019.09.10 [20:51:00] - Converted to parfor and removed unpacking options, bad practice.
		% 2019.10.02 [21:25:36] - Updated addedFeatures support for parfor and allowed this feature to be properly accessed by users.
		% 2021.08.08 [19:30:20] - Updated to handle CIAtah v4.0 switch to all functions inside ciapkg package.
		% 2022.04.13 [02:28:15] - Make default thresholding fast thresholding.
		% 2022.07.20 [14:42:00] - Improved annotation of code and added options.fastThresholding. Also by default plots are not made. Refactored extra features code and finding centroid to avoid unnecessary function calls, speeding up code.
	% TODO
		%

	import ciapkg.api.* % import CIAtah functions in ciapkg package API.

	%========================
	% get options
	options.minNumPixels = 25;
	options.maxNumPixels = 600;
	options.makePlots = 0;
	options.waitbarOn = 1;
	options.thresholdImages = 1;
	options.threshold = 0.5;
	options.valid = [];
	% options.featureList = {'Eccentricity','EquivDiameter','Area','Orientation','Perimeter','Solidity',};
	options.featureList = {'Eccentricity','EquivDiameter','Area','Orientation','Perimeter'};
	% Whether to calculate non-regionprops
	options.addedFeatures = 0;
	% Input images for add features
	options.addedFeaturesInputImages = [];
	options.runRegionprops = 1;
	%
	options.xCoords = [];
	options.yCoords = [];
	%
	options.parforAltSwitch = 0;
	% Binary: 1 = fast thresholding (vectorized), 0 = normal thresholding
	options.fastThresholding = 1;
	% image filter: none, median,
	options.imageFilter = 'none';

	% Binary: 1 = whether to display info on command line.
	options.displayInfo = 1;

	options = getOptions(options,varargin);
	% unpack options into current workspace
	% fn=fieldnames(options);
	% for i=1:length(fn)
	% 	eval([fn{i} '=options.' fn{i} ';']);
	% end
	%========================

	parforAltSwitch = options.parforAltSwitch;
	% switch nargin
	% 	case 2
	% 		parforAltSwitch = 1;
	% 	case 1
	% 		% do nothing
	% 	otherwise
	% 		% do nothing
	% end

	nImages = size(inputImages,3);

	% reverseStr = '';
	% decide whether to threshold images
	if options.thresholdImages==1
		if options.addedFeatures==1&&isempty(options.addedFeaturesInputImages)
			options.addedFeaturesInputImages = inputImages;
		end
		inputImages = thresholdImages(inputImages,'waitbarOn',1,'binary',1,'threshold',options.threshold,'fastThresholding',options.fastThresholding,'removeUnconnected',1,'imageFilter',options.imageFilter);
	end

	% Only implement in Matlab 2017a and above
	if ~verLessThan('matlab', '9.2')
		D = parallel.pool.DataQueue;
		afterEach(D, @nUpdateParforProgress);
		p = 1;
		% N = nSignals;
	end
	nInterval = round(nImages/20);

	options_runRegionprops = options.runRegionprops;
	options_featureList = options.featureList;
	options_waitbarOn = options.waitbarOn;

	% loop over images and get their stats
	if options.displayInfo==1
		disp('Computing image features...')
	end
	regionStat = cell([nImages 1]);
	if options_runRegionprops==1
		% ticBytes(gcp)
		parfor imageNo = 1:nImages
			% iImage = squeeze(inputImages(:,:,imageNo));
			% imagesc(iImage)
			% imgStats.imageSizes(imageNo) = sum(iImage(:)>0);
			thisFilt = inputImages(:,:,imageNo);
			if issparse(thisFilt)
				thisFilt = full(thisFilt);
			end
			regionStat{imageNo} = regionprops(thisFilt, options_featureList);
			if ~verLessThan('matlab', '9.2')
				send(D, imageNo); % Update
			end
		end
		% tocBytes(gcp)
		% whos

		% Add region states to the general pool
		if ~verLessThan('matlab', '9.2'); p=1;end
		if options.displayInfo==1
			disp('Adding regionprops features to output...')
		end
		for imageNo = 1:nImages
			for ifeature = options_featureList
				% regionStat = regionprops(iImage, ifeature{1});
				try
					% eval(['imgStats.' ifeature{1} '(imageNo) = regionStat.' ifeature{1} ';']);
					imgStats.(ifeature{1})(imageNo) = regionStat{imageNo}.(ifeature{1});
				catch
					% eval(['imgStats.' ifeature{1} '(imageNo) = NaN;']);
					imgStats.(ifeature{1})(imageNo) = NaN;
				end
			end
			if ~verLessThan('matlab', '9.2')
				send(D, imageNo); % Update
			end
		end
	end

	if ~verLessThan('matlab', '9.2'); p=1;end

	if options.addedFeatures==1
		% get the centroids and other info for movie
		if isempty(options.xCoords)
			[xCoords, yCoords] = findCentroid(inputImages,'waitbarOn',options.waitbarOn,'runImageThreshold',0);
		else
			xCoords = options.xCoords;
			yCoords = options.yCoords;
		end

		if parforAltSwitch==1
			imgKurtosis = NaN([1 nImages]);
			imgSkewness = NaN([1 nImages]);
			if options.displayInfo==1
				disp('Computing alternative image features with parfor...')
			end
			addedFeaturesInputImages = options.addedFeaturesInputImages;
			parfor imageNo = 1:nImages
				thisFilt = addedFeaturesInputImages(:,:,imageNo);
				if issparse(thisFilt)
					thisFilt = full(thisFilt);
				end
				if isnan(xCoords(imageNo))==0
					t1 = getObjCutMovie(thisFilt,thisFilt,'cropSize',30,'createMontage',0,'crossHairsOn',0,'addPadding',1,'waitbarOn',0,'xCoords',xCoords(imageNo),'yCoords',yCoords(imageNo));
					t1 = t1{1};
					imgKurtosis(imageNo) = double(kurtosis(t1(:)));
					imgSkewness(imageNo) = double(skewness(t1(:)));
				else
					imgKurtosis(imageNo) = NaN;
					imgSkewness(imageNo) = NaN;
				end
				if ~verLessThan('matlab', '9.2')
					send(D, imageNo); % Update
				end
			end

			imgStats.imgKurtosis = imgKurtosis;
			imgStats.imgSkewness = imgSkewness;
		else
			if options.displayInfo==1
				disp('Computing alternative image features...')
			end
			for imageNo = 1:nImages
				% iImage2 = squeeze(options.addedFeaturesInputImages(:,:,imageNo));
				% figure(11);imagesc(iImage2);title(num2str(imageNo))
				% [imageNo xCoords(imageNo) yCoords(imageNo)]
				thisFilt = options.addedFeaturesInputImages(:,:,imageNo);
				if issparse(thisFilt)
					thisFilt = full(thisFilt);
				end
				if isnan(xCoords(imageNo))==0
					% t1=getObjCutMovie(options.addedFeaturesInputImages(:,:,imageNo),options.addedFeaturesInputImages(:,:,imageNo),'cropSize',30,'createMontage',0,'crossHairsOn',0,'addPadding',1,'waitbarOn',0,'xCoords',xCoords(imageNo),'yCoords',yCoords(imageNo));
					t1 = getObjCutMovie(thisFilt,thisFilt,'cropSize',30,'createMontage',0,'crossHairsOn',0,'addPadding',1,'waitbarOn',0,'xCoords',xCoords(imageNo),'yCoords',yCoords(imageNo));
					t1 = t1{1};
					imgStats.imgKurtosis(imageNo) = double(kurtosis(t1(:)));
					imgStats.imgSkewness(imageNo) = double(skewness(t1(:)));
				else
					imgStats.imgKurtosis(imageNo) = NaN;
					imgStats.imgSkewness(imageNo) = NaN;
				end
				% imgStats.imgKurtosis(imageNo) = kurtosis(iImage(:));
				% imgStats.imgSkewness(imageNo) = skewness(iImage(:));
				if ~verLessThan('matlab', '9.2')
					send(D, imageNo); % Update
				end
			end
		end
	end

	if options.makePlots==1
		if isfield(imgStats,'Area')==1
			openFigure(1996, '');
				subplot(2,1,1)
				hist(imgStats.Area,round(logspace(0,log10(max(imgStats.Area)))));
				box off;title('distribution of IC sizes');xlabel('area (px^2)');ylabel('count');
				set(gca,'xscale','log');
				h = findobj(gca,'Type','patch');
				set(h,'FaceColor',[0 0 0],'EdgeColor','w');
		end
		if ~isempty(options.valid)
			nPts = 2;
		else
			options.valid = ones(1,nImages);
			nPts = 1;
		end
		pointColors = ['g','r'];
		openFigure(1997, '');
			for pointNum = 1:nPts
				pointColor = pointColors(pointNum);
				if pointNum==1
					valid = logical(options.valid);
				else
					valid = logical(~options.valid);
				end
				openFigure(1997, '');
				fn=fieldnames(imgStats);
				for i=1:length(fn)
					subplot(2,ceil(length(fn)/2),i)
					% eval(['iStat=imgStats.' fn{i} ';']);
					% plot(find(valid),iStat(valid),[pointColor '.'])
					plot(find(valid),imgStats.(fn{i})(valid),[pointColor '.'])
					title(fn{i})
					hold on;box off;
					xlabel('rank'); ylabel(fn{i})
					hold off
				end
			end

	end
	function nUpdateParforProgress(~)
		if ~verLessThan('matlab', '9.2')
			p = p + 1;
			% if (mod(p,nInterval)==0||p==nImages)&&options_waitbarOn==1
			% 	cmdWaitbar(p,nImages,'','inputStr','','waitbarOn',1);
			% end
			if (mod(p,nInterval)==0||p==2||p==nImages)&&options_waitbarOn==1
				if p==nImages
					fprintf('%d\n',round(p/nImages*100))
				else
					fprintf('%d|',round(p/nImages*100))
				end
				% cmdWaitbar(p,nImages,'','inputStr','','waitbarOn',1);
			end
		end
	end
end

% OLD code

% regionStat
% figure;imagesc(inputImages(:,:,imageNo));
% for ifeature = featureList
% 	% regionStat = regionprops(iImage, ifeature{1});
% 	try
% 		% eval(['imgStats.' ifeature{1} '(imageNo) = regionStat.' ifeature{1} ';']);
% 		imgStats.(ifeature{1})(imageNo) = regionStat.(ifeature{1});
% 	catch
% 		% eval(['imgStats.' ifeature{1} '(imageNo) = NaN;']);
% 		imgStats.(ifeature{1})(imageNo) = NaN;
% 	end
% end

% regionStat = regionprops(iImage, 'Eccentricity','EquivDiameter','Area','Orientation','Perimeter','Solidity');
% imgStats.Eccentricity(imageNo) = regionStat.Eccentricity;
% imgStats.EquivDiameter(imageNo) = regionStat.EquivDiameter;
% imgStats.Area(imageNo) = regionStat.Area;
% imgStats.Orientation(imageNo) = regionStat.Orientation;
% imgStats.Perimeter(imageNo) = regionStat.Perimeter;
% imgStats.Solidity(imageNo) = regionStat.Solidity;

% if (imageNo==1||mod(imageNo,10)==0||imageNo==nImages)&&options.waitbarOn==1
% 	reverseStr = cmdWaitbar(imageNo,nImages,reverseStr,'inputStr','computing image features');
% end

% subplot(2,1,1)
% scatter3(imgStats.Eccentricity(valid),imgStats.Perimeter(valid),imgStats.Orientation(valid),[pointColor '.'])
% xlabel('Eccentricity');ylabel('perimeter');zlabel('Orientation');
% rotate3d on;hold on;
% subplot(2,1,2)
% scatter3(imgStats.Area(valid),imgStats.Perimeter(valid),imgStats.Solidity(valid),[pointColor '.'])
% xlabel('area');ylabel('perimeter');zlabel('solidity');
% rotate3d on;hold on;


function rgb = black

% returns a predefined color as [red green blue] values
%
% skin_surface         = [255 213 119]/255;
% outer_skull_surface  = [140  85  85]/255;
% inner_skull_surface  = [202 100 100]/255;
% cortex = [255 213 119]/255;
% black  = [0   0   0  ]/255;
% white  = [255 255 255]/255;
% red    = [255 0   0  ]/255;
% green  = [0   192 0  ]/255;
% blue   = [0   0   255]/255;
% yellow = [255 255 0  ]/255;
% cortex_light = [199 194 169]/255;
% cortex_dark  = [100 97 85]/255;

rgb = [0   0   0  ]/255;


function [cc] = cm32cc(cm3)
% Convert volume from cubic centimeters to cubic centimeters.
% Chad Greene 2012
cc = cm3;


%kiconvolve 'Perform convolution or correlation on image data'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros iconvolve.pane file
%
% Parameters:
% InputFile: i1 'Input image', required: 'input image'
% InputFile: i2 'Kernel ', required: 'kernel'
% Toggle: upcast 'Upcast data', default: 0: 'Upcast data to double or double complex for processing'
% Integer: wc 'Width ', default: 0: 'Width coordinate of kernel hotspot'
% Integer: hc 'Height ', default: 0: 'Height coordinate of kernel hotspot'
% OutputFile: o 'Output image', required: 'output image'
%
% Example: o = kiconvolve({i1, i2}, {'i1','';'i2','';'upcast',0;'wc',0;'hc',0;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% iconvolve - Perform convolution or correlation on image data
%
%  DESCRIPTION
% \fBiconvolve" is a simple interface to the more general \fBklinearop\fP
% routine in the DATAMANIP toolbox. \fBiconvolve" is set up to perform
% convolution or correlation on image data (WxHx?x?x?) using a WxH kernel,
% in zero-padded, linear mode (not circular).
%
% The kernel origin, center, or "hotspot" can be set using the -wc and -hc
% arguments; otherwise the KPDS_KERNEL_ORIGIN attribute for the kernel object
% is queried for that information.
%
%
%
%  EXAMPLES
% iconvolve -i1 ball.xv -i2 laplacian -corr 0 -o edges
%
%  "SEE ALSO"
% kfft(1), kconvolve(1)
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

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

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


function handle = imageModify(handle, imageValues, imageSize, transpose, negative, ...
		     scale)

% IMAGEMODIFY Helper code for visualisation of image data.
% FORMAT
% DESC is a helper function for visualising image data using latent
% variable models.
% ARG handle : the handle of the image data.
% ARG imageValues : the values to set the image data to.
% ARG imageSize : the size of the image.
% ARG transpose : whether the resized image needs to be transposed
% (default 1, which is yes).
% ARG negative : whether to display the negative of the image
% (default 0, which is no).
% ARG scale : dummy input, to maintain compatability with
% IMAGEVISUALISE.
% RETURN handle : a the handle to the image data.
%
% COPYRIGHT : Neil D. Lawrence, 2003, 2004, 2006
%
% SEEALSO : imageVisualise, fgplvmResultsDynamic

% MLTOOLS

if nargin < 4
  transpose = 1;
end
if nargin< 5
  negative = 0;
end
if negative
  imageValues = -imageValues;
end
if transpose
  set(handle, 'CData', reshape(imageValues(1:imageSize(1)*imageSize(2)), imageSize(1), imageSize(2))');
else
  set(handle, 'CData', reshape(imageValues(1:imageSize(1)*imageSize(2)), imageSize(1), imageSize(2)));
end


% KDTREE_PRINT prints the structure of a kd-tree
%
% Added by Pablo Sala, November 25, 2008
%
% SYNTAX
% kdtree_print
%
% DESCRIPTION
% Displays the structure of a kd-tree
%

% Copyright (c) 2008 Andrea Tagliasacchi
% All Rights Reserved
% email: ata2@cs.sfu.ca
% $Revision: 1.0$  Created on: 2008/09/15


function out = isreal(f)
%ISREAL   True for real CLASSICFUN.
%   ISREAL(F) returns TRUE if F does not have an imaginary part and FALSE
%   otherwise.
%
% See also REAL, IMAG.

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

% Check if the ONEFUN of f is real:
out = isreal(f.onefun);

end


function box = rectToBox(rect)
%RECTTOBOX Convert rectangle data to box data.
%
%   RECT = rectToBox(BOX)
%   Converts from rectangle representation to box representation.
%   BOX is given by [XMIN XMAX YMIN YMAX].
%   RECT is given by [X0 Y0 WIDTH HEIGHT], with WIDTH and HEIGHT > 0
%
%   Example
%   rectToBox
%
%   See also
%   boxToRect, drawBox, drawRect

% ------
% Author: David Legland
% E-mail: david.legland@grignon.inra.fr
% Created: 2012-08-23, using Matlab 7.9.0.529 (R2009b)
% Copyright 2012-2022 INRA - Cepia Software Platform

box = [rect(:,1) rect(:,1)+rect(:,3) rect(:,2) rect(:,2)+rect(:,4)];


function drawPnt(h,x,c)

% DRAWPNT  Draw 3D point with color.
%   DRAWPNT(H,X) Draw 2D or 3D point with handle H at position X.
%
%   DRAWPNT(H,X,C) uses color C.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

if numel(x) == 2

    set(h,'xdata',x(1),'ydata',x(2),'vis','on')

elseif numel(x) == 3

    set(h,'xdata',x(1),'ydata',x(2),'zdata',x(3),'vis','on')

else

    error('??? Size of vector ''x'' not correct.')

end

if nargin == 3
    set(h,'color',c)
end

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB 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.
%
%   SLAMTB 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 SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function test_suite = test_createSoccerBall
%TESTCREATESoccerBall  One-line description here, please.
%
%   output = testCreateSoccerBall(input)
%
%   Example
%   testCreateSoccerBall
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2010-12-07,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRA - Cepia Software Platform.

test_suite = functiontests(localfunctions);

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

createSoccerBall();

function testVEFCreation(testCase)

[v, e, f] = createSoccerBall();
testCase.assertTrue(~isempty(v));
testCase.assertTrue(~isempty(e));
testCase.assertTrue(~isempty(f));

[nv, ne, nf] = getMeshElementsNumber;
testCase.assertEqual([nv 3], size(v));
testCase.assertEqual([ne 2], size(e));
testCase.assertEqual(nf, length(f));

function testVFCreation(testCase)

[v, f] = createSoccerBall();
testCase.assertTrue(~isempty(v));
testCase.assertTrue(~isempty(f));

[nv, ne, nf] = getMeshElementsNumber; %#ok<ASGLU>
testCase.assertEqual([nv 3], size(v));
testCase.assertEqual(nf, length(f));

function testMeshCreation(testCase)

mesh = createSoccerBall();
testCase.assertTrue(isstruct(mesh));
testCase.assertTrue(isfield(mesh, 'vertices'));
testCase.assertTrue(isfield(mesh, 'edges'));
testCase.assertTrue(isfield(mesh, 'faces'));

[nv, ne, nf] = getMeshElementsNumber;
testCase.assertEqual([nv 3], size(mesh.vertices));
testCase.assertEqual([ne 2], size(mesh.edges));
testCase.assertEqual(nf, length(mesh.faces));

function [nv, ne, nf] = getMeshElementsNumber

nv = 60;
ne = 90;
nf = 32;


function [ t_stop, y_stop ] = p30_stop ( neqn )

%*****************************************************************************80
%
%% P30_STOP returns the stopping point for problem p30.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Output, real T_STOP, Y_STOP(NEQN), the final data.
%
  y_stop = zeros ( neqn, 1 );

  t_stop = 20.0;
  y_stop = 1.0;

  return
end


% im = appendimages(image1, image2)
%
% Return a new image that appends the two images side-by-side.

function im = appendimages(image1, image2)

% Select the image with the fewest rows and fill in enough empty rows
%   to make it the same height as the other image.
rows1 = size(image1,1);
rows2 = size(image2,1);

if (rows1 < rows2)
     image1(rows2,1) = 0;
else
     image2(rows1,1) = 0;
end

% Now append both images side-by-side.
im = [image1 image2];


function range = p13_range ( )

%*****************************************************************************80
%
%% P13_RANGE returns an interval bounding the root for problem 13.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real RANGE(2), the minimum and maximum values of
%    an interval containing the root.
%
  range(1) = - 10000000000000.0;
  range(2) =   10000000000000.0;

  return
end


function test_suite = test_bayesoptimization3
    %   Run specific demo, save values and compare the results to the expected.
    %   Works for both xUnit Test Framework package by Steve Eddins and for
    %   the built-in Unit Testing Framework (as of Matlab version 2013b).
    %
    %   See also
    %     TEST_ALL, DEMO_BAYEESOPTIMIZATION
    %
    %  Copyright (c) 2015 Jarno Vanhatalo
    %  Copyright (c) 2017 Eero Siivola

    % This software is distributed under the GNU General Public
    % License (version 3 or later); please refer to the file
    % License.txt, included with the software, for details.

    % Check which package to use
    if exist('initTestSuite', 'file')
    initTestSuite_path = which('initTestSuite');
    else
    initTestSuite_path = '';
    end
    if ~isempty(initTestSuite_path) && ...
     exist([initTestSuite_path(1:end-15) 'runtests'], 'file')
    % xUnit package
    initTestSuite;
    else
    % Built-in package
    % Use all functions except the @setup
    tests = localfunctions;
    tests = tests(~cellfun(@(x)strcmp(func2str(x),'setup'),tests));
    test_suite = functiontests(tests);
    end

end

function testRunDemo(testCase)
  % Run the correspondin demo and save the values. Note this test has to
  % be run at lest once before the other test may succeed.

  % Suppress an expected warning
  Sw = warning('off','MATLAB:nearlySingularMatrix');
  rundemo(getName())
  warning(Sw); % Return the original warning visibility status
end

function testValues(testCase)
  % Test predictive mean and variance
  verifyVarsEqual(testCase, getName(), ...
    {'x'}, ...
    'RelTolElement', 0.01, 'RelTolRange', 0.02)
end

function testEI(testCase)
  % Test predictive mean and variance
  verifyVarsEqual(testCase, getName(), ...
    {'EI'}, ...
    'RelTolElement', 0.01, 'RelTolRange', 0.02)
end

% ------------------------
%     Helper functions
% ------------------------

function testCase = setup
  % Helper function to suply empty array into variable testCase as an
  % argument for each test function, if using xUnit package. Not to be
  % used with built-in test framework.
  testCase = [];
end

function name = getName
  % Helperfunction that returns the name of the demo, e.g. 'binomial1'.
  name = mfilename;
  name = name(6:end);
end


%--- help for checksiz ---
%
% CHECKSIZ Test size consistency among input arguments.
%
%    [ECODE, ERRMSG] = checksiz(SIZES, FUN)
%
%    Inputs:
%     SIZES - An Mx2 matrix containing the size of each input argument.
%
%       FUN - The name of the function from which CHECKSIZ is invoked.
%
%    Outputs:
%     ECODE - Specifies if any size consistencies are violated.
%             1 - Yes
%             0 - No
%
%    ERRMSG - Displays an error message as an output (instead of to the command
%                  window) if boundary conditions are not met.
%
%    For example:
%       To check for input argument size consistency in the function FOO which
%       takes the inputs A and B.
%
%       A = rand(5); B = rand(7);
%       [ecode, errMsg] = checksiz([size(A); size(B)], 'FOO')
%
%       ecode =
%            1
%
%       errMsg =
%       Dimensions of inputs are inconsistent.
%
%    See also CHECKRNG, CHECKTYP.
%


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defop  Method   @@sym subsref {(@var{f}, @var{idx})}
%% @defopx Operator @@sym {@var{f}(@var{i})} {}
%% @defopx Operator @@sym {@var{f}(@var{i}, @var{j})} {}
%% @defopx Operator @@sym {@var{f}(@var{i}:@var{j})} {}
%% @defopx Operator @@sym {@var{f}.property} {}
%% Access entries of a symbolic array.
%%
%% Examples:
%% @example
%% @group
%% A = sym([10 11 12]);
%% A(2)
%%   @result{} (sym) 11
%%
%% A(2:3)
%%   @result{} (sym) [11  12]  (1×2 matrix)
%%
%% A(1, 1)
%%   @result{} (sym) 10
%% @end group
%%
%% @group
%% A.flat
%%   @result{} Matrix([[10, 11, 12]])
%% @end group
%% @end example
%%
%% @seealso{@@sym/subsasgn, @@sym/subsindex, @@sym/end}
%% @end defop

function varargout = subsref (f, idx)

  switch idx.type
    case '()'
      % sym(sym) indexing gets here
      for i = 1:length(idx.subs)
        if (isa(idx.subs{i}, 'sym'))
          idx.subs{i} = subsindex(idx.subs{i})+1;
        end
      end
      for i = 1:length(idx.subs)
        if (~ is_valid_index(idx.subs{i}))
          error('OctSymPy:subsref:invalidIndices', ...
                'invalid indices: should be integers or boolean');
        end
      end
      out = mat_access(f, idx.subs);

    case '.'
      fld = idx.subs;
      if (strcmp (fld, 'pickle'))
        out = f.pickle;
      elseif (strcmp (fld, 'flat'))
        out = f.flat;
      elseif (strcmp (fld, 'ascii'))
        out = f.ascii;
      elseif (strcmp (fld, 'unicode'))
        out = f.unicode;
      %elseif (strcmp (fld, 'extra'))
      %  out = f.extra;
      % not part of the interface
      %elseif (strcmp (fld, 'size'))
      %  out = f.size;
      else
        error ('@sym/subsref: invalid or nonpublic property ''%s''', fld);
      end

    otherwise
      error ('@sym/subsref: invalid subscript type ''%s''', idx.type);

  end

  % Octave 7.1, Issue #1112 and https://savannah.gnu.org/bugs/?61898
  varargout = {out};

end

%!shared a,b
%! b = [1:4];
%! a = sym(b);
%!assert(isequal( a(1), b(1) ))
%!assert(isequal( a(2), b(2) ))
%!assert(isequal( a(4), b(4) ))
%!assert(isempty( a([]) ))

%!shared a,b
%! b = [1:4];  b = [b; 3*b; 5*b];
%! a = sym(b);
%!assert(isequal( a(1), b(1) ))
%!assert(isequal( a(2), b(2) ))
%!assert(isequal( a(4), b(4) ))
%!assert(isequal( a(:,:), a ))
%!assert(isequal( a(1:2,1:3), a(1:2,1:3) ))
%!assert(isequal( a(1:2:3,[1 2 4]), b(1:2:3,[1 2 4]) ))
%!assert(isequal( a(1:2:3,[4 2 3 1]), b(1:2:3,[4 2 3 1]) ))
% repeats
%!assert(isequal( a(1:2:3,[4 1 1 1]), b(1:2:3,[4 1 1 1]) ))

%!assert(isequal( a([],:), b([],:) ))
%!assert(isequal( size(a([],:)), [0 4] ))
%!assert(isequal( a(1:2,[]), b(1:2,[]) ))
%!assert(isequal( size(a(1:2,[])), [2 0] ))
%!assert(isempty( a(1:2,[]) ))
%!assert(isempty( a([],[]) ))
%!assert(isequal( a([],[]), sym([]) ))
%!assert(~isequal( a(1:2,[]), sym([]) ))

%!shared e
%! e = sym([1 3 5; 2 4 6]);
%!assert(isequal( e(:), sym((1:6)') ))
%!assert(isequal( e([1 2 3]), sym([1 2 3]) ))
%!assert(isequal( e([1; 3; 4]), sym([1; 3; 4]) ))
%!assert(isempty( e([]) ))
%!assert(isempty( e('') ))
%!assert(isequal( e([]), sym([]) ))

%!shared a,b
%! b = 1:5; a = sym(b);
%!assert(isequal(  a([1 2 5]),  b([1 2 5])  ))
%!assert(isequal(  a([1; 2; 5]),  b([1; 2; 5])  ))

%!shared x
%! syms x

%!test
%! % logical with empty result
%! assert(isempty( x(false) ))
%! a = [x x];
%! assert(isempty( a([false false]) ))

%!test
%! % issue 18, scalar access
%! assert(isequal( x(1), x ))
%! assert(isequal( x(true), x ))

%!shared

%!test
%! % older access tests
%! syms x
%! f = [x 2; 3 4*x];
%! % element access
%! assert (logical(  f(1,1) == x  ))
%! assert (logical(  f(1,2) == 2  ))
%! % linear access of 2d array
%! assert (logical(  f(1) == x  ))
%! assert (logical(  f(2) == 3  ))  % column based
%! assert (logical(  f(3) == 2  ))

%!shared a,b
%! % effectively a random matrix
%! a = reshape( round(50*(sin(1:20)+1)),  5,4);
%! b = sym(a);

%!test
%! % older array refs test
%! assert (logical(b(1,1) == a(1,1)))
%! assert (logical(b(3,1) == a(3,1)))
%! assert (logical(b(1,3) == a(1,3)))
%! assert (logical(b(4,4) == a(4,4)))

%!test
%! % older array refs test: linear indices
%! assert (logical(b(1) == a(1)))
%! assert (logical(b(3) == a(3)))
%! assert (logical(b(13) == a(13)))

%!test
%! % older array refs test: end
%! assert (all(all(logical(  b(end,1) == a(end,1)  ))))
%! assert (all(all(logical(  b(2,end) == a(2,end)  ))))
%! assert (all(all(logical(  b(end,end) == a(end,end)  ))))
%! assert (all(all(logical(  b(end-1,1) == a(end-1,1)  ))))
%! assert (all(all(logical(  b(2,end-1) == a(2,end-1)  ))))
%! assert (all(all(logical(  b(end-1,end-1) == a(end-1,end-1)  ))))

%!shared

%!test
%! % older slicing tests
%! syms x
%! a = [1 2 3 4 5 6]; a = [a; 3*a; 5*a; 2*a; 4*a];
%! b = sym(a);
%! assert (isequal(  b(:,1), a(:,1)  ))
%! assert (isequal(  b(:,2), a(:,2)  ))
%! assert (isequal(  b(1,:), a(1,:)  ))
%! assert (isequal(  b(2,:), a(2,:)  ))
%! assert (isequal(  b(:,:), a(:,:)  ))
%! assert (isequal(  b(1:3,2), a(1:3,2)  ))
%! assert (isequal(  b(1:4,:), a(1:4,:)  ))
%! assert (isequal(  b(1:2:5,:), a(1:2:5,:)  ))
%! assert (isequal(  b(1:2:4,:), a(1:2:4,:)  ))
%! assert (isequal(  b(2:2:4,3), a(2:2:4,3)  ))
%! assert (isequal(  b(2:2:4,3), a(2:2:4,3)  ))

%!test
%! % 2D arrays
%! b = [1:4]; b = [b; 3*b; 5*b];
%! a = sym(b);
%! I = rand(size(b)) > 0.5;
%! assert (isequal (a(I), b(I)))
%! I = I(:);
%! assert (isequal (a(I), b(I)))
%! I = I';
%! assert (isequal (a(I), b(I)))
%! I = logical(zeros(size(b)));
%! assert (isequal (a(I), b(I)))

%!test
%! % 1D arrays, does right with despite warning
%! r = [1:6];
%! ar = sym(r);
%! c = r';
%! ac = sym(c);
%! Ir = rand(size(r)) > 0.5;
%! Ic = rand(size(c)) > 0.5;
%! assert (isequal (ar(Ir), r(Ir)))
%! assert (isequal (ac(Ic), c(Ic)))
%! assert (isequal (ar(Ic), r(Ic)))
%! assert (isequal (ac(Ir), c(Ir)))

%!test
%! % rccross tests
%! B = [1 2 3 4; 5 6 7 9; 10 11 12 13];
%! A = sym(B);
%! assert (isequal (A([1 3],[2 3]), B([1 3], [2 3])  ))
%! assert (isequal (A(1,[2 3]), B(1,[2 3])  ))
%! assert (isequal (A([1 2],4), B([1 2],4)  ))
%! assert (isequal (A([2 1],[4 2]), B([2 1],[4 2])  ))
%! assert (isequal (A([],[]), B([],[])  ))

%!error <integers>
%! % issue #445
%! A = sym([10 11]);
%! A(1.1)

%!error <integers>
%! % issue #445
%! A = sym([10 11]);
%! A(sym(4)/3)

%!error <integers>
%! % issue #445
%! A = sym([1 2; 3 4]);
%! A(1.1, 1)

%!error <integers>
%! % issue #445
%! A = sym([1 2; 3 4]);
%! A(1, sym(4)/3)

%!error <out of bound>
%! A = sym([1 2; 3 4]);
%! A(5)

%!shared a, b
%! a = [1 2 3 5; 4 5 6 9; 7 5 3 2];
%! b = sym (a);

%!test
%! c = true;
%! assert (isequal (a(c), b(c)))
%! c = false;
%! assert (isequal (a(c), b(c)))

%!test
%! c = [false true];
%! assert (isequal (a(c), b(c)))
%! d = c | true;
%! assert (isequal (a(d), b(d)))
%! d = c & false;
%! assert (isequal (a(d), b(d)))

%!test
%! c = [false true false true; true false true false; false true false true];
%! assert (isequal (a(c), b(c)))
%! d = c | true;
%! assert (isequal (a(d), b(d)))
%! d = c & false;
%! assert (isequal (a(d), b(d)))

%!test
%! c = [false true false true false];
%! assert (isequal (a(c), b(c)))
%! d = c | true;
%! assert (isequal (a(d), b(d)))
%! d = c & false;
%! assert (isequal (a(d), b(d)))

%!test
%! c = [false; true; false; true; false];
%! assert (isequal (a(c), b(c)))
%! d = c | true;
%! assert (isequal (a(d), b(d)))
%! d = c & false;
%! assert (isequal (a(d), b(d)))

%!test
%! c = [false true; false true; true false];
%! assert (isequal (a(c), b(c)))
%! d = c | true;
%! assert (isequal (a(d), b(d)))
%! d = c & false;
%! assert (isequal (a(d), b(d)))

%!shared

%!test
%! % Orientation of empty results of logical indexing on row or column vectors
%! r = [1:6];
%! c = r';
%! ar = sym(r);
%! ac = sym(c);
%! assert (isequal (ar(false), r(false)))
%! assert (isequal (ac(false), c(false)))
%! assert (isequal (ar(false (1, 6)), r(false (1, 6))))
%! assert (isequal (ac(false (1, 6)), c(false (1, 6))))
%! assert (isequal (ar(false (6, 1)), r(false (6, 1))))
%! assert (isequal (ac(false (6, 1)), c(false (6, 1))))


function meow(n, paws)
%
% This Matlab function plays n successive cat meows, where each of the n
% meows is randomly chosen from one of two available sounds.  The function
% pauses for paws seconds after each meow.  The default values of n and
% paws are 5 and 3, respectively.
%
% Dr. Phillip M. Feldman   18 June, 2009

if nargin<1, n= 5; end
if nargin<2, paws= 3; end

for i= 1 : n
   if (rand(1) <= 0.5)
      infile= 'meow1.wav';
   else
      infile= 'meow2.wav';
   end

   [Y,Fs,Nbits]= wavread(infile);
   sound(Y, Fs);
   pause(paws);
end