function RF = rfGaussian2d(X,Y,sigmaMajor,sigmaMinor,theta, x0,y0)
% rfGaussian2d - Create a two dimensional Gaussian receptive field
%
%  RF = rfGaussian2d(X,Y,sigmaMajor,sigmaMinor,theta,x0,y0);
%
%    X,Y        : Sample positions in deg
%    sigmaMajor : standard deviation longest direction
%    sigmaMinor : standard deviation shortest direction
%                 [default: sigmaMinor = sigmaMajor]
%    theta      : angle of sigmaMajor (radians, 0=vertical)
%                 [default = 0];
%    x0         : x-coordinate of center of RF [default = 0];
%    y0         : y-coordinate of center of RF [default = 0];
%
%
% Example:
% To make one rf:
%    fieldRange = 20;  % Deg
%    sampleRate = 0.2; % Deg
%    x = [-fieldRange:sampleRate:fieldRange];
%    y = x;
%    [X,Y] = meshgrid(x,y);
%    sigma = 5;  % Deg
%    rf = rfGaussian2d(X,Y,sigma);
%

% Programming notes:
%  Maybe we should always make sure we use an odd number of samples and
%  have a sample at the origin

% According to profile half of the executing time for the function
% is spend at notDefined, and this functions is called lots (it
% is the slowest part in rmMain together with rfMakePrediction),   so
% if it seems that all arguments are given just skip it.
% ras 08/06: well, we can do what Bob does: not call it at all anyway.
if nargin ~= 7,
    if ~exist('X', 'var') || isempty(X),
        error('Must define X grid');
    end;

    if ~exist('Y', 'var') || isempty(Y),
        error('Must define Y grid');
    end;

    if ~exist ('sigmaMajor', 'var') || isempty(sigmaMajor),
        error('Must scale on major axis');
    end;

    if ~exist ('sigmaMinor', 'var') || isempty(sigmaMinor),
        sigmaMinor = sigmaMajor;
    end;

    if ~exist ('theta', 'var') || isempty(theta), theta = false; end;
    if ~exist ('x0', 'var') || isempty(x0),       x0 = 0;    end;
    if ~exist ('y0', 'var') || isempty(y0),       y0 = 0;    end;
end;

% Allow sigma, x,y to be a matrix so that the final output will be
% size(X,1) by size(x0,2). This way we can make many RFs at the same time.
% Here I assume that all parameters are given.
if numel(sigmaMajor)~=1,
    sz1 = numel(X);
    sz2 = numel(sigmaMajor);

    X   = repmat(X(:),1,sz2);
    Y   = repmat(Y(:),1,sz2);

    sigmaMajor = repmat(sigmaMajor(:)',sz1,1);
    sigmaMinor = repmat(sigmaMinor(:)',sz1,1);

    if any(theta(:)),
        theta = repmat(theta(:)',sz1,1);
    end;

    x0 = repmat(x0(:)',sz1,1);
    y0 = repmat(y0(:)',sz1,1);
end;

% Translate grid so that center is at RF center
X = X - x0;   % positive x0 moves center right
Y = Y - y0;   % positive y0 moves center up

% Rotate grid around the RF center, positive theta rotates the
% grid to the right. No need for this if theta is 0.
if any(theta(:)),
    Xold = X;
    Yold = Y;
    X = Xold .* cos(theta) - Yold .* sin(theta);
    Y = Xold .* sin(theta) + Yold .* cos(theta);
end;

% make gaussian on current grid
RF = exp( -.5 * ((Y ./ sigmaMajor).^2 + (X ./ sigmaMinor).^2));

% Normalize the Gaussian.
% The idea is that if you stimulate the entire RF you will
% always get the same activation, independent of the RF parameters.
% RF = RF ./ (sigmaMajor.*2.*pi.*sigmaMinor);
% Decided not to do this. The fitting will deal with this.
% Thus amplitude will always be the same.

return;


function score = nmi_onmf(true_labels, cluster_labels)
%NMI Compute normalized mutual information (NMI) using the true and cluster
%   labels and return the value in 'score'.
%
%   Input    : true_labels    : N-by-1 vector containing true labels
%              cluster_labels : N-by-1 vector containing cluster labels
%
%   Output   : score          : NMI value
%
%   Reference: Shi Zhong, 2003.
%              http://www.cse.fau.edu/~zhong/software/textclust.zip

% Compute the confusion matrix 'cmat', where
%   col index is for true label (CAT),
%   row index is for cluster label (CLS).
n = length(true_labels);
cat = spconvert([(1:n)' true_labels ones(n,1)]);
cls = spconvert([(1:n)' cluster_labels ones(n,1)]);
cls = cls';
cmat = full(cls * cat);

n_i = sum(cmat, 1); % Total number of data for each true label (CAT), n_i
n_j = sum(cmat, 2); % Total number of data for each cluster label (CLS), n_j

% Calculate n*n_ij / n_i*n_j
[row, col] = size(cmat);
product = repmat(n_i, [row, 1]) .* repmat(n_j, [1, col]);
index = find(product > 0);
n = sum(cmat(:));
product(index) = (n*cmat(index)) ./ product(index);
% Sum up n_ij*log()
index = find(product > 0);
product(index) = log(product(index));
product = cmat .* product;
score = sum(product(:));
% Divide by sqrt( sum(n_i*log(n_i/n)) * sum(n_j*log(n_j/n)) )
index = find(n_i > 0);
n_i(index) = n_i(index) .* log(n_i(index)/n);
index = find(n_j > 0);
n_j(index) = n_j(index) .* log(n_j(index)/n);
denominator = sqrt(sum(n_i) * sum(n_j));

% Check if the denominator is zero
if denominator == 0
  score = 0;
else
  score = score / denominator;
end


% Nonnegative matrix factorization
% Argyris Zymnis, Joelle Skaf, Stephen Boyd
%
% We are given a matrix A in R^{m*n}
% and are interested in solving the problem:
%
% minimize    ||A - Y*X||_F
% subject to  Y >= 0, X >= 0
%
% where Y in R{m*k} and X in R{k*n}.
% This script generates a random matrix A and obtains an
% *approximate* solution to the above problem by first generating
% a random initial guess for Y and the alternatively minimizing
% over X and Y for a fixed number of iterations.

% Generate data matrix A
rstate = rand('state');
m = 10; n = 10; k = 5;
A = rand(m,k)*rand(k,n);

% Initialize Y randomly
Y = rand(m,k);

% Perform alternating minimization
MAX_ITERS = 30;
residual = zeros(1,MAX_ITERS);
for iter = 1:MAX_ITERS
    cvx_begin quiet
        if mod(iter,2) == 1
            variable X(k,n)
            X >= 0;
        else
            variable Y(m,k)
            Y >= 0;
        end
        minimize(norm(A - Y*X,'fro'));
    cvx_end
    fprintf(1,'Iteration %d, residual norm %g\n',iter,cvx_optval);
    residual(iter) = cvx_optval;
end

% Plot residuals
plot(residual);
xlabel('Iteration Number');
ylabel('Residual Norm');

% Display results
disp( 'Original matrix:' );
disp( A );
disp( 'Left factor Y:' );
disp( Y );
disp( 'Right factor X:' );
disp( X );
disp( 'Residual A - Y * X:' );
disp( A - Y * X );
fprintf( 'Residual after %d iterations: %g\n', iter, cvx_optval );


function [mu, b, se, LR_chi2, convState] = drxlr_logistic_regression(x,y,iterlim,convcrit)
% regression by logistic model
% discrete reponse and different types of explanatory variables
% x: column vector of explanatory variables
% y: column vector of observations
% solved by maximum likelihood estimates using iterative  weighted
% least-squared.
% written by Issam El Naqa Spring 2003
% Extracted for generalized use 2005, AJH
% LM: APA 07/13/2006, added convState as output parameter to represent the
% state of convergence. convState is a 1x3 vector with 1st element being
% converged Yes or no, second element being number of iterations for
% convergence and third element being convergence criteria condition
%
% Copyright 2010, Joseph O. Deasy, on behalf of the DREES development team.
%
% This file is part of the Dose Response Explorer System (DREES).
%
% DREES development has been led by:  Issam El Naqa, Aditya Apte, Gita Suneja, and Joseph O. Deasy.
%
% DREES has been financially supported by the US National Institutes of Health under multiple grants.
%
% DREES is distributed under the terms of the Lesser GNU Public License.
%
%     This version of DREES 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.
%
% DREES 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 DREES.  If not, see <http://www.gnu.org/licenses/>.

% Initialize parameters
%warning('off');
x = [x ones(size(x,1),1)]; % constant factor
iter = 0;
[n p] = size(x);
seps = sqrt(eps);
eta = drxlr_rlogit((y + 0.5)/2); % initialize
b = zeros(p,1);
b0 = b+1;
% Start iterating
while(1)
    iter = iter+1;
    mu = drxlr_invlogit(eta);
    mu = max(0, min(1, mu));
    % Check stopping conditions
    if (~any(abs(b-b0) > convcrit * max(seps, abs(b0))))
        convState = [1 iter-1 max(abs(b-b0))];
        break;
    end
    if (iter>iterlim)
        warning('drxlr_logistic_regression: Number of iterations exceeded without convergence (convergence tolerance = %e', convcrit)
        convState = [2 iter-1 max(abs(b-b0))];
        break;  % iteration limit reached, exit!
    end
    deta = drxlr_d_logit(mu);
    z = eta + (y - mu) .* deta;
    vy=drxlr_binomial_variance(mu);
    w = 1 ./ max(eps, (deta .^ 2) .* vy);
    b0 = b;
    [b,R,se] = drxlr_wfit(z, x, w, p);
    eta = x * b;
end

%%% calculate likelihood ratio test
LR_chi2=drxlr_get_lrt(y,mu);
return


function d = distanz(x,y,algtype)
% DISTANZ : calculates the distances between all vectors in x and y.
%
% usage:
%    d = distanz(x,y);
%
% inputs:
%    x      matrix with col vectors
%    y      matrix with col vectors (default == x)
%    algtype   the type of algorithm that is used (default==3)
%
% outputs:
%    d      distance matrix, not squared
%
% note:
%    part of the code is inspired by dist.m of the nntoolbox, other
%    part adapted from Francis Bach who took it from Roland
%    Bunschoten.
%
% sth * 19apr2002
% Adapted from create.m, originally written by
% (c) Stefan Harmeling, 2006

if exist('algtype')~=1 || isempty(algtype), algtype = 3; end
switch algtype
 case 1  % inspired by dist.m
  if exist('y')~=1 || isempty(y)
    % here comes code just for x
    [rx,cx] = size(x);
    d = zeros(cx,cx);
    nuller = zeros(cx,1);
    for c = 1:cx
      d(c,:) = sum((x-x(:,c+nuller)).^2,1);
    end
  else
    % here comes code for x and y
    [rx,cx] = size(x);
    [ry,cy] = size(y);
    if rx~=ry, error('x and y do not fit'), end
    d = zeros(cx,cy);
    if cx>cy
      nuller = zeros(cx,1);
      for c = 1:cy
	d(:,c) = sum((x-y(:,c+nuller)).^2,1)';
      end
    else
      nuller = zeros(cy,1);
      for c = 1:cx
	d(c,:) = sum((x(:,c+nuller)-y).^2,1);
      end
    end
  end

 case 2  % same as case 1, but with repmat instead of nuller
  if exist('y')~=1 || isempty(y)
    % here comes code just for x
    [rx,cx] = size(x);
    d = zeros(cx,cx);
    nuller = zeros(cx,1);
    for c = 1:cx
      d(c,:) = sum((x-repmat(x(:,c),[1 cx])).^2,1);
    end
  else
    % here comes code for x and y
    [rx,cx] = size(x);
    [ry,cy] = size(y);
    if rx~=ry, error('x and y do not fit'), end
    d = zeros(cx,cy);
    if cx>cy
      nuller = zeros(cx,1);
      for c = 1:cy
	d(:,c) = sum((x-repmat(y(:,c),[1 cx])).^2,1)';
      end
    else
      nuller = zeros(cy,1);
      for c = 1:cx
	d(c,:) = sum((repmat(x(:,c),[1 cy])-y).^2,1);
      end
    end
  end

 case 3  % inspired by Roland Bunschoten
  if exist('y')~=1 || isempty(y)
    % here comes code just for x
    cx = size(x,2);
    xx = sum(x.*x,1); xz = x'*x;
    d = abs(repmat(xx',[1 cx]) - 2*xz + repmat(xx,[cx 1]));
  else
    % here comes code for x and y
    [rx,cx] = size(x);
    [ry,cy] = size(y);
    if rx~=ry, error('x and y do not fit'), end
    xx = sum(x.*x,1); yy = sum(y.*y,1);  xy = x'*y;
    d = abs(repmat(xx',[1 cy]) + repmat(yy,[cx 1]) - 2*xy);
  end
end

d = sqrt(d);


function y = barycentricInterpolate(Y,Idx,W)
% y = barycentricInterpolate(Y,Idx,W)
%
% This function interpolates a point y, based on the data in Y and the
% weights (W) on the verticies Y(Idx)
%
% INPUTS:
%   Y = [N, 1] data set.
%   W = [d+1, n] weight to apply to each index
%   Idx = [d+1, n] linear index corresponding to each weight
%
% OUTPUTS:
%   y = [n,d] = function value at query points
%
% NOTES:
%   --> y = f(x), where x is d-dimensional, and y is scalar
%   --> Y = Y(x1,x2,...,xd)
%   --> n = size(Y);
%   --> y(X(:,i)) = W(i,:)*Y(Idx(:,i));
%
% See Also: barycentricWeights

n = size(Idx,2);
y = zeros(n,1);

for query=1:n
    y(query) = dot(W(:,query),Y(Idx(:,query)));
end

end


function unique_num = r8col_tol_unique_count ( m, n, a, tol )

%*****************************************************************************80
%
%% R8COL_TOL_UNIQUE_COUNT counts tolerably unique entries in an R8COL.
%
%  Discussion:
%
%    Because the array is unsorted, this algorithm is O(N^2).
%
%    If the tolerance is large enough, then the concept of uniqueness
%    can become ambiguous.  If we have a tolerance of 1.5, then in the
%    list ( 1, 2, 3, 4, 5, 6, 7, 8, 9 ) is it fair to say we have only
%    one unique entry?  That would be because 1 may be regarded as unique,
%    and then 2 is too close to 1 to be unique, and 3 is too close to 2 to
%    be unique and so on.
%
%    This seems wrongheaded.  So I prefer the idea that an item is not
%    unique under a tolerance only if it is close to something that IS unique.
%    Thus, the unique items are guaranteed to cover the space if we include
%    a disk of radius TOL around each one.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 July 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows.
%
%    Input, integer N, the number of columns.
%
%    Input, real A(M,N), the unsorted array.
%
%    Input, real TOL, a tolerance for equality.
%
%    Output, integer UNIQUE_NUM, the number of unique columns of A.
%
  undx = zeros ( n, 1 );
%
%  Implicitly sort the array.
%
  indx = r8col_sort_heap_index_a ( m, n, a );
%
%  Consider entry I = 1.
%  It is unique, so set the number of unique items to K.
%  Set the K-th unique item to I.
%  Set the representative of item I to the K-th unique item.
%
  i = 1;
  k = 1;
  undx(k) = indx(i);
%
%  Consider entry I.
%
%  If it is unique, increase the unique count K, set the
%  K-th unique item to I, and set the representative of I to K.
%
%  If it is not unique, set the representative of item I to a
%  previously determined unique item that is close to it.
%
  for i = 2 : n

    unique = 1;

    for j = 1 : k
      diff = max ( abs ( a(1:m,indx(i)) - a(1:m,undx(j)) ) );
      if ( diff <= tol )
        unique = 0;
        break
      end
    end

    if ( unique )
      k = k + 1;
      undx(k) = indx(i);
    end

  end

  unique_num = k;

  return
end


function length = circle01_length ( )

%*****************************************************************************80
%
%% CIRCLE01_LENGTH: length of the circumference of the unit circle in 2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real LENGTH, the length.
%
  r = 1.0;
  length = 2.0 * pi * r;

  return
end


function [ss, dist_map] = makeSphericalSection(radius, height, width, plot_section, binary)
%MAKESPHERICALSECTION     Create a binary map of a sphere segment within a 3D grid.
%
% DESCRIPTION:
%       makeSphericalSection creates a binary map of a section of a
%       spherical surface within a three-dimensional matrix. The sphere is
%       created using an extension of the midpoint circle algorithm. A
%       single grid point is taken as the sphere center so the total
%       diameter will always be an odd number of grid points. The sphere is
%       then truncated based on the values for height and width (a diagram
%       of the input sizes is given below). The face of the spherical
%       section faces in the positive x-direction and the optional width
%       parameter truncates the size in the y-direction.
%
%       If the optional input parameter "binary" is set to false (the
%       default), the section map is returned as a double precision matrix.
%       If it is set to true, the map is returned as a logical matrix. The
%       average distance between each grid point in the spherical section
%       and its contiguous neighbours can also be returned. This is given
%       as a ratio compared to the average neighbour distance for a flat
%       surface.
%
% SYNTAX:
%       ss = makeSphericalSection(radius, height)
%       ss = makeSphericalSection(radius, height, width)
%       ss = makeSphericalSection(radius, height, width, plot_section)
%       ss = makeSphericalSection(radius, height, [], plot_section)
%       ss = makeSphericalSection(radius, height, width, plot_section, binary)
%       ss = makeSphericalSection(radius, height, [], [] binary)
%
%       [ss, dist_map] = makeSphericalSection(radius, height)
%       [ss, dist_map] = makeSphericalSection(radius, height, width)
%       [ss, dist_map] = makeSphericalSection(radius, height, [], plot_section)
%       [ss, dist_map] = makeSphericalSection(radius, height, width, plot_section)
%       [ss, dist_map] = makeSphericalSection(radius, height, width, plot_section, binary)
%       [ss, dist_map] = makeSphericalSection(radius, height, [], [] binary)
%
% INPUTS:
%       radius          - radius of curvature [grid points]
%       height          - transducer height [grid points]
%
% OPTIONAL INPUTS:
%       width           - section width (must be specified as an odd
%                         number) [grid points]
%       plot_section    - Boolean controlling whether the spherical section
%                         is plotted using voxelPlot (default = false)
%       binary          - Boolean controlling whether the spherical section
%                         is returned as a double precision matrix (false)
%                         or a logical matrix (true) (default = false)
%
% OUTPUTS:
%       ss              - binary matrix containing spherical section
%       dist_map        - ratio of average neighbour distance for each grid
%                         point within the spherical section compared to a
%                         flat surface
%
% ABOUT:
%       author          - Bradley Treeby
%       date            - 3rd February 2012
%       last update     - 20th August 2014
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2014 Bradley Treeby and Ben Cox
%
% See also makeBall, makeSphere

% This file is part of k-Wave. k-Wave 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.
%
% k-Wave 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 Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.

%#ok<*UNRCH>

% option to use the spherical sections or square sections of the sphere
% returned by makeSphere (true by default)
use_spherical_sections = true;

% force inputs to be integers
radius = round(radius);
height = round(height);

% check for width input
if nargin < 3 || (nargin == 4 && isempty(width))

    % set width truncation flag to false
    use_width = false;

else

    % set width truncation flag to true
    use_width = true;

    % force input to an integer
    width = round(width);

    % check that it's an odd number
    if ~rem(width, 2)
        error('width must be an odd number');
    end

end

% check for plot input
if nargin < 4 || isempty(plot_section)
    plot_section = false;
end

% check for data type input
if nargin < 5 || isempty(binary)
    binary = false;
end

% calculate minimum grid dimensions to fit entire sphere
Nx = 2*radius + 1;

% create sphere
ss = makeSphere(Nx, Nx, Nx, radius, [], binary);

% truncate to given height
if use_spherical_sections
    ss = ss(1:height, :, :);
else
    ss = permute(ss(:, 1:height, :), [2, 3, 1]);
end

% flatten transducer and store the maximum and indices
mx = squeeze(max(ss, [], 1));

% calculate the total length/width of the transducer
length = sum(mx(ceil(end/2), :), 2);

% truncate transducer grid based on length (removes empty rows and columns)
offset = (Nx - length)/2;
ss = ss(:, 1 + offset:end - offset, 1 + offset:end - offset);

% also truncate to given width if defined by user
if use_width

    % check the value is appropriate
    if width > length
        error('input for width must be less than or equal to transducer length');
    end

    % calculate offset
    offset = (length - width)/2;

    % truncate transducer grid
    ss = ss(:, 1 + offset:end - offset, :);

end

% compute average distance between each grid point and it's contiguous
% neighbours if dist_map output is defined
if nargout == 2

    % calculate x-index of each grid point in the spherical section, create
    % mask and remove singleton dimensions
    [mx, mx_ind] = max(ss, [], 1);
    mask = squeeze(mx ~= 0);
    mx_ind = squeeze(mx_ind).*mask;

    % double check there there is only one value of spherical section in
    % each matrix column
    if sum(mx(:)) ~= sum(ss(:))
        error('mean neighbour distance cannot be calculated uniquely due to overlapping points in the x-direction');
    end

    % calculate average distance to grid point neighbours in the flat case
    x_dist = repmat([1 0 1], 3, 1);
    y_dist = x_dist.';
    flat_dist = sqrt(x_dist.^2 + y_dist.^2);
    flat_dist = mean(flat_dist(:));

    % compute distance map
    dist_map = zeros(size(mx_ind));
    sz = size(mx_ind);
    for m = 1:sz(1)
        for n = 1:sz(2)

            % clear map
            local_heights = zeros(3, 3);

            % extract the height (x-distance) of the 8 neighbouring grid
            % points
            if m == 1 && n == 1
                local_heights(2:3, 2:3) = mx_ind(m:m + 1, n:n + 1);
            elseif m == sz(1) && n == sz(2)
                local_heights(1:2, 1:2) = mx_ind(m - 1:m, n - 1:n);
            elseif m == 1 && n == sz(2)
                local_heights(2:3, 1:2) = mx_ind(m:m + 1, n - 1:n);
            elseif m == sz(1) && n == 1
                local_heights(1:2, 2:3) = mx_ind(m - 1:m, n:n + 1);
            elseif m == 1
                local_heights(2:3, :) = mx_ind(m:m + 1, n - 1:n + 1);
            elseif m == sz(1)
                local_heights(1:2, :) = mx_ind(m - 1:m, n - 1:n + 1);
            elseif n == 1
                local_heights(:, 2:3) = mx_ind(m - 1:m + 1, n:n + 1);
            elseif n == sz(2)
                local_heights(:, 1:2) = mx_ind(m - 1:m + 1, n - 1:n);
            else
                local_heights = mx_ind(m - 1:m + 1, n - 1:n + 1);
            end

            % compute average variation from center
            local_heights_var = abs(local_heights - local_heights(2, 2));

            % threshold no neighbours
            local_heights_var(local_heights == 0) = 0;

            % calculate total distance from centre
            dist = sqrt(x_dist.^2 + y_dist.^2 + local_heights_var.^2);

            % average and store as a ratio
            dist_map(m, n) = 1 + (mean(dist(:)) - flat_dist)./flat_dist;

        end
    end

    % threshold out the non-transducer grid points
    dist_map(mask ~= 1) = 0;

    % flattened plot and distance values
    if plot_section
        figure;
        subplot(2, 1, 1);
        imagesc(mx_ind);
        axis image;
        colorbar;
        title('Height of Transducer Face');
        subplot(2, 1, 2);
        dist_map_plot = dist_map;
        dist_map_plot(dist_map_plot ~= 0) = dist_map_plot(dist_map_plot ~= 0) -1;
        imagesc(100*dist_map_plot);
        axis image;
        colorbar;
        title('Percentage Increase in Average Neighbour Distance Compared to a Flat Surface');
    end

end

% plot if required
if plot_section

    voxelPlot(double(ss));
    view(150, 20);

%     % create surface plot
%     figure;
%     sz = size(ss);
%     [x, y] = meshgrid(1:sz(3),1:sz(2));
%     surface_ind = find(mx ~= 0);
%     plot3(x(surface_ind), y(surface_ind), mx_ind(mx ~= 0), 'k.');
%     axis image;

end


function nearest = find_closest3 ( m, nr, r, ns, s )

%*****************************************************************************80
%
%% FIND_CLOSEST3 finds the nearest R point to each S point.
%
%  Discussion:
%
%    We are given R, a set of NR points in M dimensions.
%
%    We are given S, a set of NS points in M dimensions.
%
%    For each S(I) in S, we seek the index J of the point R(J)
%    which is nearest to S(I) over all points in R.
%
%    Modified in accordance with suggestions by Gene Cliff, 08 July 2010.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 July 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer NR, the number of cell generators.
%
%    Input, real R(M,NR), the cell generators.
%
%    Input, integer NS, the number of sample points.
%
%    Input, real S(M,NS), the points to be checked.
%
%    Output, integer NEAREST(NS), the index of the cell generator nearest
%    to the sample point.
%
  ones_k = ones ( 1, nr );
  nearest = NaN ( 1, ns );

  for i = 1 : ns
    d1 = r - s(:,i) * ones_k;
    d2 = sum ( d1 .* d1 );
    [ min_val, min_loc ] = min ( d2 );
    nearest(i) = min_loc;
  end

  return
end


function [ x, seed ] = sphere01_sample ( n, seed )

%*****************************************************************************80
%
%% SPHERE01_SAMPLE picks random points on the unit sphere.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 April 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of samples.
%
%    Input/output, integer SEED, a seed for the random
%    number generator.
%
%    Output, real X(3,N), the sample points.
%
  x = zeros ( 3, n );

  for j = 1 : n
%
%  Pick a uniformly random VDOT, which must be between -1 and 1.
%  This represents the dot product of the random vector with the Z unit vector.
%
%  Note: this works because the surface area of the sphere between
%  Z and Z + dZ is independent of Z.  So choosing Z uniformly chooses
%  a patch of area uniformly.
%
    [ vdot, seed ] = r8_uniform_01 ( seed );
    vdot = 2.0 * vdot - 1.0;

    phi = r8_acos ( vdot );
%
%  Pick a uniformly random rotation between 0 and 2 Pi around the
%  axis of the Z vector.
%
    [ theta, seed ] = r8_uniform_01 ( seed );
    theta = 2.0 * pi * theta;

    x(1,j) = cos ( theta ) * sin ( phi );
    x(2,j) = sin ( theta ) * sin ( phi );
    x(3,j) = cos ( phi );

  end

  return
end


function [R] = ipsrf(varargin)
%IPSRF Interval Potential Scale Reduction Factor
%
%   [R] = IPSRF(X) or
%   [R] = IPSRF(x1,x2,...,xs)
%   returns "Potential Scale Reduction Factor" (PSRF) for
%   collection of MCMC-simulations. X is a NxDxM matrix
%   which contains M MCMC simulations of length N, each with
%   dimension D. MCMC-simulations can be given as separate
%   arguments x1,x2,... which should have the same length.
%
%   Returns
%     R     PSRF in a row vector of length D
%
%   The idea of the PSRF is that if R is not near 1 (below 1.1 for
%   example) one may conclude that the tested samples were not from
%   the same distribution (chain might not have been converged
%   yet). Instead of normality assumption, 80% empirical intervals
%   are used to compute R.
%
%   If only one simulation is given, the factor is calculated
%   between first and last third of the chain. Note that use of
%   only one chain will produce over-optimistic result.
%
%   Method is from:
%      Brooks, S.P. and Gelman, A. (1998) General methods for
%      monitoring convergence of iterative simulations. Journal of
%      Computational and Graphical Statistics. 7, 434-455.
%
%   See also
%     CIPSRF, PSRF

% Copyright (C) 1999 Simo S�rkk�
% Copyright (C) 2004 Aki Vehtari
%
% This software is distributed under the GNU General Public
% Licence (version 3 or later); please refer to the file
% Licence.txt, included with the software, for details.

% In case of one argument split to two halves (first and last thirds)
onechain=0;
if nargin==1
  X = varargin{1};
  if size(X,3)==1
    n = floor(size(X,1)/3);
    x = zeros([n size(X,2) 2]);
    x(:,:,1) = X(1:n,:);
    x(:,:,2) = X((end-n+1):end,:);
    X = x;
    onechain=1;
  end
elseif nargin==0
  error('Cannot calculate PSRF of scalar');
else
  X = zeros([size(varargin{1}) nargin]);
  for i=1:nargin
    X(:,:,i) = varargin{i};
  end
end

[N,D,M]=size(X);

if N<1
  error('Too few samples');
end

W = zeros(1,D);
V = zeros(1,D);
for d=1:D
  x=X(:,d,:);
  W(1,d)=mean(diff(prctile(x,[10 90])));
  V(1,d)=diff(prctile(x(:),[10 90]));
end
R = V./W;


function M=minMatOverDim(C,minIdx)
%%MINMATOVERDIM Given a multidimensional matrix C, this function returns
%           matrix M that is obtained by minimizing C over the given
%           dimension and removing the given dimension. This is equivalent
%           to using a call to min(C,[],minIdx) in Matlab. However, here,
%           we do it without using any matrix/ vector commands so that it
%           can mirror how one might implement such a function in C.
%
%INPUTS: C A real n1Xn2Xn3..XnS S-dimensional hypermatrix.
%   minIdx The real index from 1 to S over which the minimization should be
%          performed.
%
%OUTPUTS: M An n1X...n(minIdx-1)X1Xn(minIdx+1)X...nS matrix holding the
%           minimum values over the specified dimension.
%
%The algorithm consists of two types of steps. First, a step in the linear
%indexation of C to go from one value of an index in spot minIdx is
%prod(nVals(1:(minIdx-1))), where nVals=size(C). Thus, we can go from one
%element to the next for the minimization. For a 3D matrix, the step to go
%from C(i1,1,i2) to C(i1+1,1,i2) increments by 1. However, to go from
%C(n1,1,i2) to C(1,1,i2+1) is a step of prod(nVals(1:minIdx)). The same
%type of thing applies to a matrix with more dimensions, since all
%dimensions before the one in question and after can be collapsed into 1
%dimension. Thus, this function puts the above rules together to go
%minimize the matrix.
%
%EXAMPLE:
%Here, we just show that the results are equivalent to using the min
%command with a resize.
% C=randn(13,18,11,6,9);
% minIdx=3;
% M=minMatOverDim(C,minIdx);
% MAlt=min(C,[],minIdx);
% all(M(:)==MAlt(:))
%The result is 1, indicating that the two values are equal.
%
%March 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

nVals=size(C);
S=numel(nVals);

if(minIdx<1)
    error('Invalid value of minIdx given.')
end

if(minIdx>S)
    M=C;
    return;
end

MDims=nVals;
MDims(minIdx)=1;
M=zeros(MDims);

totalNumElsM=prod(MDims);

%Note that prod([])=1
incrMinIdx=prod(nVals(1:(minIdx-1)));

incrBigStep=incrMinIdx*nVals(minIdx);

CStartIdx=0;
curMCol=0;
for curEl=0:(totalNumElsM-1)
    curIdx=CStartIdx;
    minVal=C(curIdx+1);

    curIdx=curIdx+incrMinIdx;
    for i=2:nVals(minIdx)
        curVal=C(curIdx+1);

        if(curVal<minVal)
            minVal=curVal;
        end

        curIdx=curIdx+incrMinIdx;
    end
    M(curEl+1)=minVal;

    %If a big step has to be taken.
    if(mod(curEl+1,incrMinIdx)==0)
        curMCol=curMCol+1;

        CStartIdx=incrBigStep*curMCol;
    else
        CStartIdx=CStartIdx+1;
    end
end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function moc_display ( a, b, n, f )

%*****************************************************************************80
%
%% MOC_DISPLAY plots data related to the modulus of continuity of a function.
%
%  Discussion:
%
%    Three graphs will be shown:
%    1) A plot of F(X) from A to B.
%    2) A plot of the function MC1(X) for 0 <= T <= B-A, where
%       MC1(T) = max | F(X+DX) - F(X) |, for DX = T, X and X+DX in [A,B].
%    3) A plot of the function MC(X) for 0 <= T <= B-A, where
%       MC(T) = max | F(X+DX) - F(X) |, for DX <= T, X and X+DX in [A,B].
%
%    The functions MC1 and MC are estimated by evaluating F(X) at N
%    equally spaced points in [A,B].
%
%    MC(T) is known as the "modulus of continuity" for F(X);
%    MC1(T) has no special name.
%
%    The exact function MC(T) should be a monotone increasing function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 October 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the left and right endpoints of the interval.
%
%    Input, integer N, the number of equally spaced sample points used to
%    estimate MC1(T) and MC(T).
%
%    Input, function F(x), a handle to the function whose modulus of
%    continuity function is to be estimated and plotted.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'MOC_DISPLAY:\n' );
  fprintf ( 1, '  Estimate and plot the Modulus of Continuity function\n' );
  fprintf ( 1, '  over an interval [A,B], using N sample points, and a\n' );
  fprintf ( 1, '  user-specified function F(X).\n' );

  if ( nargin < 1 )
    a = 0.0;
  end

  if ( nargin < 2 )
    b = a + 1.0;
  end

  if ( nargin < 3 )
    n = 501;
  end
%
%  Compute discrete data for given N.
%
  x = linspace ( a, b, n );
  dx = linspace ( 0, b - a, n );
  fx = f ( x );

  mc1 = zeros ( n, 1 );
  for i = 0 : n - 1
    mc1(i+1) = max ( abs ( fx(1+i:n) - fx(1:n-i) ) );
  end

  mc = zeros ( n, 1 );
  for i = 1 : n - 1
    mc(i+1) = max ( mc(i), mc1(i+1) );
  end
%
%  Display the plots.
%
  subplot ( 3, 1, 1 )
  n_fine = 1000;
  x_fine = linspace ( a, b, n_fine );
  fx_fine = f ( x_fine );
  plot ( x_fine, fx_fine, 'LineWidth', 2 )
  grid on
  title ( 'F(X)' );

  subplot ( 3, 1, 2 )
  plot ( dx, mc1, 'LineWidth', 2 );
  grid on
  title ( sprintf ( 'MC1(DX): max |F(X+DX)-F(X)|, N = %d', n ) )

  subplot ( 3, 1, 3 )
  plot ( dx, mc, 'LineWidth', 2 );
  grid on
  title ( sprintf ( 'MC(T): max |F(X+DX)-F(X)| for DX <= T, N = %d', n ) )

  return
end


function c_nm = sphMultiplication(a_nm, b_nm, G)
%SPHMULTIPLICATION Computes coefficients of a product spherical function
%
%   The coefficients of a product function of two spherical functions can
%   be given directly as a linear combination of the coefficients of the
%   original functions, by employing Gaunt coefficients
%
%   a_nm: (N+1)^2 coefficients of spherical function a(\theta,\phi)
%   b_nm: (N+1)^2 coefficients of spherical function b(\theta,\phi)
%
%   c_nm:  (N+1)^2 coefficients of the product function
%           c(\theta,\phi) = a(\theta,\phi)*b(\theta,\phi)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   Archontis Politis, 10/10/2013
%   archontis.politis@aalto.fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% order
Na = sqrt(length(a_nm)) - 1;
Nb = sqrt(length(b_nm)) - 1;
Nc = Na+Nb;

c_nm = zeros((Nc+1)^2, 1);
% evaluate the coefficients of the product through the gaunt coefficients
if nargin<3
    G = gaunt_mtx(Na, Nb, Nc);
end
for n=0:Nc
    for m=-n:n
        q = n*(n+1)+m;
        c_nm(q+1) = a_nm.' * G(:,:,q+1) * b_nm;

    end
end

end


function m = imMoment(img, p, q)
%IMMOMENT  Compute simple moment(s) of an image
%
%   M_PQ = imMoment(IMG, P, Q)
%   P is order for x coord, Q is order for y coord.
%
%   Example
%   % generate image
%   img = zeros([5 6]);
%   img(2:3, 2:5) = 1;
%   % compute total mass of image
%   m00  = imMoment(img, 0, 0);
%   % compute centroid
%   cx  = imMoment(img, 1, 0)/m00;
%   cy  = imMoment(img, 0, 1)/m00;
%
%
%   See also
%     imEquivalentEllipse, imPrincipalAxes
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2008-10-08,    using Matlab 7.4.0.287 (R2007a)
% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas.

% image dimension
dim = size(img);
Dx = dim(2);
Dy = dim(1);

% compute x and y for each pixel
Ix = repmat((1:Dx), [Dy 1]);
Iy = repmat((1:Dy)', [1 Dx]);

% compute moment
m = zeros(size(p));
for i=1:length(p(:))
    m(i) = sum(Ix(:).^p(i) .* Iy(:).^q(i) .* img(:));
end


function [W, R, P] = miso_firwiener(N, X, y)
%MISO_FIRWIENER Optimal FIR Wiener filter for multiple inputs.
%   MISO_FIRWIENER(N, X, Y) computes the optimal FIR Wiener filter of
%   order N, given any number of (stationary) random input signals as
%   the columns of matrix X, and one output signal in column vector Y.

%   Author: Keenan Pepper
%   Last modified: 2007-12-21

%   References:
%     [1] Y. Huang, J. Benesty, and J. Chen, Acoustic MIMO Signal
%     Processing, Springer−Verlag, 2006, page 48

% Number of input channels.
M = size(X, 2);

% Input covariance matrix, in abbreviated block Toeplitz form.
R = zeros(M*(N+1), M);
for m = 1:M
    for i = 1:M
         rmi = xcorr(X(:,m), X(:,i), N);
         Rmi = flipud(rmi(1:N+1));
         top = (m-1) * (N+1) + 1;
         bottom = m * (N+1);
         R(top:bottom,i) = Rmi;
    end
end

R = reshape(R, [N+1,M,M]);      % This just permutes the indices to
R = permute(R, [2,1,3]);        % change R from Toeplitz-block to
R = reshape(R, [M*(N+1),M]);    % block-Toeplitz.

% Cross−correlation vector.
P = zeros(1, M*(N+1));
for i = 1:M
    top = (i-1)*(N+1)+1;
    bottom = i * (N+1);
    p = xcorr(y, X(:,i), N);
    P(top:bottom) = p(N+1:2*N+1)';
end

P = reshape(P, [N+1,M]);        % More index rearrangement.
P = reshape(P', [M*(N+1),1]);

W = block_levinson(P, R);

W = reshape(W, [M,N+1]);        % Make output compatible with earlier
W = reshape(W', [1, M*(N+1)]);  % version.


%  追赶法 分解的紧凑方式
function [x] = my_forward_backward(A,f)

[m,n]=size(A);
if (m~=n)
    fprintf('\n Error: A 不是方阵!\n'); return;
end

a = diag(A, -1);
a(2:n) = a;
a(1) = 0;
b = diag(A);
c = diag(A, 1);

% 判断是否三对角矩阵
if sum(any(tril(A, -2))) > 0 | sum(any(triu(A, 2))) > 0
    fprintf('\n Error: A 不是三对角矩阵!\n'); x = [];  return;
end

% 判断是否对角占优
if (abs(b(1)) <= abs(c(1)) | abs(c(1)) == 0 | find(abs(b(2:n-1)) < abs(a(2:n-1)) + abs(c(2:n-1))) > 0 | abs(b(n)) <= abs(a(n))) | abs(a(n)) == 0
  fprintf('\n Error: A 不是对角占优矩阵!\n'); x = [];  return;
end

alpha = zeros(n, 1);
beda = zeros(n-1, 1);
gamma = a;   % gamma直接等于a，无需计算

alpha(1) = b(1);
for i = 1 : n - 1
    beda(i) = c(i) / alpha(i);
    alpha(i + 1) = b(i + 1) - a(i + 1) * beda(i);
end

% 求解Ly=b 和 Ux=y
y(1) = f(1) / b(1);
for i=2:n
    y(i)=(f(i) - a(i)*y(i-1)) / alpha(i);
end
x(n) = y(n);
for i = n-1 : -1 : 1
    x(i)=y(i) - beda(i) * x(i+1);
end

% END


 function X = dtft1(x, omega, n_shift)
%function X = dtft1(x, omega, n_shift)
%| Compute DTFT of 1D signal x at frequency locations wx
%| In
%|	x	[N,ncol]	signal values
%|	omega	[M,1]		frequency locations
%|	n_shift	[1,1]		use [0:(N-1)]-n_shift indices
%| Out
%|	X	[M,ncol]	DTFT values
%|
%| This needs enough memory to store M * N size matrices
%| Copyright 2000-1-9, Jeff Fessler, University of Michigan

if nargin == 1 && streq(x, 'test'), dtft1_test, return, end
if nargin < 2, ir_usage(), end

N = size(x,1);
if ~isvar('n_shift') || isempty(n_shift), n_shift = 0; end
nn = [0:(N-1)] - n_shift;

X = exp(-1i*omega*nn) * x; % compute 1D DTFT

function dtft1_test()
N = 4;
x = [[1:N]', [1 1 2 2]'];	% two test signal
omega = 2*pi*[0:(N-1)]'/N;	% test with uniform frequency locations
Xd = dtft1(x, omega);
Xf = fft(x);
%disp([Xd Xf])
printm('max %% difference = %g', max_percent_diff(Xf,Xd))


function p = MS_fnn(y,de,tau,th,kth);
% function nfnn = MS_fnn(y,de,tau,th,kth)
%
% determine the number of false nearest neighbours for the time
% series y embedded in dimension de with lag tau.
%
% for each pair of values (de,tau) the data y is embeded and the
% nearest neighbour to each point (excluding the immediate
% neighbourhood of n points) is determined. If the ratio of the
% distance of the next (kth) points and these points is greater than
% th then they are counted as false nearest neighbours.
%
% default:
% th=5
% kth=1
%
% p(i,j) is the proportion of false nearest neighbours for de(i)
% and tau(j).
%
% Michael Small
% michael.small@uwa.edu.au, http://school.maths.uwa.edu.au/~small/
% 3/3/2005
% For further details, please see M. Small. Applied Nonlinear Time Series
% Analysis: Applications in Physics, Physiology and Finance. Nonlinear Science
% Series A, vol. 52. World Scientific, 2005. (ISBN 981-256-117-X) and the
% references therein.
% (minor cosmetic changes made by Ben Fulcher, 2010)

if nargin < 5
  kth = 1;
  disp(['th = ',int2str(kth)]);
end
if nargin < 4
  th = 5;
  disp(['th = ',int2str(th)]);
end
if nargin < 3
  tau = MS_firstzero(y);
  disp(['tau = ',int2str(tau)]);
end
if nargin < 2
  de = [1:10];
  disp(['de = ',int2str(de(1)),':',int2str(de(end))]);
end

p=[];
for t=tau,
  px=[];
  for d=de
    %embed the data
    X=MS_embed(y,d,t);
    [dx,nx]=size(X);

    %find the nearest neighbours of each point
    ind=MS_nearest(X(:,1:(nx-kth)),tau); %whooh hooo!

    %distance between each point and its nearest neighbour
    d0=MS_rms(X(:,(1:(nx-kth)))'-X(:,ind)');
    %... and after one time step
    d1=MS_rms(X(:,(kth+1):nx)'-X(:,ind+1)');

    %exclude any coincident points
    d1(d0==0)=[];
    d0(d0==0)=[];

    %calculate the proportion fnn
    ifnn=sum((d1./d0)>th)/length(d0);

    %disp
    % disp(['tau = ', int2str(t),', de = ',int2str(d),', nfnn = ',num2str(ifnn*100),'%']);

    px=[px ifnn];
  end;

  p=[p;px];

end;

p=p';


function geometry_test0183 ( )

%*****************************************************************************80
%
%% TEST0183 tests CIRCLE_LLR2IMP_2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 December 2010
%
%  Author:
%
%    John Burkardt
%
  p_hi =  10.0;
  p_lo = -10.0;
  test_num = 5;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST0183\n' );
  fprintf ( 1, '  CIRCLE_LLR2IMP_2D is given:\n' );
  fprintf ( 1, '  a line through P1 and P2,\n' );
  fprintf ( 1, '  a line through Q1 and Q2,\n' );
  fprintf ( 1, '  and a radius R,\n' );
  fprintf ( 1, '  and determines the centers C of 4 circles\n' );
  fprintf ( 1, '  of the given radius, tangent to both lines.\n' );

  seed = 123456789;

  for test = 1 : test_num

    [ p1(1:2,1), seed ] = r8vec_uniform ( 2, p_lo, p_hi, seed );
    [ p2(1:2,1), seed ] = r8vec_uniform ( 2, p_lo, p_hi, seed );
    [ q1(1:2,1), seed ] = r8vec_uniform ( 2, p_lo, p_hi, seed );
    [ q2(1:2,1), seed ] = r8vec_uniform ( 2, p_lo, p_hi, seed );

    r_lo = 1.0;
    r_hi = 5.0;
    [ r, seed ] = r8_uniform ( r_lo, r_hi, seed );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Radius R = %f\n', r );

    fprintf ( 1, '  Point #P1: %f  %f\n', p1(1:2,1) );
    fprintf ( 1, '  Point #P2: %f  %f\n', p2(1:2,1) );
    fprintf ( 1, '  Point #Q1: %f  %f\n', q1(1:2,1) );
    fprintf ( 1, '  Point #Q2: %f  %f\n', q2(1:2,1) );

    pc = circle_llr2imp_2d ( p1, p2, q1, q2, r );

    fprintf ( 1, '  Center #1: %f  %f\n', pc(1:2,1) );
    fprintf ( 1, '  Center #2: %f  %f\n', pc(1:2,2) );
    fprintf ( 1, '  Center #1: %f  %f\n', pc(1:2,3) );
    fprintf ( 1, '  Center #2: %f  %f\n', pc(1:2,4) );

    d1 = line_exp_point_dist_2d ( p1, p2, pc(1:2,1) );
    d2 = line_exp_point_dist_2d ( p1, p2, pc(1:2,2) );
    d3 = line_exp_point_dist_2d ( p1, p2, pc(1:2,3) );
    d4 = line_exp_point_dist_2d ( p1, p2, pc(1:2,4) );

    fprintf ( 1, '  %f  %f  %f  %f\n', d1, d2, d3, d4 );

    d1 = line_exp_point_dist_2d ( q1, q2, pc(1:2,1) );
    d2 = line_exp_point_dist_2d ( q1, q2, pc(1:2,2) );
    d3 = line_exp_point_dist_2d ( q1, q2, pc(1:2,3) );
    d4 = line_exp_point_dist_2d ( q1, q2, pc(1:2,4) );

    fprintf ( 1, '  %f  %f  %f  %f\n', d1, d2, d3, d4 );

  end

  return
end


function [X, info] = dominant_invariant_subspace_complex(A, p)
% Returns a unitary basis of the dominant invariant p-subspace of A.
%
% function X = dominant_invariant_subspace_complex(A, p)
%
% Input: A complex, Hermitian matrix A of size nxn and an integer p < n.
% Output: A complex, unitary matrix X of size nxp such that trace(X'*A*X)
%         is maximized. That is, the columns of X form a unitary basis
%         of a dominant subspace of dimension p of A.
%
% The optimization is performed on the complex Grassmann manifold, since
% only the space spanned by the columns of X matters.
%
% See dominant_invariant_subspace for more details in the real case.
%
% See also: dominant_invariant_subspace grassmanncomplexfactory

% This file is part of Manopt and is copyrighted. See the license file.
%
% Main author: Nicolas Boumal, June 30, 2015
% Contributors:
%
% Change log:
%
%   Xiaowen Jiang Aug. 31, 2021
%       Added AD to compute the egrad and the ehess

    % Generate some random data to test the function
    if ~exist('A', 'var') || isempty(A)
        A = randn(128) + 1i*randn(128);
        A = (A+A')/2;
    end
    if ~exist('p', 'var') || isempty(p)
        p = 3;
    end

    % Make sure the input matrix is Hermitian
    n = size(A, 1);
    assert(size(A, 2) == n, 'A must be square.');
    assert(norm(A-A', 'fro') < n*eps, 'A must be Hermitian.');
	assert(p<=n, 'p must be smaller than n.');

    % Define the cost and its derivatives on the complex Grassmann manifold
    Gr = grassmanncomplexfactory(n, p);
    problem.M = Gr;
    problem.cost  = @(X)    -real(trace(X'*A*X));
    problem.egrad = @(X)    -2*A*X;
    problem.ehess = @(X, H) -2*A*H;

    % An alternative way to compute the egrad and the ehess is to use
    % automatic differentiation provided in the deep learning toolbox
    % (slower). AD does not support complex numbers if the Matlab version
    % is R2021a or earlier. The cost function should be defined differently
    % In this case. See complex_example_AD.m and manoptADhelp.m for more
    % information.
    % problem.cost = @cost_complex;
    %    function f = cost_complex(X)
    %        AX = cprod(A,X);
    %        Xtransp = ctransp(X);
    %        product = cprod(Xtransp,AX);
    %        f = -creal(ctrace(product));
    %    end
    % call manoptAD to automatically obtain the egrad and the ehess
    % problem = manoptAD(problem);

    % If the version of Matlab installed is R2021b or later, specify the
    % cost function in the normal way and call manoptAD. Notice that
    % the function trace is not supported for AD so far. Replace it with
    % ctrace described in the file manoptADhelp.m
    % problem.cost  = @(X)    -real(ctrace(X'*A*X));
    % problem = manoptAD(problem);

    % Execute some checks on the derivatives for early debugging.
    % These can be commented out.
    % checkgradient(problem);
    % pause;
    % checkhessian(problem);
    % pause;

    % Issue a call to a solver. A random initial guess will be chosen and
    % default options are selected except for the ones we specify here.
    options.Delta_bar = 8*sqrt(p);
    [X, costX, info, options] = trustregions(problem, [], options); %#ok<ASGLU>

    fprintf('Options used:\n');
    disp(options);

    % For our information, Manopt can also compute the spectrum of the
    % Riemannian Hessian on the tangent space at (any) X. Computing the
    % spectrum at the solution gives us some idea of the conditioning of
    % the problem. If we were to implement a preconditioner for the
    % Hessian, this would also inform us on its performance.
    %
    % Notice that (typically) all eigenvalues of the Hessian at the
    % solution are positive, i.e., we find an isolated minimizer. If we
    % replace the Grassmann manifold by the Stiefel manifold, hence still
    % optimizing over orthonormal matrices but ignoring the invariance
    % cost(XQ) = cost(X) for all Q orthogonal, then we see
    % dim O(p) = p(p-1)/2 zero eigenvalues in the Hessian spectrum, making
    % the optimizer not isolated anymore.
    if Gr.dim() < 512
        evs = hessianspectrum(problem, X);
        stairs(sort(evs));
        title(['Eigenvalues of the Hessian of the cost function ' ...
               'at the solution']);
        xlabel('Eigenvalue number (sorted)');
        ylabel('Value of the eigenvalue');
    end

end


function [q] = MeshQuality(EToV,VX,VY)
%
% Purpose: Assess the triangle mesh quality using a mesh quality indicators.
%          q=2r/R, where r is the inradius and R is the circumradius of a
%          triangle.
%
%          Function is useful for detecting degenerate triangles.
%
%          EToV : Element-To-Vertice table
%          VX   : x-table for vertices
%          VY   : y-table for vertices
%
% By Allan P. Engsig-Karup, apek@imm.dtu.dk.

% Compute side lengths of triangles
lx = VX(EToV(:,[1 2 3])) - VX(EToV(:,[3 1 2]));
ly = VY(EToV(:,[1 2 3])) - VY(EToV(:,[3 1 2]));
l = sqrt(lx.^2+ly.^2);
a = l(:,1); b = l(:,2); c = l(:,3);
q = (b+c-a).*(c+a-b).*(a+b-c)./(a.*b.*c);

N = 100;
x = linspace(0,1,N+1);
dx = x(2)-x(1);
subdivision = x(1:N)+dx/2;
count = zeros(1,N);
K = size(EToV,1);
for i = 1 : length(subdivision)
    count(i) = length(find(q>subdivision(i)-dx/2 & q<=subdivision(i)+dx/2))/K*100;
end
figure
bar(subdivision,count,1)
minlimit = find(q<0.7);
if isempty(minlimit)
    axis([0.7 1 -1 max(count)*1.05])
else
    axis([min(q) 1 -1 max(count)*1.05])
    hold on
    plot([0.7 0.7],[0 100],'r--')
end
xlabel('Mesh quality')
ylabel('Percentage of elements')
colormap(cool)


function [ n_data, x, fx ] = fresnel_sin_values ( n_data )

%*****************************************************************************80
%
%% FRESNEL_SIN_VALUES returns some values of the Fresnel sine integral function.
%
%  Discussion:
%
%    The Fresnel sine integral is defined by
%
%      S(X) = integral ( 0 <= T <= X ) sin ( pi * T^2 / 2 ) / T dT
%
%    In Mathematica, the function can be evaluated by:
%
%      FresnelS[x]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Wolfram Media / Cambridge University Press, 1999.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
%    first call.  On each call, the routine increments N_DATA by 1, and
%    returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real X, the argument of the function.
%
%    Output, real FX, the value of the function.
%
  n_max = 16;

  fx_vec = [ ...
     0.0000000000000000E+00, ...
     0.4187609161656762E-02, ...
     0.3335943266061318E-01, ...
     0.1105402073593870E+00, ...
     0.2493413930539178E+00, ...
     0.4382591473903548E+00, ...
     0.6234009185462497E+00, ...
     0.7135250773634121E+00, ...
     0.6388876835093809E+00, ...
     0.4509387692675831E+00, ...
     0.3434156783636982E+00, ...
     0.4557046121246569E+00, ...
     0.6196899649456836E+00, ...
     0.5499893231527195E+00, ...
     0.3915284435431718E+00, ...
     0.4963129989673750E+00 ];

  x_vec = [ ...
     0.0E+00, ...
     0.2E+00, ...
     0.4E+00, ...
     0.6E+00, ...
     0.8E+00, ...
     1.0E+00, ...
     1.2E+00, ...
     1.4E+00, ...
     1.6E+00, ...
     1.8E+00, ...
     2.0E+00, ...
     2.2E+00, ...
     2.4E+00, ...
     2.6E+00, ...
     2.8E+00, ...
     3.0E+00 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    x = 0.0;
    fx = 0.0;
  else
    x = x_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


function ph=phase4(cp,mode)
% PHASE4 4 Quadrant arctangent.
%        PHASE4 provides a 4 quadrant arctangent of a complex number such
%        that -360 < PH <= 0.  It also takes care of wrapping when
%        necessary.

% Author: Craig Borghesani
% Date: 8/17/94
% Revised: 10/24/94
% Copyright (c) 1999, Prentice-Hall

ph = atan2(imag(cp),real(cp));

if nargin == 1, % normal phase computation for frequency response plots

 ph = ph - 2*pi*(ph>1e-5);

else % unwrap phase values for gain (phase) plot

 [r,c] = size(ph);
 for k = 1:c,
  dph = diff(ph(:,k));
  loc_brk = find(abs(dph)>pi);
  if length(loc_brk),
   brks = loc_brk;
   if dph(loc_brk(1)) > 0, brks = [0;brks]; end
   if dph(loc_brk(length(loc_brk))) < 0, brks = [brks;length(ph)]; end
   for k2 = 1:2:length(brks),
    ph((brks(k2)+1):(brks(k2+1)),k) = ph((brks(k2)+1):(brks(k2+1)),k) + 2*pi;
   end
  end
 end

end


function A = construct_incidence_matrix(measurements)
%function A = construct_incidence_matrix(measurements)
%
% This function computes and returns the oriented incidence matrix of the
% underlying directed graph of measurements:
%
% A_{ie} =  -1, if edge e *leaves* node i,
%           +1, if edge e *enters* node i,
%           0, otherwise.
%
% (see eq. (7) in the paper).

% Copyright (C) 2016 by David M. Rosen

N = max(max(measurements.edges));  % Number of nodes in the pose graph
M = size(measurements.edges, 1);  % Number of edges in the pose graph

out_nodes = measurements.edges(:, 1)';  %out_nodes(e) = i if edge e leaves node i
in_nodes = measurements.edges(:, 2)';  %out_nodes(e) = j if edge e enters node i

node_indices = [out_nodes, in_nodes];
edge_indices = [ [1:M], [1:M] ];
vals = [-ones(1, M), ones(1, M)];

A = sparse(node_indices, edge_indices, vals, N, M);

end


function zInterp=biquadraticInterp(xyPts,x0,y0,deltaX,deltaY,zGrid)
%%BIQUADRATICINTERP Biquadratic interpolation is interpolation of a
%       function that depends on two independent variables, by first
%       performing quadratic interpolation across one dimension, and then
%       performing quadratic interpolation across the next dimension. This
%       function assumes that in x and y generating the values in zGrid is
%       uniform.
%
%INPUTS: xyPts A 2XnumPts set of [x;y] pairs at which the value of z should
%              be interpolated.
%       x0, y0 These are values of the independent variables corresponding
%              to the entry in zGrid(1,1).
% deltaX, deltaY The uniform spacings between the independent variables for
%              gridded elements in zGrid. Thus, zGrid(i,j) holds the z
%              value associated with x=x0+deltaX*(i-1) and
%              y=y0+deltaY*(i-1).
%        zGrid A numXXnumY matrix of values of the independent variable
%              for different values of the dependent variables. The first
%              index selects the x value and the second index the y value.
%              numX>=3 and numY>=3.
%
%OUTPUTS: zInterp A 1XnumPts vector of interpolated values.
%
%Biquadratic interpolation is described in [1]. However, this function does
%not use the implementation that is given at the end of [1].
%
%EXAMPLE:
%A 2D function is evaluated and plotted. Then, the function is evaluated at
%a much smaller number of points and those are used to interpolate and plot
%the function again. The basis points are ploted in black. The
%small discontinuities between interpolation regions can be seen.
% numXPts=400;
% numYPts=401;
% plotXPts=linspace(-1,1,numXPts);
% plotYPts=linspace(-1,1,numYPts);
% z=@(xy)sum(sin(1-(16/15)*xy).^2-(1/50)*sin(4-(64/15)*xy)-sin(1-(16/15)*xy),1);
% [Y,X]=meshgrid(plotYPts,plotXPts);
% xy=[X(:).';Y(:).'];
% Z=reshape(z(xy),[numXPts,numYPts]);
%
% figure(1)
% clf
% hold on
% surface(X,Y,Z,'edgeColor','None')
%
% %Get a small number of points to use for interpolation and mark the
% %points on the plot.
% numXBasis=10;
% numYBasis=11;
% x0=-1;
% y0=-1;
% xBasis=linspace(x0,1,numXBasis);
% yBasis=linspace(y0,1,numYBasis);
% deltaX=xBasis(2)-xBasis(1);
% deltaY=yBasis(2)-yBasis(1);
% [YB,XB]=meshgrid(yBasis,xBasis);
% xyB=[XB(:).';YB(:).'];
% ZGrid=reshape(z(xyB),[numXBasis,numYBasis]);
% scatter3(XB(:),YB(:),ZGrid(:),200,'.k')
% view(25,50)
%
% %Now, interpolate the surface using the above basis points.
% ZInterp=biquadraticInterp(xy,x0,y0,deltaX,deltaY,ZGrid);
% ZInterp=reshape(ZInterp,[numXPts,numYPts]);
%
% %Plot the biquadratically interpolated surface and the control points.
% figure(2)
% clf
% hold on
% surface(X,Y,ZInterp,'edgeColor','None')
% scatter3(XB(:),YB(:),ZGrid(:),200,'.k')
% view(25,50)
%
%REFERENCES:
%[1] D. Smith, "NOAA technical memorandum NOS NGS 84: Biquadratic
%    interpolation," National Oceanic and Atmospheric Administration,
%    National Geodetic Survey, Silver Spring, MD, Tech. Rep., Sep. 2020.
%
%July 2021 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

numPts=size(xyPts,2);
zInterp=zeros(1,numPts);

numX=size(zGrid,1);
numY=size(zGrid,2);

for curPt=1:numPts
    xCur=xyPts(1,curPt);
    yCur=xyPts(2,curPt);

    idxX=round((xCur-x0)/deltaX)+1;
    idxY=round((yCur-y0)/deltaY)+1;

    %The points cannot be endpoints.
    idxX=idxX+(idxX==1)-(idxX==numX);
    idxY=idxY+(idxY==1)-(idxY==numY);

    %First, interpolate across X for each Y.
    x0Cur=x0+deltaX*(idxX-2);
    y0Cur=y0+deltaY*(idxY-2);

    zInterp1=quadraticInterpUnif3Pt(xCur,x0Cur,deltaX,zGrid(idxX-1,idxY-1),zGrid(idxX,idxY-1),zGrid(idxX+1,idxY-1));
    zInterp2=quadraticInterpUnif3Pt(xCur,x0Cur,deltaX,zGrid(idxX-1,idxY),zGrid(idxX,idxY),zGrid(idxX+1,idxY));
    zInterp3=quadraticInterpUnif3Pt(xCur,x0Cur,deltaX,zGrid(idxX-1,idxY+1),zGrid(idxX,idxY+1),zGrid(idxX+1,idxY+1));

    zInterp(curPt)=quadraticInterpUnif3Pt(yCur,y0Cur,deltaY,zInterp1,zInterp2,zInterp3);
end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function [y] = l1median_VaZh_z(X, maxiter, tol, zerotol, medIn )
%To calculate the L1_median of X  with the l1median_VaZh method
%INput:
%     X       ---the number of the records is the number of rows
%     maxiter ---the max number of iteration
%     tol     ---the tolerance of iteration
%     zerotol ---the tolerance of vector to zero
%     medIn   ---a row vector representing initial median of X
%output:
%     y       ---the median of X

    %To discuss the parameters
    if (nargin > 5)
        error ('Too many input arguments.') ;
    elseif (nargin < 5)
        medIn = median(X);
        if(nargin < 4)
            zerotol = 1e-15 ;
            if (nargin < 3)
                tol = 1e-9 ;
                if (nargin < 2)
                    maxiter = 200 ;
                    if (nargin < 1)
                        error ('Data matrix X is missing.') ;
                    end
                end
            end
        end
    end

    [rn,vn] = size(X);
    iterdis = 1;
    iter = 0;
    y = medIn;

    %Begin the iteration
    while (iterdis > 0) && (iter < maxiter)
        Tnum=zeros(1,vn);
        R = zeros(1,vn);
        Tden=0;
        yita = 0;
        for i=1:rn
            dist = norm(X(i,:)-y);
            if dist >= zerotol
                Tnum = Tnum + X(i,:)/dist;
                Tden=Tden + 1/dist;
                R = R + (X(i,:)-y)/dist;
            else
                yita = 1;
            end
        end

        if Tden == 0
            T=0;
        else
           T=Tnum/Tden;
        end

        if norm(R) == 0
            r = 0;
        else
            r = min(1,yita/norm(R));
        end

        Ty = (1-r)*T + r*y;

        iterdis = norm((Ty-y),1) - tol*norm(y,1);
        iter = iter + 1;
        y=Ty;

    end

    %End the iteration


function [f] = poch(z,n)
%Pochhammer function (z)n = z(z+1)(z+2)...(z+n-1)
%
%usage:  f = poch(z,n)
%
%tested on version 5.3.1
%
%        z and n may be complex but must be equal in size.
%
%see also: Gamma, Fact

%Paul Godfrey
%pgodfrey@conexant.com
%8-24-00

f = gamma(z+n)./gamma(z);

p=find(z==0 & n==0);
if ~isempty(p)
    f(p)=0;
end

return


function result=cpcr(x,y,varargin)

%CPCR performs a classical principal components regression.
% First, classical PCA is applied to the predictor variables x (see cpca.m) and
% k components are retained. Then a multiple linear regression method (see mlr.m)
% is performed of the response variable y on the k principal components.
%
% I/O: result=cpcr(x,y,'k',2);
%
% Required input arguments:
%      x : Data matrix of the explanatory variables
%          (n observations in rows, p variables in columns)
%      y : Data matrix of the response variables
%          (n observations in rows, q variables in columns)
%
% Optional input argument:
%      k : Number of principal components to compute. If k is missing,
%          a scree plot is drawn which allows to select
%          the number of principal components.
%  plots : If equal to one (default), a menu is shown which allows to draw several plots,
%          such as a score outlier map and a regression outlier map.
%          If 'plots' is equal to zero, all plots are suppressed.
%          See also makeplot.m
%
% The output is a structure containing
%
%   result.slope      : Classical slope
%   result.int        : Classical intercept
%   result.fitted     : Classcial prediction vector
%   result.res        : Classical residuals
%   result.sigma      : Estimated variance-covariance matrix of the residuals
%   result.rsquared   : R-squared value
%   result.k          : Number of components used in the regression
%   result.sd         : Classical score distances
%   result.od         : Classical orthogonal distances
%   result.resd       : Residual distances (when there are several response variables).
%                       If univariate regression is performed, it contains the standardized residuals.
%   result.cutoff     : Cutoff values for the score, orthogonal and residual distances.
%   result.flag      : The observations whose orthogonal distance is larger than result.cutoff.od
%                      (orthogonal outliers => result.flag.od) and/or whose residual distance is
%                      larger than result.cutoff.resd (bad leverage points/vertical outliers => result.flag.resd)
%                      can be considered as outliers and receive a flag equal to zero (=> result.flag.all).
%                      The regular observations, including the good leverage points, receive a flag 1.
%   result.class      : 'CPCR'
%   result.cpca       : Full output of the classical PCA part (see cpca.m)
%
% This function is part of LIBRA: the Matlab Library for Robust Analysis,
% available at:
%              http://wis.kuleuven.be/stat/robust.html
%
% Written by S. Verboven
% Last Update: 05/04/2003

default=struct('plots',1,'k',0);
list=fieldnames(default);
options=default;
IN=length(list);
i=1;
counter=1;
if nargin>2
    %
    % placing inputfields in array of strings
    %
    for j=1:nargin-2
        if rem(j,2)~=0
            chklist{i}=varargin{j};
            i=i+1;
        end
    end
    % Checking which default parameters have to be changed
    % and keep them in the structure 'options'.
    while counter<=IN
        index=strmatch(list(counter,:),chklist,'exact');
        if ~isempty(index) % in case of similarity
            for j=1:nargin-2 % searching the index of the accompanying field
                if rem(j,2)~=0 % fieldnames are placed on odd index
                    if strcmp(chklist{index},varargin{j})
                        I=j;
                    end
                end
            end
            options=setfield(options,chklist{index},varargin{I+1});
            index=[];
        end
        counter=counter+1;
    end
end

%classical PCA
if options.k==0
    out.cpca=cpca(x,'plots',0);
else
    out.cpca=cpca(x,'plots',0,'k',options.k);
end
%model with intercept
T=[out.cpca.T(:,1:out.cpca.k) ones(size(out.cpca.T,1),1)];
%Multivariate linear regression
out.a=inv(T'*T)*T'*y;
out.fitted=T*out.a;
len=size(out.a,1);
p=size(T,2);
q=size(y,2);
geg=[T,y];
[n,m]=size(geg);
S=cov(geg);
Sx=S(1:p-1,1:p-1);
Sxy=S(1:p-1,p+1:m);
Syx=Sxy';
Sy=S(p+1:m,p+1:m);
Se=Sy-out.a(1:p-1,1:q)'*Sx*out.a(1:p-1,1:q); %variance of errors
%regression coefficients slope and intercept ([\beta \alpha])
out.coeffs=[out.cpca.P(:,1:out.cpca.k)*out.a(1:len-1,:); out.a(len,:)-out.cpca.M*out.cpca.P(:,1:out.cpca.k)*out.a(1:len-1,:)];    %%coefficients in the original space;
out.slope=out.cpca.P(:,1:out.cpca.k)*out.a(1:len-1,:);
out.int=out.a(len,:)-out.cpca.M*out.cpca.P(:,1:out.cpca.k)*out.a(1:len-1,:);
out.res=y-out.fitted;
out.sigma=Se;
if q==1
    out.stdres=out.res./sqrt(diag(out.sigma));
end
out.k=out.cpca.k;
STTm=sum((y-repmat(mean(y),length(y),1)).^2);
SSE=sum(out.res.^2);
out.rsquared=1-SSE/STTm;
out.class='CPCR';

%calculating residual distances
if q>1
    if (-log(det(Se)/(m-1)))>50
        out.resd='singularity';
    else
       cen=zeros(q,1);
       out.resd=sqrt(libra_mahalanobis(out.res,cen','cov',Se))';
   end
else % q==1
    out.resd=out.stdres; %standardized residuals
end
out.cutoff=out.cpca.cutoff;
out.cutoff.resd=sqrt(chi2inv(0.975,size(y,2)));
%computing flags
out.flag.od=out.cpca.flag.od;
out.flag.sd=out.cpca.flag.sd;
out.flag.resd=abs(out.resd)<=out.cutoff.resd;
out.flag.all=(out.flag.od & out.flag.resd);

result=struct( 'slope',{out.slope}, 'int',{out.int},'fitted',{out.fitted},'res',{out.res},...
    'cov',{out.sigma},'rsquared',{out.rsquared},...
    'k',{out.k},'sd', {out.cpca.sd},'od',{out.cpca.od},'resd',{out.resd},...
    'cutoff',{out.cutoff},'flag',{out.flag},'class',{out.class},...
    'cpca',{out.cpca});

try
    if options.plots
        makeplot(result)
    end
catch %output must be given even if plots are interrupted
    %> delete(gcf) to get rid of the menu
    end


%% Distributed Marginal Value-at-Risk Simulation
% This example uses the Parallel Computing Toolbox(TM) to perform a Monte
% Carlo simulation of a number of stocks in a portfolio. At a given
% confidence level, we predict the value at risk (VaR) of the portfolio as
% well as the marginal value at risk (mVaR) of each of the stocks in the
% portfolio.  We also provide confidence intervals for our estimates.
%
%   Copyright 2007-2012 The MathWorks, Inc.
%   Adapted and simplified in 2013 by Michael Weidman, Quantitative Support
%   Services, Ltd.

%% 1. Open a pool of MATLAB workers and load input data

if matlabpool('size') == 0
    matlabpool open
end

load pctdemo_data_mvar

%% 2. Define Parameters

nSims           = 1e5;
relativeWeights = [1 1 2 2 1 3 2]/12;
time            = 50;%(10:1:50)';
confLevel       = 95;

nTimes          = length(time);
nAssets         = size(stock,2);

%% 3. Estimate asset moments

returns         = (stock(2:end,:) - stock(1:end-1,:)) ./ stock(1:end-1,:);
expReturns      = mean(returns);
expCovariances  =  cov(returns);

%% 4. Simulate asset prices

tic

simPrices   = zeros(nTimes, nAssets, nSims);
portPrices  = zeros(nTimes,       1, nSims);
price0      = stock(end,:);
portPrice0  = price0 * relativeWeights';

parfor iSim = 1:nSims
    simPrices( :,:,iSim) = simulatePrices(expReturns, expCovariances, ...
        price0, time);
    portPrices(:,:,iSim) = sum(bsxfun(@times, simPrices(:,:,iSim), ...
        relativeWeights), 2);
end

toc

%% 5. Calculate mVaR and VaR

simRelativeLosses = bsxfun(@rdivide, ...
    bsxfun(@minus, price0, simPrices), price0);
simRelativePortLosses = bsxfun(@minus, portPrice0, portPrices) ...
    ./ portPrice0;

mVaR = prctile(simRelativeLosses    , confLevel, 3);
VaR  = prctile(simRelativePortLosses, confLevel, 3);

%% 6. Plot the Results

plotMVAR(VaR, mVaR, time, names);


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni

% N- point IDFTs of a 4-point sequence

X=[10 -2+2j -2 -2-2j];

% 4-point IDFT
ifft(X)

% 4-point IDFT
idft(X)

% 6-point IDFT
ifft(X,6)

% 6-point IDFT
X(6)=0
ifft(X)


function point_num = sphere_icos_point_num ( factor )

%*****************************************************************************80
%
%% SPHERE_ICOS_POINT_NUM sizes an icosahedral grid on a sphere.
%
%  Discussion:
%
%    With FACTOR = 1, the grid has 20 triangular faces, 30 edges, and 12 nodes.
%
%    With FACTOR = 2, each triangle of the icosahedron is subdivided into
%    2x2 subtriangles, resulting in 80 faces, 120 edges, and
%    42 = 12 + 20 * 3 * (1)/2 + 20 * 0 ) nodes.
%
%    With FACTOR = 3, each triangle of the icosahedron is subdivided into
%    3x3 subtriangles, resulting in 180 faces, 270 edges, and
%    92 ( = 12 + 20 * 3 * (2)/2 + 20 * 1 ) nodes.
%
%    In general, each triangle is subdivided into FACTOR*FACTOR subtriangles,
%    resulting in 20 * FACTOR * FACTOR faces, 30 * FACTOR * FACTOR edges, and
%      12
%    + 20 * 3          * (FACTOR-1) / 2
%    + 20 * (FACTOR-2) * (FACTOR-1) / 2 nodes.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 July 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer FACTOR, the subdivision factor, which must
%    be at least 1.
%
%    Output, integer POINT_NUM, the number of nodes.
%
  point_num =   12                                   ...
              + 10 * 3              * ( factor - 1 ) ...
              + 10 * ( factor - 2 ) * ( factor - 1 );

  return
end


function xfat = r8vec_expand_linear ( n, x, fat )

%*****************************************************************************80
%
%% R8VEC_EXPAND_LINEAR linearly interpolates new data into a vector.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 October 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of input data values.
%
%    Input, real X(N), the original data.
%
%    Input, integer FAT, the number of data values to interpolate
%    between each pair of original data values.
%
%    Output, real XFAT((N-1)*(FAT+1)+1), the "fattened" data.
%
  k = 0;

  for i = 1 : n-1

    k = k + 1;
    xfat(k) = x(i);

    for j = 1 : fat
      k = k + 1;
      xfat(k) = ( ( fat - j + 1 ) * x(i)     ...
                + (       j     ) * x(i+1) ) ...
                / ( fat     + 1 );
    end

  end

  k = k + 1;
  xfat(k) = x(n);

  return
end


function t = tvec_even_bracket2 ( nt, theta1, theta2 )

%*****************************************************************************80
%
%% TVEC_EVEN_BRACKET2 computes an evenly spaced set of angles between THETA1 and THETA2.
%
%  Example:
%
%    NT = 5
%    THETA1 = 30
%    THETA2 = 90
%
%    T = ( 40, 50, 60, 70, 80 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NT, the number of values to compute.
%
%    Input, real THETA1, THETA2, the limiting angles.
%
%    Output, real TVEC(NT), the evenly spaced angles.
%
  for i = 1 : nt
    t(i) = ( ( nt + 1 - i ) * theta1   ...
           + (          i ) * theta2 ) ...
           / ( nt + 1     );
  end

  return
end


function [ code, itree, more ] = tree_parent_next ( nnode, more )

%*****************************************************************************80
%
%% TREE_PARENT_NEXT generates, one at a time, all labeled trees.
%
%  Discussion:
%
%    The routine also returns the corresponding Pruefer codes.
%
%    There are N^(N-2) labeled trees on N nodes (Cayley's formula).
%
%    The number of trees in which node I has degree D(I) is the
%    multinomial coefficient: ( N-2; D(1)-1, D(2)-1, ..., D(N)-1 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 June 2013
%
%  Parameters:
%
%    Input, integer NNODE, the number of nodes to be used in
%    the trees.
%
%    Output, integer CODE(NNODE).  The first NNODE-2 entries
%    of CODE contain the Pruefer code for the given labeled tree.
%
%    Output, integer ITREE(NNODE).  The first NNODE-1 entries
%    of ITREE describe the edges that go between the nodes.  Each pair
%    (I, ITREE(I)) represents an edge.  Thus if ITREE(5) = 3,
%    there is an edge from node 3 to node 5.
%
%    Input/output, logical MORE.  On the first call only, the
%    user is required to set MORE = .FALSE.  Then call the routine, and
%    it will return information about the first tree
%    as well as setting MORE to the value .TRUE.
%    Keep calling to get another tree until MORE is .FALSE.
%    on return, at which point there are no more trees.
%
  persistent iarray;

  if ( ~ more )
    iarray = [];
  end

  [ iarray, more ] = vec_next ( nnode-2, nnode, iarray, more );

  code(1:nnode-2) = iarray(1:nnode-2) + 1;

  itree = pruefer_to_tree_2 ( nnode, code );

  return
end


function [all_theta] = oneVsAll(X, y, num_labels, lambda)
    %% ONEVSALL trains multiple logistic regression classifiers and returns all
    %the classifiers in a matrix all_theta, where the i-th row of all_theta
    %corresponds to the classifier for label i
    %   [all_theta] = ONEVSALL(X, y, num_labels, lambda) trains num_labels
    %   logisitc regression classifiers and returns each of these classifiers
    %   in a matrix all_theta, where the i-th row of all_theta corresponds
    %   to the classifier for label i

    % Some useful variables
    n = size(X, 1);
    d = size(X, 2);

    % You need to return the following variables correctly
    all_theta = zeros(num_labels, d + 1);

    % Add ones to the X data matrix
    X = [ones(n, 1) X];

    % ====================== YOUR CODE HERE ======================
    % Instructions: You should complete the following code to train num_labels
    %               logistic regression classifiers with regularization
    %               parameter lambda.
    %
    % Hint: theta(:) will return a column vector.
    %
    % Hint: You can use y == c to obtain a vector of 1's and 0's that tell use
    %       whether the ground truth is true/false for this class.
    %
    % Note: For this assignment, we recommend using fmincg to optimize the cost
    %       function. It is okay to use a for-loop (for c = 1:num_labels) to
    %       loop over the different classes.
    %
    %       fmincg works similarly to fminunc, but is more efficient when we
    %       are dealing with large number of parameters.
    %
    % Example Code for fmincg:
    %
    %     % Set Initial theta
    %     initial_theta = zeros(n + 1, 1);
    %
    %     % Set options for fminunc
    %     options = optimset('GradObj', 'on', 'MaxIter', 50);
    %
    %     % Run fmincg to obtain the optimal theta
    %     % This function will return theta and the cost
    %     [theta] = ...
    %         fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
    %                 initial_theta, options);
    %

    % for optimization of theta
    options = optimset('GradObj', 'on', 'MaxIter', 50);

    % for each class label
    for k = 1 : num_labels

        % initialize theta, and minimize value for cost function
        init_theta = zeros(d + 1, 1);
        theta = fmincg(@(t)(lrCostFunction(t, X, (y == k), lambda)), ...
            init_theta, options);
        all_theta(k, :) = theta';
    end
end


% MAHAL2CONF - Translates a Mahalanobis distance into a confidence
%              interval.  Consider a multivariate Gaussian
%              distribution of the form
%
%   p(x) = 1/sqrt((2 * pi)^d * det(C)) * exp((-1/2) * MD(x, m, inv(C)))
%
%              where MD(x, m, P) is the Mahalanobis distance from x
%              to m under P:
%
%                 MD(x, m, P) = (x - m) * P * (x - m)'
%
%              A particular Mahalanobis distance k identifies an
%              ellipsoid centered at the mean of the distribution.
%              The confidence interval associated with this ellipsoid
%              is the probability mass enclosed by it.
%
%              If X is an d dimensional Gaussian-distributed vector,
%              then the Mahalanobis distance of X is distributed
%              according to the Chi-squared distribution with d
%              degrees of freedom.  Thus, the confidence interval is
%              determined by integrating the chi squared distribution
%              up to the Mahalanobis distance of the measurement.
%
% Usage:
%
%   c = mahal2conf(m, d);
%
% Inputs:
%
%   m    - the Mahalanobis radius of the ellipsoid
%   d    - the number of dimensions of the Gaussian distribution
%
% Outputs:
%
%   c    - the confidence interval, i.e., the fraction of
%          probability mass enclosed by the ellipsoid with the
%          supplied Mahalanobis distance
%
% See also: CONF2MAHAL

% Copyright (C) 2002 Mark A. Paskin
%
% 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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function c = mahal2conf(m, d)

c = chi2cdf(m, d);


function [varargout] = cubic_cubic_integrated_distance( ...
    x, ...
    y, ...
    g_C, ...
    h_C, ...
    P, ...
    g_D, ...
    h_D, ...
    Q)
  %
  % [E] = cubic_cubic_integrated_distance( x, y, g_C, h_C, P, g_D, h_D, Q)
  % [H,F,c] = cubic_cubic_integrated_distance( x, y, g_C, h_C, P, g_D, h_D)
  %
  % E = ½ ∫ₓʸ ‖ C( g_C u + h_C ) - D( g_D u + h_D ) ‖² du
  %
  % where C's control points are in rows of P and D's control points are in rows
  % of Q.
  %
  % E = 0.5*trace(Q.'*H*Q) + trace(Q.'*F) + c;
  %
  % That is,
  %   Q★ = argmin_Q E(Q)
  %   Q★ = H⁻¹ F
  %
  % Where
  %
  % C(T) = (1-T)³ Pᵢ⁰ + 3(1-T)²T Pᵢ¹ + 3(1-T)T² Pᵢ² + T³ Pᵢ³
  % D(T) = (1-T)³ Qᵢ⁰ + 3(1-T)²T Qᵢ¹ + 3(1-T)T² Qᵢ² + T³ Qᵢ³
  %
  % Inputs:
  %   x  starting value of integral 0≤x<1
  %   y  ending value of integral x<y≤1
  %   g_C  scalar multiplicative factor in parametric values of fixed curve
  %   h_C  scalar additive factor in parametric values of fixed curve
  %   P  4 by dim list of fixed curve control points
  %   g_D  scalar multiplicative factor in parametric values of fixed curve
  %   h_D  scalar additive factor in parametric values of fixed curve
  %   Q  4 by dim list of unknown curve control points (optional)
  % Outputs
  %   E  integrated energy
  %   H  4 by 4 quadratic form of energy as function of Q
  %   F  4 by dim linear term of energy as function of Q
  %   c  scalar constant of energy as function of Q
  %
  if isfloat(x) && isfloat(y)
    assert(x>=0);
    assert(x<1);
    assert(y>=x);
    assert(y<=1);
  end
  dim = size(P,2);

  % https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature
  % n is number of points
  % 2n-1 order polynomial is integrated exactly
  % ↓
  % n = 4

  % https://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules/quadrature_rules.html
  % n=4 Gauss-Legendre quadrature on [-1,1]
  w = [
    0.347854845137453857373063949222
    0.652145154862546142626936050778
    0.652145154862546142626936050778
    0.347854845137453857373063949222
    ];
  a = [
   -0.861136311594052575223946488893
   -0.339981043584856264802665759103
    0.339981043584856264802665759103
    0.861136311594052575223946488893
  ];
  % Move to [x,y] range.
  u = (0.5*a + 0.5)*(y-x)+x;
  % Adjust weights.
  w = ((y-x)/(1- -1))*w;

  % Evaluate C at quadrature points
  C = cubic_eval( P, g_C*u + h_C);

  % Map quadrature points to D's direct paramter space
  T = g_D * u + h_D;

  if nargout<=1
    % Compute energy directly. This is faster. Better be the same as below.
    %
    % It's ever so slightly different (between 1e-16 and 1e-20)
    E = 0.5*sum(w.*(C - cubic_eval( Q, T)).^2,'all');
    varargout{1} = E;
    return;
  end

  % Stack bezier basis matrices for each evaluation point
  M = [(1-T).^3 3*T.*(1-T).^2 3*T.^2.*(1-T) T.^3];

  W = diag(w);

  H = M.'*W*M;
  assert(all(size(H) == [4 4]));
  F = -M.'*W*C;
  assert(size(F,1) == 4);
  assert(size(F,2) == dim);

  c = 0.5*trace(C.'*W*C);

  if isempty(Q)
    warning("Cant compute energy on empty Q");
    E = [];
  else
    % Actually compute energy
    E = 0.5*trace(Q.'*H*Q) + trace(Q.'*F) + c;
  end

  varargout{1} = H;
  varargout{2} = F;
  varargout{3} = c;
  varargout{4} = E;
end


function A = sllinreg(X, Y, varargin)
%SLLINREG Performs Multivariate Linear Regression and Ridge Regression
%
% $ Syntax $
%   - A = sllinreg(X, Y, ...)
%
% $ Arguments $
%   - X:        The matrix of x samples
%   - Y:        The matrix of y samples
%   - A:        The solved transform matrix
%
% $ Description $
%   - A = sllinreg(X, Y, varargin) solves the linear regression problem to
%     get the linear transforms A: (y = Ax + e). The solution is given by
%     the following optimization problem:
%       A = argmin_{A} sum_i ||y_i - A x_i||^2 + sum_k lambda_k ||a_k||^2
%     Here, Y is a dy x n matrix with the i-th column giving y_i;
%           X is a dx x n matrix with the i-th column giving x_i
%           A is a dy x dx transform matrix
%           a_k is the k-row vector of A, which corresponds to the k-th
%                  component of y
%           lambda_k is the regularization weight in ridge regression
%     According to mathematical analysis, the solution is given as
%       A = (Y * X^T) * (X * X^T + diag(lambda))^{-1}
%     You can specify the following properties to control the regression:
%     \*
%     \t    Table  Linear Regression Properties
%     \h        name       &             description
%              'lambdas'   &  The regularization coefficients in ridge
%                             linear regression. If all components share
%                             the same value, then lambdas can be a scalar.
%                             If different values are for different
%                             dimensions, then lambdas can be a dy x 1
%                             column vector. (default = 0)
%              'weights'   &  The sample weights, can be either [] or
%                             an 1 x n row vector.
%              'invparams' &  The parameters for invoking slinvcov to
%                             compute inverse matrix, in the form of
%                             {method, ...}. default = [], means directly
%                             using inv to do inverse.
%     \*
%
% $ Remarks $
%   - To solve the linear problem like y = Ax + b, you have two ways:
%     (1) centralize x and y respectively, and invoke sllinreg, then set
%         b = my - A * mx
%     (2) invoke sllinrega, which is specially designed for such an
%         augmented problem.
%
% $ History $
%   - Created by Dahua Lin, on Sep 15, 2006
%

%% parse and verify input arguments

if nargin < 2
    raise_lackinput('sllinreg', 2);
end

if ~isnumeric(X) || ~isnumeric(Y) || ndims(X) ~= 2 || ndims(Y) ~= 2
    error('sltoolbox:invalidarg', ...
        'The X and Y should be both 2D numeric matrices');
end

[dx, n] = size(X);
[dy, ny] = size(Y);
if n ~= ny
    error('sltoolbox:sizmismatch', ...
        'X and Y contain different numbers of samples');
end

opts.lambdas = 0;
opts.rv = 1e-3;
opts.weights = [];
opts.invparams = [];
opts = slparseprops(opts, varargin{:});

lambdas = opts.lambdas;
if ~isscalar(lambdas) && ~isequal(size(lambdas), [dy, 1])
    error('lambdas should be either a scalar or a dy x 1 column vector');
end

w = opts.weights;
if ~isempty(w)
    if ~isequal(size(w), [1, n])
        error('The sample weights should be a 1 x n row vector');
    end
end

%% main

if isempty(w)
    Xt = X';
else
    Xt = slmulvec(X, w, 2)';
end

M2 = X * Xt;
if ~isequal(lambdas, 0)
    inds = (1:dx)' * (dx+1) - dx;
    M2(inds) = M2(inds) + lambdas;
end

if isempty(opts.invparams)
    invM2 = inv(M2);
else
    invM2 = slinvcov(M2, opts.invparams{:});
end
clear M2;

M1 = Y * Xt;

A = M1 * invM2;


function [y, sigma, p] = linRegPred(model, X, t)
% Compute linear regression model reponse y = w'*X+w0 and likelihood
% Input:
%   model: trained model structure
%   X: d x n testing data
%   t (optional): 1 x n testing response
% Output:
%   y: 1 x n prediction
%   sigma: variance
%   p: 1 x n likelihood of t
% Written by Mo Chen (sth4nth@gmail.com).
w = model.w;
w0 = model.w0;
y = w'*X+w0;
%% probability prediction
if nargout > 1
    beta = model.beta;
    if isfield(model,'U')
        U = model.U;        % 3.54
        Xo = bsxfun(@minus,X,model.xbar);
        XU = U'\Xo;
        sigma = sqrt((1+dot(XU,XU,1))/beta);   % 3.59
    else
        sigma = sqrt(1/beta)*ones(1,size(X,2));
    end
end

if nargin == 3 && nargout == 3
    p = exp(-0.5*(((t-y)./sigma).^2+log(2*pi))-log(sigma));
end


% Implement a simple version of "Geodesics in Heat" by Crane et al. 2013

clc; clear all; close all;
[V,F] = readOBJ('../data/spot.obj');
[V,F,S] = loop(V,F,2); % upsample the mesh to see the speed difference
use_prefactorization = true; % set it to "true" or "false" to see speed difference

% precompute matrices
A = massmatrix(V,F);
Lc = cotmatrix(V,F);
t = avgedge(V,F)^2;
LHS = A - t*Lc;
G = grad(V,F); % #F*dim by #V
D = div(V,F); % #V by #F*dim

% prefactorization
preLHS = decomposition(LHS);
preLc = decomposition(Lc);

%% change heat source
heatSrcIdx = 1;

tic;

% step 1
delta = zeros(size(V,1),1);
delta(heatSrcIdx) = 1;
if use_prefactorization
    u = preLHS \ delta;
else
    u = LHS \ delta;
end

% step 2
gradu = G*u;
gradu = reshape(gradu, size(F,1), 3);
gradu_normalized = gradu ./ normrow(gradu);
X = -gradu_normalized;

% step 3
divX = D * reshape(X, size(F,1)*3, 1);
if use_prefactorization
    phi = preLc \ divX;
else
    phi = Lc \ divX;
end
phi = phi - phi(heatSrcIdx);

toc;

%% visualization
tsurf(F,V, 'CData', phi);
axis equal;
CM = cbrewer('Reds', 500);
CM = CM(size(CM,1):-1:1,:);
colormap(CM);
colorbar
shading interp
drawnow


function [ t, wts ] = sgqf ( nt, aj, bj, zemu )

%*****************************************************************************80
%
%% SGQF computes knots and weights of a Gauss Quadrature formula.
%
%  Discussion:
%
%    This routine computes all the knots and weights of a Gauss quadrature
%    formula with simple knots from the Jacobi matrix and the zero-th
%    moment of the weight function, using the Golub-Welsch technique.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, real AJ(NT), the diagonal of the Jacobi matrix.
%
%    Input, real BJ(NT), the subdiagonal of the Jacobi
%    matrix, in entries 1 through NT-1.  On output, BJ has been overwritten.
%
%    Input, real ZEMU, the zero-th moment of the weight function.
%
%    Output, real T(NT), the knots.
%
%    Output, real WTS(NT), the weights.
%

%
%  Exit if the zero-th moment is not positive.
%
  if ( zemu <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'SGQF - Fatal error!\n' );
    fprintf ( 1, '  ZEMU <= 0.\n' );
    error ( 'SGQF - Fatal error!' );
  end
%
%  Set up vectors for IMTQLX.
%
  wts = zeros ( nt, 1 );

  wts(1) = sqrt ( zemu );
  wts(2:nt) = 0.0;
%
%  Diagonalize the Jacobi matrix.
%
  [ t, wts ] = imtqlx ( nt, aj, bj, wts );

  wts(1:nt) = wts(1:nt).^2;

  return
end


function [J, grad] = linearRegCostFunction(X, y, theta, lambda)
%LINEARREGCOSTFUNCTION Compute cost and gradient for regularized linear
%regression with multiple variables
%   [J, grad] = LINEARREGCOSTFUNCTION(X, y, theta, lambda) computes the
%   cost of using theta as the parameter for linear regression to fit the
%   data points in X and y. Returns the cost in J and the gradient in grad

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly
J = 0;
grad = zeros(size(theta));
J = 1/(2*m)*sum((X*theta-y).^2)+lambda/(2*m)*(sum(theta.^2)-theta(1).^2);

grad = 1/m*X'*(X*theta-y)+lambda/m*theta;
grad(1) = grad(1) -lambda/m*theta(1);
% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost and gradient of regularized linear
%               regression for a particular choice of theta.
%
%               You should set J to the cost and grad to the gradient.
%

% =========================================================================

grad = grad(:);

end


function value = u_integral ( e )

%*****************************************************************************80
%
%% U_INTEGRAL: integral ( -1 <= x <= +1 ) x^e sqrt ( 1 - x^2 ) dx.
%
%  Discussion:
%
%     E    U_INTEGRAL
%    --    --------------
%     0         pi /    2
%     2         pi /    8
%     4         pi /   16
%     6     5 * pi /  128
%     8     7 * pi /  256
%    10    21 * pi / 1024
%    12    33 * pi / 2048
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 April 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer E, the exponent of X.
%    0 <= E.
%
%    Output, real VALUE, the value of the integral.
%
  if ( mod ( e, 2 ) == 1 )

    value = 0.0;

  else

    arg1 = 0.5 * ( 1 + e );
    arg2 = 2.0 + 0.5 * e;
    value = 0.5 * sqrt ( pi ) * gamma ( arg1 ) / gamma ( arg2 );

  end

  return
end


function v=scatterquad2(x,y,z)
% SCATTERQUAD2 - calculates the volume under a surface defined by scattered points
%
% Usage:
%   v = scatterquad2(x,y,z)
%
% Inputs:
%   X,Y,Z are vectors of equal size specifying the coordinates of the points
%   defining the surface.  Z can also be a scalar or a function handle accepting
%   two inputs.
%
% Outputs:
%   V is the volume under the surface defined by linear interpolation of Z on
%   the Delaunay triangulation of the points (X(i),Y(i)), assuming that z=0
%   outside the convex hull of the points (X(i),Y(i)).
%
% Method:
%   The linear interpolation is a linear combination of basis functions of the
%   form z=t if (x,y) is in triangle T such that
%     (x,y)=r*(u1,v1)+s*(u2,v2)+t*(u3,v3)  where r+s+t=1 (all non-negative) and
%   (u,v) are the vertices of T, or z=0 otherwise.  The integral of z is
%   (1/3)*Area(T) where the area of T is determined by the cross product of two
%   edge vectors.
%
% Examples:
%   load seamount
%   scatterquad2(x,y,z-min(z)) % returns 190.7996
%   inR = (x>=211.1 & x<=211.4 & y>=-48.35 & y<=-48);
%   scatterquad2(x,y,(z-min(z)).*inR) % returns 142.3083
%   scatterquad2(x,y,1) % returns 0.2696
%
% For functions that can be evaluated at arbitrary points, use DBLQUAD or
% QUAD2D.  For regular grids, use TRAPZ twice.

if nargin<3
  error('scatterquad2:nargin','Expect 3 input arguments');
elseif ~isnumeric(x) || ~isnumeric(y)
  error('scatterquad2:xytype','Inputs X and Y must be numeric');
elseif ~isequal(numel(x),numel(y))
  error('scatterquad2:xysize','Inputs X and Y must have same number of elements');
elseif numel(x)<3
  error('scatterquad2:xsize','Inputs X and Y must have at least 3 elements');
elseif ~isnumeric(z)
  if isa(z,'function_handle')
    try
      z=z(x,y);
      if ~isnumeric(z)
        error('scatterquad2:zftype','Input Z failed to return a numeric array');
      end;
    catch ME
      error('scatterquad2:zfeval','Input Z failed to evaluate at (X,Y)');
    end;
  else
    error('scatterquad2:ztype','Input Z must be numeric or a function handle');
  end;
end;

if ~isequal(numel(z),numel(x))
  if numel(z)==1
    z=repmat(z,numel(x),1);
  else
    error('scatterquad2:zsize','Input Z must be scalar or the same size as X and Y');
  end;
end;

DT=DelaunayTri(x,y);
i=DT(:,1);
j=DT(:,2);
k=DT(:,3);
A=abs((x(j)-x(i)).*(y(k)-y(i))-(y(j)-y(i)).*(x(k)-x(i)))/2; % area of triangles
v=sum((z(i)+z(j)+z(k)).*A)/3;

end % main function scatterquad2(...)


function [ p, Fstat, df1, df2 ] = ftest(n,np1,np2,chi1,chi2)
% [ p ] = ftest(n,np1,np2,chi1,chi2)
% function to test whether addition of model parameters to
%     fit data is warranted by level of misfit improvement
%
% Inputs
% n = # of data
% np1, np2 = number of free parameters for each fit.
% chi1 & chi2 = sum of squares of misfits for two models.
%     must be positive values
%     normalization of chis by n not required
%     (normalization divides out in Fstatistic)
%
% Outputs
% p = probability (between 0 - 1) that improvement to fit from
%     addition of parameters is due to chance. I.e.,
%     0 means certainty that extra parameters are warranted
%     1 means improvement undoubtedly attributable to chance
% If desired, will also return F-statistic (Fstat) and
%     degrees of freedom (df1, df2) for f-distribution
%
% Written by James Conder, Southern Illinois University, Oct. 2010
% Citation:
%     Anderson, K.B. & Conder, J.A., Discussion of Multicyclic Hubbert
% Modeling as a Method for Forecasting Future Petroleum Production,
% Energy & Fuels, dx.doi.org/10.1021/ef1012648, 2011
%
% Update June, 2011
%   Check added for df1=1 (giving -Inf). Use MatrixLabs approximation
%   for f when df1=1. Accuracy ok, but some small differences against
%   fcdf
%
% Update May 31, 2012
%   Allow Fstat, df1, & df2 as outputs.
%   Use fcdf from matlab statistics toolbox if available (fast)
%   Some cosmetic clean up
%
% Comments & questions should be directed to conder@siu.edu
%----------------------

%%% check ordering. np2 should be > np1 and chi2 should be < chi1
% i.e., second model should have more parameters and better fit
if np2 == np1
    disp('number of model parameters are the same in both cases!')
    p = 1;
    return
elseif np2 < np1        % np1 should be less than np2. If not, just swap.
    nptemp = np1; np1 = np2; np2 = nptemp;
    chitemp = chi1; chi1 = chi2; chi2 = chitemp;
end

if chi2 >= chi1
    disp('misfit higher for model with more parameters!')
    p = 1;
    return
end

%%% number of degrees of freedom for f-distribution
df1 = np2 - np1;		% number of degrees of freedom
df2 = n - np2 - 1;

%%% F-statistic
Fstat = df2*(chi1 - chi2)/(df1*chi2);

%%% find p by determination of cumulative f-distribution at Fstat
% first check if fcdf from matlab statistics toolbox is present (fast).
% if not, numerically integrate f-distribution.
% cdff is equivalent to result from fcdf in Matlab statistics package.

if exist('fcdf.m','file') == 2       % check for availability of fcdf from statistics toolbox
    p = 1 - fcdf(Fstat,df1,df2);
else
    if df1 ~= 1         % numerically integrate f-distribution
        ifpt = 1000001; % large number of slices for accurate numerical integration
        dx = Fstat/(ifpt-1);
        x = 0:dx:1.2*Fstat;

        fnumgam = gammaln((df1+df2)/2);		% gamma func factors can be very large, use ln
        fdengam = gammaln(df1/2) + gammaln(df2/2);
        fgam = exp(fnumgam - fdengam);

        fnum = fgam*((df1/df2)^(df1/2)).*(x.^(0.5*df1 -1));
        fden = ((1 + df1*x/df2).^(0.5*(df1+df2)));
        f = fnum./fden;	% f distribution for df1, df2
        %fF = f(ifpt);		% f at Fstat

        cdff = cumsum(f)*dx;	% numerical integration of f distribution
        p = 1 - cdff(ifpt);
    else    % when df1=1 use F-dist approximation from MatrixLabs to avoid -Inf
        if Fstat <= 0.5    % Compute using inverse for small F-values
            s = df2;
            t = df1;
            z = 1/Fstat;
        else
            s = df1;
            t = df2;
            z = Fstat;
        end
        j = 2/(9*s);
        k = 2/(9*t);

        % Use approximation formulas
        y = abs((1 - k)*z^(1/3) - 1 + j)/sqrt(k*z^(2/3) + j);
        if t < 4
            y = y*(1 + 0.08*y^4/t^3);
        end

        a1 = 0.196854;
        a2 = 0.115194;
        a3 = 0.000344;
        a4 = 0.019527;
        p = 0.5/(1 + y*(a1 + y*(a2 + y*(a3 + y*a4))))^4;

        % Adjust if inverse was computed
        if Fstat <= 0.5
            p = 1 - p;
        end
     end
end

end


function K = besselk_correlation ( s, t )

%*****************************************************************************80
%
%% BESSELK_CORRELATION evaluates the Bessel K correlation function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real S(*), T(*), pairs of argument values.
%
%    Output, real K(*), the correlation function values
%
  K = ones ( size ( s ) );

  i = find ( s ~= t );
  K(i) = abs ( s(i) - t(i) ) .* besselk ( 1, abs ( s(i) - t(i) ) );

  return
end