%GENREGSIN Generate sinusoidal regression data
%
%     X = GENDATSIN(N,SIGMA)
%
% INPUT
%    N      Number of objects to generate
%    SIGMA  Standard deviation of the noise
%
% OUTPUT
%    X      Regression dataset
%
% DESCRIPTION
% Generate an artificial regression dataset [X,Y] with:
%
%    y = sin(4x) + noise.
%
% where noise is Gaussian distributed with standard deviation sigma.
%
%  X = GENDATSIN(100)
% generates 100 x,y pairs with data and default noise (sigma = 0.1).
%
%  x = (0:0.01:1)';
%  y = genregsin(x,0);
% generates the true function along the x-axis, with zero noise.
%
% SEE ALSO (PRTools Guide)
% GENDATR, GENDATSINC

% Copyright: D.M.J. Tax, D.M.J.Tax@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands
function x = gendatsin(nrx,noise)
if nargin<2
  noise = 0.1;
end

if (length(nrx)>1)
  x = nrx;
  nrx = size(x);
  x = sin(4*x) + noise*randn(nrx);
else
  x = rand(nrx,1);
  y = sin(4*x) + noise*randn(nrx,1);
end
x = gendatr(x,y);

return


function [rhsHx, rhsHy, rhsHz, rhsEx, rhsEy, rhsEz] = MaxwellRHS3D(Hx,Hy,Hz,Ex,Ey,Ez)

% function [rhsHx, rhsHy, rhsHz, rhsEx, rhsEy, rhsEz] = MaxwellRHS3D(Hx,Hy,Hz,Ex,Ey,Ez)
% Purpose  : Evaluate RHS flux in 3D Maxwell equations

Globals3D;

% storage for field differences at faces
dHx = zeros(Nfp*Nfaces,K); dHy = dHx; dHz = dHx;
dEx = zeros(Nfp*Nfaces,K); dEy = dEx; dEz = dEx;

% form field differences at faces
dHx(:)  = Hx(vmapP)-Hx(vmapM);  dEx(:)  = Ex(vmapP)-Ex(vmapM);
dHy(:)  = Hy(vmapP)-Hy(vmapM); 	dEy(:)  = Ey(vmapP)-Ey(vmapM);
dHz(:)  = Hz(vmapP)-Hz(vmapM);  dEz(:)  = Ez(vmapP)-Ez(vmapM);

% make boundary conditions all reflective (Ez+ = -Ez-)
dHx(mapB) = 0;  dEx(mapB) = -2*Ex(vmapB);
dHy(mapB) = 0;  dEy(mapB) = -2*Ey(vmapB);
dHz(mapB) = 0;  dEz(mapB) = -2*Ez(vmapB);

alpha=1; % => full upwinding

ndotdH = nx.*dHx + ny.*dHy + nz.*dHz;
ndotdE = nx.*dEx + ny.*dEy + nz.*dEz;

fluxHx = -ny.*dEz + nz.*dEy + alpha*(dHx - ndotdH.*nx);
fluxHy = -nz.*dEx + nx.*dEz + alpha*(dHy - ndotdH.*ny);
fluxHz = -nx.*dEy + ny.*dEx + alpha*(dHz - ndotdH.*nz);

fluxEx =  ny.*dHz - nz.*dHy + alpha*(dEx - ndotdE.*nx);
fluxEy =  nz.*dHx - nx.*dHz + alpha*(dEy - ndotdE.*ny);
fluxEz =  nx.*dHy - ny.*dHx + alpha*(dEz - ndotdE.*nz);

% evaluate local spatial derivatives
[curlHx,curlHy,curlHz] = Curl3D(Hx,Hy,Hz);
[curlEx,curlEy,curlEz] = Curl3D(Ex,Ey,Ez);

% calculate Maxwell's right hand side
rhsHx = -curlEx + LIFT*(Fscale.*fluxHx/2);
rhsHy = -curlEy + LIFT*(Fscale.*fluxHy/2);
rhsHz = -curlEz + LIFT*(Fscale.*fluxHz/2);

rhsEx =  curlHx + LIFT*(Fscale.*fluxEx/2);
rhsEy =  curlHy + LIFT*(Fscale.*fluxEy/2);
rhsEz =  curlHz + LIFT*(Fscale.*fluxEz/2);
return;


%  OPTIMZE_LOGISTIC -- finds the optimal parameters of a logistic function
%
%  ::
%
%
%    ab=optimize_logistic(x1,p1,x2,p2)
%
%    ab=optimize_logistic(x1,p1,x2,p2,op)
%
%  Args:
%
%     - **x1,x2** [scalars] : points at which to evaluate the logistic
%
%     - **p1,p2** [scalars] : probability values for x1 and x2
%
%     - **op** [{'+'}|'-'] : decides whether b is to be multiplied by 1 or by
%       -1 in the evaluation the logistic function.
%
%  Returns:
%     :
%
%     - **ab** [vector] : optimized parameters of the logistic function
%
%  Note:
%
%       The function has the form f(x,a,b)=a/(a+exp(b*x)) so that f(x1,a,b)=p1
%       and f(x2,a,b)=p2
%
%  Example:
%
%     See also:
%


function D = EuDist2(fea_a,fea_b,bSqrt)
% Euclidean Distance matrix
%   D = EuDist(fea_a,fea_b)
%   fea_a:    nSample_a * nFeature
%   fea_b:    nSample_b * nFeature
%   D:      nSample_a * nSample_a
%       or  nSample_a * nSample_b

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

if (~exist('fea_b','var')) | isempty(fea_b)
    [nSmp, nFea] = size(fea_a);

    aa = sum(fea_a.*fea_a,2);
    ab = fea_a*fea_a';

    aa = full(aa);
    ab = full(ab);

    if bSqrt
        D = sqrt(repmat(aa, 1, nSmp) + repmat(aa', nSmp, 1) - 2*ab);
        D = real(D);
    else
        D = repmat(aa, 1, nSmp) + repmat(aa', nSmp, 1) - 2*ab;
    end

    D = max(D,D');
    D = D - diag(diag(D));
    D = abs(D);
else
    [nSmp_a, nFea] = size(fea_a);
    [nSmp_b, nFea] = size(fea_b);

    aa = sum(fea_a.*fea_a,2);
    bb = sum(fea_b.*fea_b,2);
    ab = fea_a*fea_b';

    aa = full(aa);
    bb = full(bb);
    ab = full(ab);

    if bSqrt
        D = sqrt(repmat(aa, 1, nSmp_b) + repmat(bb', nSmp_a, 1) - 2*ab);
        D = real(D);
    else
        D = repmat(aa, 1, nSmp_b) + repmat(bb', nSmp_a, 1) - 2*ab;
    end

    D = abs(D);
end


function g = p42_g ( n, x )

%*****************************************************************************80
%
%% P42_G evaluates the gradient for problem 42.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 March 2002
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of variables.
%
%    Input, real X(N), the values of the variables.
%
%    Output, real G(N), the gradient of the objective function.
%
  g = zeros ( n, 1 );

  g(1) = 2.0 * ( x(1) - x(2) ) / ( 1.0 + ( x(1) - x(2) )^2 )^2;

  g(2) = 2.0 * ( x(2) - x(1) ) / ( 1.0 + ( x(1) - x(2) )^2 )^2 ...
    - 0.5 * pi * x(3) * cos ( 0.5 * pi * x(2) * x(3) );

  g(3) = - 0.5 * pi * x(2) * cos ( 0.5 * pi * x(2) * x(3) );

  if ( x(2) ~= 0.0 )

    arg = ( x(1) + 2.0 * x(2) + x(3) ) / x(2);
    term = exp ( - arg^2 );

    g(1) = g(1) + 2.0 * term * ( x(1) + 2.0 * x(2) + x(3) ) / x(2)^2;
    g(2) = g(2) - 2.0 * term * ( x(1) + 2.0 * x(2) + x(3) ) ...
      * ( x(1) + x(3) ) / x(2)^3;
    g(3) = g(3) + 2.0 * term * ( x(1) + 2.0 * x(2) + x(3) ) / x(2)^2;

  end

  return
end


function [se_within, stats] = barplot_get_within_ste(dat,varargin)
% :Usage:
% ::
%
%     [se_within, stats] = barplot_get_within_ste(dat)
%
% Compute within-subjects standard errors
%
% :Note: The old version of this used average s.e.'s for contrasts
% of interest, which depend on contrast scaling and are less appropriate
% for use as error bars.
%
% The new version as of 12/10 uses the Loftus & Masson 1994 method and has
% been checked against the data in that paper.
%
% See help below for the L & M data and additional
% code for getting the ANOVA decomposition.
%
% Useful for barplots of conditions when calculating within-subject SEs
%
% :Examples:
% ::
%
%    %% data from Loftus & Masson, Table 2
%
%    mtx = [1 10 13 13 12.00
%    2 6 8 8 7.33
%    3 11 14 14 13.00
%    4 22 23 25 23.33
%    5 16 18 20 18.00
%    6 15 17 17 16.33
%    7 1 1 4 2.00
%    8 12 15 17 14.67
%    9 9 12 12 11.00
%    10 8 9 12 9.67];
%
%    dat = mtx(:, 2:4);  % data from Loftus & Masson, Table 2
%
%    [se_within, stats] = barplot_get_within_ste(dat)
%    fprintf('Within ste: %3.2f, 95%% CI: mean +/- %3.2f\n', se_within, stats.ci);
%
% Extra stuff from ANOVA table
%
% Mean square for condition: Variance of condition means * sample
% size...average squared variance accounted for by condition means
% ::
%
%    [n, k] = size(dat);
%    MS_cond = var( mean(dat) - mean(dat(:)) ) * n;
%
%    MS_subject = var( mean(dat') - mean(dat(:)) ) * k;
%
%    datv = dat(:);
%    MS_total = scale(datv, 1)' * scale(datv, 1);

% notes: 6/3/2018 - tor added wh_omit line to omit all-NaN cases and
% row-wise replacement to make error bars robust to presence of NaNs in
% data.  Previously returned NaN/zero error bars in presence of NaNs

if nargin > 1 && ~isempty(varargin{1})

    covs = varargin{1};

    if size(covs,1) ~= size(dat,1), error('Covs and dat must have same no. of observations.'); end

    disp('Warning: covariates are no longer removed for within-subject SE bars.');

end

% remove cases with all NaN values
% otherwise, these cases could influence calculations and interfere with
% scaling below.
wh_omit = all(isnan(dat), 2); dat(wh_omit, :) = [];

% Replace remaining NaNs with row means
m = nanmean(dat')';
m = repmat(m, 1, size(dat, 2));
wh = isnan(dat);
dat(wh) = m(wh);

% number of subjects and conditions
[n, k] = size(dat);

df_s = n - 1;  % degrees of freedom for subjects
df_c = k - 1;  % degrees of freedom for conditions
df_sxc = df_s * df_c;  % degrees of freedom for subj x condition

% within-subject, within-condition errors
errs = scale(scale(dat, 1)', 1)';

% Sums of squared errors
SS_sxc = errs(:)' * errs(:);

% Mean squared error, accounting for reduced df due to estimating marginal means
MS_sxc  = SS_sxc / df_sxc;

se_within = sqrt(MS_sxc / n);

ci = se_within * tinv(1 - (.05 / 2), df_sxc);

stats.se_within = se_within;
stats.ci = ci;
stats.ci_descrip = '95% confidence interval';
stats.SS_sxc = SS_sxc;
stats.MS_sxc = MS_sxc;

% Extra stuff from ANOVA table
% ---------------------------------------------------------------
% Mean square for condition: Variance of condition means * sample
% size...average squared variance accounted for by condition means
stats.MS_cond = var( mean(dat) - mean(dat(:)) ) * n;

stats.MS_subject = var( mean(dat') - mean(dat(:)) ) * k;

datv = dat(:);
stats.MS_total = scale(datv, 1)' * scale(datv, 1);

return


% ^   Matrix power.
%    Z = X^y is X to the y power if y is a scalar and X is square. If y
%    is an integer greater than one, the power is computed by repeated
%    squaring. For other values of y the calculation involves
%    eigenvalues and eigenvectors.
%
%    Z = x^Y is x to the Y power if Y is a square matrix and x is a scalar.
%    Computed using eigenvalues and eigenvectors.
%
%    Z = X^Y, where both X and Y are matrices, is an error.
%
%    C = MPOWER(A,B) is called for the syntax 'A ^ B' when A or B is an
%    object.
%
%    See also POWER.
%
%    Reference page in Doc Center
%       doc mpower
%
%    Other functions named mpower
%
%       codistributed/mpower    gpuArray/mpower    sym/mpower    ts/mpower
%


%DEMO_AUDITORYFILTERBANK  Construct an auditory filterbank
%
%   In this file we construct a uniform filterbank using a the impulse
%   response of a 4th order gammatone for each channel. The center frequencies
%   are equidistantly spaced on an ERB-scale, and the width of the filter are
%   choosen to match the auditory filter bandwidth as determined by Moore.
%
%   Each channel is subsampled by a factor of 8 (a=8), and to generate a
%   nice plot, 4 channels per Erb has been used.
%
%   The filterbank covers only the positive frequencies, so we must use
%   |filterbankrealdual| and |filterbankrealbounds|.
%
%   .. figure::
%
%      Classic spectrogram
%
%      A classic spectrogram of the spoken sentense. The dynamic range has
%      been set to 50 dB, to highlight the most important features.
%
%   .. figure::
%
%      Auditory filterbank representation
%
%      Auditory filterbank representation of the spoken sentense using
%      gammatone filters on an Erb scale.  The dynamic range has been set to
%      50 dB, to highlight the most important features.
%
%   See also: freqtoaud, audfiltbw, gammatonefir, ufilterbank, filterbankrealdual
%
%   References: glasberg1990daf

% Use part of the 'cocktailparty' spoken sentense.
f=cocktailparty;
f=f(20001:80000,:);
fs=44100;
a=8;
channels_per_erb=2;
filterlength=5000;
dynrange_for_plotting=50;

% Determine minimal transform length
Ls=length(f);
L=ceil(filterlength/a)*a;

% Number of channels, slightly less than 1 ERB(Cambridge) per channel.
M=ceil(freqtoerb(fs/2)*channels_per_erb);

% Compute center frequencies.
fc=erbspace(0,fs/2,M);

%% --------------- display classic spectrogram -------------------
figure(1);
sgram(f,fs,dynrange_for_plotting);

%% ---------------  Gammatone filters ----------------------------

if 1

g_gam=gammatonefir(fc,fs,filterlength,'peakphase');

% In production code, it is not necessary to call 'filterbankrealbounds',
% this is just for veryfying the setup.
disp('Frame bound ratio for gammatone filterbank, should be close to 1 if the filters are choosen correctly.');
filterbankrealbounds(g_gam,a,L)

% Create reconstruction filters
gd_gam=filterbankrealdual(g_gam,a,L);

% Analysis transform
coef_gam=ufilterbank(f,g_gam,a);

% Synthesis transform
r_gam=2*real(ifilterbank(coef_gam,gd_gam,a,Ls));

disp('Relative error in reconstruction, should be close to zero.');
norm(f-r_gam)/norm(f)

figure(2);
plotfilterbank(coef_gam,a,fc,fs,dynrange_for_plotting,'audtick');

F  = frame('ufilterbankreal',g_gam,a,M);
c2 = frana(F,f);
Ls=length(f);

[r_iter,relres,iter] = frsyniter(F,c2,Ls);
disp('Relative error in interative reconstruction, should be close to zero.');
norm(f-r_iter)/norm(f)

end;


%%  Introduction to *wavelet_layer_2d*
% *wavelet_layer_2d* is computing the wavelet transform coefficient from
% the coefficient of the previous layer. It should be applied iteratively
% to an input signal.
%
%% Usage
% [A, V] = *wavelet_layer_2d*(U, filters, options), documentation is given in
% <matlab:doc('wavelet_layer_2d') wavelet_layer_2d>
%
%% Description
% It is possible to create some wavelet filters with wavelet_factory_2d for
% instance. The filters size have to be adapted to the size of the input
% signal $x$.
clear; close all;

x = mandrill;

% Create $ U[\empty]x $
U{1}.signal{1} = x;
U{1}.meta.j = zeros(0,1);
U{1}.meta.q = zeros(0,1);
U{1}.meta.resolution=0;
filters = morlet_filter_bank_2d(size(x));

% A corresponds to the output scattering coefficients, and V to the wavelet
% coefficients.
[A, V] = wavelet_layer_2d(U{1}, filters);

colormap gray
subplot(121)
imagesc(real(V.signal{1}))
axis off
title('Real part of the first wavelet transform coefficient');
subplot(122)
imagesc(imag(V.signal{1}))
axis off
title('Imaginary part of the first wavelet transform coefficient');

%% Options
% The options are the same as in *wavelet_2d*.


function d = p08_fd ( p )

%*****************************************************************************80
%
%% P08_FD is a signed distance function for problem 08.
%
%  Licensing:
%
%    (C) 2004 Per-Olof Persson.
%    See COPYRIGHT.TXT for details.
%
%  Modified:
%
%    06 February 2006
%
%  Parameters:
%
%    Input, real P, one or more points.
%
%    Output, real D, the signed distance of each point to the boundary of the region.
%
  g1 = dcircle ( p, 0, 0, 1 );
  g2 = drectangle ( protate ( p, pi/12 ), -1, 1, 0, 1 );
  g3 = drectangle ( protate ( p, -pi/12 ), -1, 1, -1, 0 );
  g4 = drectangle ( protate ( pshift ( p, -0.9, 0 ), -pi/4 ), 0, 0.2, 0, 0.2 );
  g5 = dcircle ( p, 0.6, 0, 0.1 );

  d = ddiff ( ddiff ( ddiff ( ddiff ( g1, g2 ), g3 ), g4 ), g5 );

  return
end


function param = copulaparam(type,tau)
%COPULAPARAM Copula parameter, given Kendall's rank correlation.
%   RHO = COPULAPARAM('Gaussian',TAU) returns the linear correlation
%   parameter RHO corresponding to a Gaussian copula having Kendall's rank
%   correlation TAU.  If TAU is a scalar correlation coefficient, RHO is a
%   scalar correlation coefficient corresponding to a bivariate copula.  If
%   TAU is a P-by-P correlation matrix, RHO is a P-by-P correlation matrix
%   corresponding to a P-variate copula.
%
%   RHO = COPULAPARAM('t',TAU) returns the linear correlation parameter RHO
%   corresponding to a t copula having Kendall's rank correlation TAU.  If
%   TAU is a scalar correlation coefficient, RHO is a scalar correlation
%   coefficient corresponding to a bivariate copula.  If TAU is a P-by-P
%   correlation matrix, RHO is a P-by-P correlation matrix corresponding to
%   a P-variate copula.
%
%   ALPHA = COPULAPARAM(TYPE,TAU) returns the copula parameter ALPHA
%   corresponding to a bivariate Archimedean copula having Kendall's rank
%   correlation TAU.  TYPE is one of 'Clayton', 'Frank', or 'Gumbel'.
%
%   Example:
%      % Determine the linear correlation coefficient corresponding to a
%      % bivariate Gaussian copula having a rank correlation of -0.5
%      tau = -0.5
%      rho = copulaparam('gaussian',tau)
%
%      % Generate dependent beta random values using that copula
%      u = copularnd('gaussian',rho,100)
%      b = betainv(u,2,2)
%
%      % Verify that those pairs have a sample rank correlation approximately
%      % equal to tau
%      tau_sample = kendall(b)

%   Written by Peter Perkins, The MathWorks, Inc.
%   Revision: 1.0  Date: 2003/09/05
%   This function is not supported by The MathWorks, Inc.
%
%   Requires MATLAB R13.

if nargin < 2
    error('Requires two input arguments.');
end

switch lower(type)
case {'gaussian' 't'}
    if ((numel(tau) == 1) && (tau < -1 | 1 < tau)) || ((numel(tau) ~= 1) && ~iscor(tau))
        error('TAU must be a correlation coefficient between -1 and 1, or a positive semidefinite correlation matrix.');
    end
    param = sin(tau.*pi./2);

case {'clayton' 'frank' 'gumbel'}
    if (numel(tau) ~= 1) || (tau < -1 | 1 < tau)
        error('TAU must be a correlation coefficient between -1 and 1.');
    end
    switch lower(type)
    case 'clayton'
        if tau < 0
            error('TAU must be nonnegative for the Clayton copula.');
        end
        param = 2*tau ./ (1-tau);
    case 'frank'
        if tau == 0
            param = 0;
        elseif abs(tau) < 1
            % There's no closed form for alpha in terms of tau, so alpha has to be
            % determined numerically.
            warn = warning('off','MATLAB:fzero:UndeterminedSyntax');
            param = fzero(@frankRootFun,sign(tau),[],tau);
            warning(warn);
        else
            param = sign(tau).*Inf;
        end
    case 'gumbel'
        if tau < 0
            error('TAU must be nonnegative for the Gumbel copula.');
        end
        param = 1 ./ (1-tau);
    end

otherwise
    error('Unrecognized copula type: ''%s''',type);
end

function err = frankRootFun(alpha,targetTau)
if abs(alpha) < realmin
    tau = 0;
else
    tau = 1 + 4 .* (debye1(alpha)-1) ./ alpha;
end
err = tau - targetTau;


function asset_path_test ( )

%*****************************************************************************80
%
%% ASSET_PATH_TEST tests ASSET_PATH.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ASSET_PATH_TEST:\n' );
  fprintf ( 1, '  Demonstrate the simulation of an asset price path.\n' );

  s0 = 2.0;
  mu = 0.1;
  sigma = 0.3;
  n = 100;
  t0 = 0.0;
  t1 = 1.0;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The asset price at time 0,     S0    = %f\n', s0 );
  fprintf ( 1, '  The asset expected growth rate MU    = %f\n', mu );
  fprintf ( 1, '  The asset volatility           SIGMA = %f\n', sigma );
  fprintf ( 1, '  The expiry date                T1    = %f\n', t1 );
  fprintf ( 1, '  The number of time steps       N     = %d\n', n );

  s = asset_path ( s0, mu, sigma, t1, n );
%
%  Plot.
%
  figure ( 1 )
  t = ( linspace ( t0, t1, n + 1 ) )';
  plot ( t, s )
  grid on
  xlabel ( '<-- Time -->' )
  ylabel ( '<-- Value --> ' )
  title ( 'Simulated asset path' )
%
%  Print a little.
%
  r8vec_print_part ( n + 1, s, 10, '  Partial results:' );
%
%  Write to a file.
%
  output_filename = 'asset_path.txt';

  r8vec_write ( output_filename, n + 1, s );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Full results written to "%s".\n', output_filename );

  return
end


function x = r8vec_chebyspace ( n, a, b )

%*****************************************************************************80
%
%% R8VEC_CHEBYSPACE creates a vector of Chebyshev spaced values in [A,B].
%
%  Discussion:
%
%    An R8VEC is a vector of R8's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 June 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vector.
%
%    Input, real A, B, the first and last entries.
%
%    Output, real X(N,1), a vector of Chebyshev spaced data.
%
  x = zeros ( n, 1 );

  if ( n == 1 )

    x(1) = ( a + b ) / 2.0;

  else

    for i = 1 : n

      theta = ( n - i ) * pi / ( n - 1 );

      c = cos ( theta );

      if ( mod ( n, 2 ) == 1 )
        if ( 2 * i - 1 == n )
          c = 0.0;
        end
      end

      x(i) = ( ( 1.0 - c ) * a  ...
             + ( 1.0 + c ) * b ) ...
             /   2.0;

    end

  end

  return
end


function [ mO ] = ApplyLocalLinearKernel( mI, filterRadius, regFctr )
% ----------------------------------------------------------------------------------------------- %
%[ mOutputImage ] = ApplyLocalLinearFilter( mInputImage, filterRadius, regFctr )
% Applying Linear Edge Preserving Smoothing Filter based on Local Linear (Affine) model.
% Input:
%   - mI            -   Input Image.
%                       Structure: Image Matrix (Single Channel).
%                       Type: 'Single' / 'Double'.
%                       Range: [0, 1].
%   - filterRadius  -   Filter Radius.
%                       The filter radius.
%                       Structure: Scalar.
%                       Type: 'Single' / 'Double'.
%                       Range: {1, 2, ...}.
%   - regFctr       -   Regularization Factor.
%                       Regularize the local covariance (Variance).
%                       Structure: Scalar.
%                       Type: 'Single' / 'Double'.
%                       Range: (0, inf).
% Output:
%   - mO            -   Output Image.
%                       Structure: Image Matrix (Single Channel).
%                       Type: 'Single' / 'Double'.
%                       Range: [0, 1].
% References:
%   1.  "Guided Image Filtering".
% Remarks:
%   1.  This is basically estimating the Linear Function (Affine)
%       parameters for the Local Window. Namely, the ouput is a Linear
%       combination of the input Window and a DC Factor. The final step is
%       aggregation (Uniform) off all estimations of the parameters.
%   2.  Prefixes:
%       -   'v' - Vector.
%       -   'm' - Matrix.
%       -   't' - Tensor (Multi Dimension Matrix)
%       -   's' - Struct.
%       -   'c' - Cell Array.
%   3.  The calculation of the Local Variance might be negative due to
%       numerical diffuculties. If artifacts appear, this might be the
%       casue. Usually using matrices of type 'double' solves it.
%   4.  This implemnetation is `ApplyGuidedFilter` where the Guiding Image
%       is the Input Image.
%   5.  Speed otimizzation can be achived by wiser use of 'mNumEffPixels'.
%       Instead of dividing by it calculate its reciprocal once. Moreover,
%       it can be used only once in the aggregation process.
% TODO:
%   1.  Create Multi Variable Linear Model.
%   2.  Some speed potimization could be made (Taking advantage of 'mNumEffPixels').
% Release Notes:
%   -   1.0.000     05/01/2016  Royi Avital
%       *   First release version
% ----------------------------------------------------------------------------------------------- %

FALSE   = 0;
TRUE    = 1;

OFF = 0;
ON  = 1;

BORDER_TYPE_CONSTANT    = 1;
BORDER_TYPE_CIRCULAR    = 2;
BORDER_TYPE_REPLICATE   = 3;
BORDER_TYPE_SYMMETRIC   = 4;

numRows = size(mI, 1);
numCols = size(mI, 2);

borderType      = BORDER_TYPE_CONSTANT;
borderValue     = 0;
normalizeFlag   = OFF;

mNumEffPixels = ApplyBoxFilter(ones([numRows, numCols]), filterRadius, borderType, borderValue, normalizeFlag);

mLocalMean          = ApplyBoxFilter(mI, filterRadius, borderType, borderValue, normalizeFlag) ./ mNumEffPixels;
mLocalMeanSquare    = ApplyBoxFilter((mI .* mI), filterRadius, borderType, borderValue, normalizeFlag) ./ mNumEffPixels;
mLocalCovariance    = mLocalMeanSquare - (mLocalMean .* mLocalMean);

mO = zeros([numRows, numCols]);

for jj = 1:numCols
    for ii = 1:numRows
        % The coordinate i, j are set.

        sumWeights = 0;

        % Running on the Neighborhood of the pixel
        for ll = -filterRadius:filterRadius
            for kk = -filterRadius:filterRadius

                jRowIdx = ii + kk;
                jColIdx = jj + ll;

                if((jColIdx >= 1) && (jColIdx <= numCols) && (jRowIdx >= 1) && (jRowIdx <= numRows))
                    % Valid Pixel
                    numPixels       = 0;
                    jPixelWeight    = 0;

                    % Running on Wk Window
                    for nn = -filterRadius:filterRadius
                        for mm = -filterRadius:filterRadius

                            % K Index
                            kRowIdx = jRowIdx + mm;
                            kColIdx = jColIdx + nn;

                            if((kColIdx >= 1) && (kColIdx <= numCols) && (kRowIdx >= 1) && (kRowIdx <= numRows) && (abs(kColIdx - jj) <= filterRadius) && (abs(kRowIdx - ii) <= filterRadius))

                                numPixels = numPixels + 1;

                                % Weight
                                jPixelWeight = jPixelWeight + 1 + (((mI(ii, jj) - mLocalMean(kRowIdx, kColIdx)) * (mI(jRowIdx, jColIdx) - mLocalMean(kRowIdx, kColIdx))) / (mLocalCovariance(kRowIdx, kColIdx) + regFctr));
                            end
                        end
                    end

                    % jPixelWeight = jPixelWeight / (numPixels * numPixels);
                    mO(ii, jj) = mO(ii, jj) + (jPixelWeight * mI(jRowIdx, jColIdx));

                    sumWeights = sumWeights + jPixelWeight;

                end
            end
        end

        mO(ii, jj) = mO(ii, jj) / sumWeights;

    end
end

end


function scMove(Pos1,length,LinCol)
%scMove : Move along the transmission line on smith chart to transform impedance
%
%
%  SYNOPSIS:
%     Transform a point to another one as one moves along a lossless transmission line on
%     smith chart.
%
%     See also scDraw, scInv, scConCirc, scMatchCirc
%
%  SYNTAX:
%     scMove(Pos1, length, Direction, LinCol)
%
%  INPUT ARGUMENTS:
%     Pos1      : Starting point coordinates [r x] normalized
%     length    : Length of the transmission line normalized to wavelength
%     LinCol     : Color of the end-ray emanating from origin
%     Direction : Towards(+1) or away from the generator(-1) %%%%TO BE INCORPORATED YET.
%
%  OUTPUT ARGUMENT:
%     none
%
%  EXAMPLE:
%         The Command sequence
%         scDraw;
%         scMove([2 3],.3)
%         will draw a blank smith chart and will plot the point
%         corresponding to impedance (2+j*3)*Z_L and its transformed value
%         after moving 0.3*lambda towards the generator along the
%         transmission line
%
%     Mohammad Ashfaq - (31-05-2000)
%     Mohammad Ashfaq - (13-04-2006) Modified (example included)
%

if nargin == 2
    LinCol = 'm';
end

 r1       = Pos1(1);
 x1       = Pos1(2);
 [u1, v1] = scPOI(r1,x1);

 % MARK STARTING POINT
 scRay(Pos1);

 r        = sqrt(u1^2+v1^2);
 Theta1   = atan2(v1,u1);
 length1  = (1-Theta1/pi)/4;
 length2  = length1 + length;
 Theta2   = (1-4*length2)*pi;
 u2       = r * cos(Theta2);
 v2       = r * sin(Theta2);

 % MARK END POINT
 plot(u2, v2,'r*')

 Theta2d  = Theta2*180/pi;
 if (Theta2d<-180)
    Theta2d  = 360 + Theta2d;
 elseif (Theta2d>180)
    Theta2d  = 360 - Theta2d;
 end
 length2 = length2-floor(length2/.5)*.5;

 plot([0 u2],[0 v2],LinCol);
 plot([1.25*cos(Theta2) u2],[1.25*sin(Theta2) v2],'k');
 string = ['\theta=', num2str(Theta2d,'%3.2f'), '  l/\lambda=', num2str(length2, '%0.3f')];

 if abs(Theta2d)>90
    Theta2d  = Theta2d+180;
    h = text(1.25*cos(Theta2),1.25*sin(Theta2), string);
    set(h,'rotation', Theta2d, 'Fontsize', 8, 'HorizontalAlignment','right');
 else
    h = text(1.25*cos(Theta2),1.25*sin(Theta2), string);
    set(h,'rotation', Theta2d, 'Fontsize', 8);
 end


function C= train_QDA(xTr, yTr, varargin)
%TRAIN_QDA - Quadratic Discriminant Analysis
%
%Synopsis:
%   C = train_QDA(XTR, YTR)
%   C = train_QDA(XTR, YTR, PRIOR)
%
%Arguments:
% XTR: DOUBLE [NxM] - Data matrix, with N feature dimensions, and M
%                     training points/examples.
% YTR: INT [CxM] - Class membership labels of points in X_TR. C by M matrix
%                  of training labels, with C representing the number of
%                  classes and M the number of training examples/points.
%                  Y_TR(i,j)==1 if the point j belongs to class i.
% PRIOR: DOUBLE - (default ones(nClasses, 1)/nClasses): Empirical class
%                 priors
%
%Returns:
%   C: STRUCT - Trained classifier structure, with the hyperplane given by
%               fields C.w, C.b and C.sq
%
%See also:
%   APPLY_QDA

if size(yTr,1)==1,
  nClasses= 2;
  clInd{1}= find(yTr==-1);
  clInd{2}= find(yTr==1);
  N= [length(clInd{1}) length(clInd{2})];
else
  nClasses= size(yTr,1);
  clInd= cell(nClasses,1);
  N= zeros(nClasses, 1);
  for ci= 1:nClasses,
    clInd{ci}= find(yTr(ci,:));
    N(ci)= length(clInd{ci});
  end
end

if nargin==2
  priorP= ones(nClasses,1)/nClasses;
else
  priorP= varargin{1};
end
if isequal(priorP, '*')
  priorP = N/sum(N);
end

d= size(xTr,1);
C.w= zeros(d, nClasses);
C.b= zeros(1, nClasses);
C.sq= zeros(d, d, nClasses);
for ci= 1:nClasses,
  cli= clInd{ci};
  C.w(:,ci)= mean(xTr(:,cli), 2);
  yc= xTr(:,cli) - C.w(:,ci)*ones(1,N(ci));
  Sq= yc*yc';
  C.sq(:,:,ci)= Sq / (N(ci)-1);
end
C.b= zeros(1, nClasses);
for ci= 1:nClasses,
  S= C.sq(:,:,ci);
  S= pinv(S);
  C.sq(:,:,ci)= -0.5*S;
  C.b(ci)=  -0.5*C.w(:,ci)' * S*C.w(:,ci) + ...
            0.5*log(max([det(S),realmin])) + log(priorP(ci));
  C.w(:,ci)= S*C.w(:,ci);
end
C.b=C.b';

if nClasses==2,
  sq(:,:)= C.sq(:,:,2) - C.sq(:,:,1);
  C.sq= sq;
  C.w= C.w(:,2)-C.w(:,1);
  C.b= C.b(2) - C.b(1);
end


function pde = Stokesdata0

%
nu = 1;
pde = struct('f',@f,'g',@g,'exactp', @exactp, ...
             'exactu', @exactu,'g_D', @g_D, 'nu', nu);

    function z = f(p)
        x = p(:,1); y = p(:,2);
        z(:,1) = -4*pi^2*(2*cos(2*pi*x)-1).*sin(2*pi*y)+x.^2;
        z(:,2) = 4*pi^2*(2*cos(2*pi*y)-1).*sin(2*pi*x);
    end

    function z = g(p)
        z = zeros(size(p,1),1);
    end

    function z = exactu(p)
        x = p(:,1); y = p(:,2);
        z(:,1) = (1-cos(2*pi*x)).*sin(2*pi*y);
        z(:,2) = -(1-cos(2*pi*y)).*sin(2*pi*x);
    end

    function z = exactp(p)
        x = p(:,1); % y = p(:,2);
        z = 1/3*x.^3;
    end

    function z = g_D(p) % Dirichlet boundary condition
        z = exactu(p);
    end
end


function b = isPointOnLine(point, line, varargin)
%ISPOINTONLINE Test if a point belongs to a line.
%
%   B = isPointOnLine(POINT, LINE)
%   with POINT being [xp yp], and LINE being [x0 y0 dx dy].
%   Returns 1 if point lies on the line, 0 otherwise.
%
%   If POINT is an N-by-2 array of points, B is a N-by-1 array of booleans.
%
%   If LINE is a N-by-4 array of line, B is a 1-by-N array of booleans.
%
%   B = isPointOnLine(POINT, LINE, TOL)
%   Specifies the tolerance used for testing location on 3D line. Default value is 1e-14.
%
%   See also
%   lines2d, points2d, isPointOnEdge, isPointOnRay, isLeftOriented
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2003-10-31
% Copyright 2003-2022 INRA - TPV URPOI - BIA IMASTE

% extract computation tolerance
tol = 1e-14;
if ~isempty(varargin)
    tol = varargin{1};
end

% test if lines are colinear, using third coordinate of 3D cross-product
% same test as:
% b = abs((xp-x0).*dy-(yp-y0).*dx)./hypot(dx, dy).^2 < tol;
b = bsxfun(...
    @rdivide, abs(...
    bsxfun(@times, bsxfun(@minus, point(:,1), line(:,1)'), line(:,4)') - ...
    bsxfun(@times, bsxfun(@minus, point(:,2), line(:,2)'), line(:,3)')), ...
    (line(:,3).^2 + line(:,4).^2)') < tol;


function prob_test1486 ( )

%*****************************************************************************80
%
%% TEST1486 tests UNIFORM_01_MEAN, *_SAMPLE, *_VARIANCE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  nsample = 1000;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST1486\n' );
  fprintf ( 1, '  For the Uniform 01 PDF:\n' );
  fprintf ( 1, '  UNIFORM_01_MEAN computes mean;\n' );
  fprintf ( 1, '  UNIFORM_01_SAMPLE samples;\n' );
  fprintf ( 1, '  UNIFORM_01_VARIANCE computes variance.\n' );

  mean = uniform_01_mean ( );
  variance = uniform_01_variance ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PDF mean =            %14f\n', mean );
  fprintf ( 1, '  PDF variance =        %14f\n', variance );

  for i = 1 : nsample
    [ x(i), seed ] = uniform_01_sample ( seed );
  end

  mean = r8vec_mean ( nsample, x );
  variance = r8vec_variance ( nsample, x );
  xmax = max ( x(1:nsample) );
  xmin = min ( x(1:nsample) );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Sample size =     %6d\n', nsample );
  fprintf ( 1, '  Sample mean =     %14f\n', mean );
  fprintf ( 1, '  Sample variance = %14f\n', variance );
  fprintf ( 1, '  Sample maximum =  %14f\n', xmax );
  fprintf ( 1, '  Sample minimum =  %14f\n', xmin );

  return
end


function [gradISE,gradJhr,gradJrr]=GaussMixISEMeanGrads(w1,mu1,P1,w2,mu2,P2,PDFVals12,PDFVals22)
%%GAUSSMIXISEMEANGRADS Compute the gradient of the non-normalized
%               integrated squared error (ISE) between two Gaussian mixture
%               PDFs with respect to the mean vectors of the individual
%               components of the second Gaussian mixture. This gradient
%               can arise when optimizing over the ISE with respect to the
%               means.
%
%INPUTS: w1 The N1X1 or 1XN1 vector of weights for the first Gaussian
%           mixture. All w1>0 and sum(w1)=1.
%       mu1 The xDimXN1 set of mean vectors for the first Gaussian mixture
%           distribution.
%        P1 The xDimXxDimXN1 set of positive definite covariance matrices
%           for the first Gaussian mixture distirbution.
% w2, mu2, P2, The length N2, xDimXN2, and xDimXxDimXN2 set of weights,
%           mean vectors and positive-definite covariance matrices for the
%           second Gaussian mixture distribution.
% PDFVals12 A matrix such that the value in element (i,j) is
%           N(mu1(:,i);mu2(:,j),P1(:,:,i)+P2(:,:,j)), where N indicates the
%           multivariate Gaussian PDF evaluated at the first argument with
%           the second and third arguments being the mean and covarince
%           matrix. This parameter is returned by computeGaussMixISE.
% PDFVals22 A matrix such that the value in element (i,j) is
%           N(mu2(:,i);mu2(:,j),P2(:,:,i)+P2(:,:,j)). This parameter is
%           returned by computeGaussMixISE.
%
%OUTPUTS: gradISE The xDimXn2 set of derivatives of the ISE with respect to
%                 the elements of q (the square roots of w2).
% gradJhr, gradJrr In Chapter 3 of [1], the ISE is expressed in terms of
%                 Jhr and Jrr terms. These are the xDimXn2 gradients of
%                 those terms.
%
%Formule for gradJhr and gradJrr are Equation 3.34 in Section 3.3.3.2 of
%[1]. They relate to the ISE via Equation 3.20. See the function
%computeGaussMixISE to compute the ISE.
%
%EXAMPLE 1:
%In this example with a scalar random variable, we verify that the gradient
%obtained from this function is consistent with numerical differentiation.
% w1=[0.03,0.18,0.12,0.19,0.02,0.16,0.06,0.1,0.08,0.06];
% n1=length(w1);
% mu1=[1.45,2.20,0.67,0.48,1.49,0.91,1.01,1.42,2.77,0.89];
% P1=[0.0487,0.0305,0.1171,0.0174,0.0295,0.0102, 0.0323, 0.0380, 0.0115, 0.0679];
% P1=reshape(P1,[1,1,n1]);
%
% %The second PDF is the first with the five least-weight components deleted.
% w2=[0.18,0.12,0.19,0.16,0.1,0.08];
% w2=w2/sum(w2);
% n2=length(w2);
% mu2=[2.20,0.67,0.48,0.91,1.42,2.77];
% P2=[0.0305,0.1171,0.0174,0.0102,0.0380,0.0115];
% P2=reshape(P2,[1,1,n2]);
%
% [ISEVal,PDFVals12,PDFVals22]=computeGaussMixISE(w1,mu1,P1,w2,mu2,P2);
%
% epsVal=1e-8;
% gradISENumDiff=zeros(1,n2);
% for j=1:n2
%     muCur=mu2;
%     muCur(1,j)=muCur(1,j)+epsVal;
% 	ISEValCur=computeGaussMixISE(w1,mu1,P1,w2,muCur,P2);
%     gradISENumDiff(1,j)=(ISEValCur-ISEVal)/epsVal;
% end
% gradISE=GaussMixISEMeanGrads(w1,mu1,P1,w2,mu2,P2,PDFVals12,PDFVals22);
% RelErr=max(abs((gradISENumDiff-gradISE)./gradISENumDiff))
%The relative error will be about 5.4042e-6, which indicates good numeric
%agreement.
%
%EXAMPLE 2:
%In this example with a bivariate distribution, we verify that the gradient
%obtained from this function is consistent with numerical differentiation.
% w1=[0.25;0.5;0.25];
% mu1=zeros(2,2);
% mu1(:,1)=[1;-1];
% mu1(:,2)=[-1;1];
% mu1(:,3)=[0;0];
% P1=zeros(2,2,2);
% P1(:,:,1)=[4/9,  14/45;
%            14/45,4/9];
% P1(:,:,2)=[4/9, 0;
%            0, 4/9];
% P1(:,:,3)=[2/9, -1/9;
%           -1/9, 3/9];
%
% %The second distribution just throws out the first component.
% w2=w1(2:3);
% w2=w2/sum(w2);
% mu2=mu1(:,2:3);
% P2=P1(:,:,2:3);
%
% n2=length(w2);
% [ISEVal,PDFVals12,PDFVals22]=computeGaussMixISE(w1,mu1,P1,w2,mu2,P2);
%
% numDim=size(mu1,1);
% epsVal=1e-8;
% gradISENumDiff=zeros(numDim,n2);
% for curDim=1:numDim
%     for j=1:n2
%         muCur=mu2;
%         muCur(curDim,j)=muCur(curDim,j)+epsVal;
%         ISEValCur=computeGaussMixISE(w1,mu1,P1,w2,muCur,P2);
%         gradISENumDiff(curDim,j)=(ISEValCur-ISEVal)/epsVal;
%     end
% end
% gradISE=GaussMixISEMeanGrads(w1,mu1,P1,w2,mu2,P2,PDFVals12,PDFVals22);
% RelErr=max(max(abs((gradISENumDiff-gradISE)./gradISENumDiff)))
%The relative error will be about 1.2876e-7, which indicates good numeric
%agreement.
%
%REFERENCES:
%[1] J. L. Williams, "Gaussian mixture reduction for tracking multiple
%    maneuvering targets in clutter," Master's thesis, Air Force Institute
%    of Technology, Mar. 2003. [Online].
%    Available: http://www.dtic.mil/srch/doc?collection=t3&id=ADA415317
%
%May 2019 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

Nh=length(w1);
Nr=length(w2);
xDim=size(mu1,1);

%The formulae for the gradient of Jhr and Jrr are given in Equation 3.34 of
%Section 3.3.3.2 of [1].
gradJhr=zeros(xDim,Nr);
gradJrr=zeros(xDim,Nr);

for j=1:Nr
    for i=1:Nh
        gradJhr(:,j)=gradJhr(:,j)+(P1(:,:,i)+P2(:,:,j))\(mu2(:,j)-mu1(:,i))*PDFVals12(i,j)*w1(i);
    end
    gradJhr(:,j)=-w2(j)*gradJhr(:,j);
end

for j=1:Nr
    for i=1:Nr
        gradJrr(:,j)=gradJrr(:,j)+(P2(:,:,i)+P2(:,:,j))\(mu2(:,j)-mu2(:,i))*PDFVals22(i,j)*w2(i);
    end
    gradJrr(:,j)=-2*w2(j)*gradJrr(:,j);
end

gradISE=gradJrr-2*gradJhr;
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.


% VAR - variance of memory mapped underlying array
%
% Author: Arnaud Delorme, SCCN, INC, UCSD, Nov. 2008

% Copyright (C) 2008 Arnaud Delorme, SCCN, INC, UCSD
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function sumval = var(obj,flag,dim)

    if nargin < 2
        flag = 0;
    end
    if nargin < 3
        dim = 1;
    end

    meanvalsq = mean(obj,dim).^2;

    sumval = 0;
    s1  = size(obj);
    ss.type = '()';
    ss.subs(1:length(s1)) = { ':' };
    for index = 1:s1(dim)
        ss.subs{dim} = index;
        tmpdata = subsref(obj, ss);
        sumval = sumval + tmpdata.*tmpdata - meanvalsq;
    end
    if isempty(flag) || flag == 0
         sumval = sumval/(size(obj,dim)-1);
    else sumval = sumval/size(obj,dim);
    end


function [n,V,p] = affine_fit(X,W)
    %Computes the plane that fits best (lest square of the normal distance
    %to the plane) a set of sample points.
    %INPUTS:
    %
    %X: a N by 3 matrix where each line is a sample point
    %
    %OUTPUTS:
    %
    %n : a unit (column) vector normal to the plane
    %V : a 3 by 2 matrix. The columns of V form an orthonormal basis of the
    %plane
    %p : a point belonging to the plane
    %
    %NB: this code actually works in any dimension (2,3,4,...)
    %Author: Adrien Leygue
    %Date: August 30 2013

    if nargin<2
      W = 1/size(X,1)*ones(size(X,1),1);
    end
    W = W(:)./sum(W);

    %the mean of the samples belongs to the plane
    p = sum(bsxfun(@times,W,X));

    %The samples are reduced:
    R = bsxfun(@times,bsxfun(@minus,X,p),W);
    %Computation of the principal directions if the samples cloud
    [V,D] = eig(R'*R);
    %Extract the output from the eigenvectors
    n = V(:,1);
    V = V(:,2:end);
end

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


function B = barymat(y, x, w, s, r, doFlip)
%BARYMAT  Barycentric Interpolation Matrix.
%   BARYMAT(Y, X, W), where Y is a column vector of length M and X and W are
%   column and row vectors of length N, respectively, returns the M*N matrix
%   which interpolates data from the grid X to the grid Y using the 2nd-kind
%   barycentric interpolation formula with barycentric weights W. If W is not
%   supplied it is assumed to be the weights for polynomial interpolation at a
%   2nd-kind Chebyshev grid: W(j) = (-1)^j, W([1, N]) = 0.5*W([1, N]).
%
%   BARYMAT(Y, X, W, S, R) is the same, where S = acos(Y) and R = acos(X). The
%   purpose of this is that Y(j) - X(k) can be more accurately computed in this
%   'theta space'. This is sometimes referred to as the 'trig trick' in spectral
%   collocation. BARYMAT(Y, X, W, S, R, 1) also performs the 'flipping trick',
%   which takes advantage of the fact that the smaller entries in R and S can be
%   computed more accurately. Note that X and Y should be symmetric about zero
%   for this work, and it is assumed that S and R are sorted in descending
%   order.

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

if ( isempty(y) || isempty(x) )
    % Nothing to do here!
    B = [];
    return
end

if ( size(x, 2) > 1 || size(y, 2) > 1 )
    error('CHEBFUN:barymat:dims', 'Inputs should be column vectors.');
end

% Obtain lengths of inputs:
N = length(x);
M = length(y);

% Nothing to do here!
if ( M == N && all(x == y) )
    B = eye(N);
    return
end

% Default to the Chebyshev barycentric weights:
if ( nargin < 3 || isempty(w) )
    w = ones(1, N);
    w(2:2:end) = -1;
    w([1, N]) = 0.5*w([1, N]);
else
    % Ensure w is a row vector:
    w = reshape(w, 1, N);
end

% Repmat(Y-X'):
if ( nargin < 5 )
    B = bsxfun(@minus, y, x.');
else
    % Use the 'trig trick' that y-x = cos(s)-cos(r) = 2*sin((s+r)/2)*sin((r-s)/2).
    B = 2*bsxfun(@(r, s) sin((s+r)/2).* sin((r-s)/2), r.', s);
end

% Construct the matrix:
if ( M >= 500 && N >= 1000 )            % <-- Experimentally determined.
    % Testing shows BSXFUN is faster in this regime
    B = bsxfun(@rdivide, w, B);         % w(k)/(y(j)-x(k))
    B = bsxfun(@rdivide, B, sum(B, 2)); % Normalisation.
else
    % Else use FOR loops
    for k = 1:N
        B(:,k) = w(k)./B(:,k);          % w(k)/(y(j)-x(k))
    end
    c = 1./sum(B, 2);                   % Normalisation.
    for j = 1:M
        B(j,:) = B(j,:)*c(j);
    end
end

% Where points coincide there will be division by zeros (as with bary.m).
% Replace these entries with the identity:
B(isnan(B)) = 1;

% Flipping trick:
if ( nargin > 5 && doFlip )
    ii = logical(rot90(tril(ones(M, N)), 2));
    ii = fliplr(ii);
    rot90D = rot90(B, 2);
    B(ii) = rot90D(ii);
    B(isnan(B)) = 1;
end

end


%CORRECTMATCHES  Refines coordinates of corresponding points
%
%     [newPoints1, newPoints2] = cv.correctMatches(F, points1, points2)
%
% ## Input
% * __F__ 3x3 fundamental matrix.
% * __points1__ first set of 2D points. A numeric Nx2/Nx1x2/1xNx2 array or a
%   cell array of 2-element vectors `{[x,y], ...}` (floating-point precision).
% * __points2__ second set of 2D points. Same size and type as `points1`.
%
% ## Output
% * __newPoints1__ The optimized `points1`. Similar in shape to `points1`
%   (either Nx2/1xNx2 numeric array or cell array of 2D points).
% * __newPoints2__ The optimized `points2`.
%
% The function implements the Optimal Triangulation Method (see [Hartley2004]
% for details). For each given point correspondence `points1[i] <-> points2[i]`,
% and a fundamental matrix `F`, it computes the corrected correspondences
% `newPoints1[i] <-> newPoints2[i]` that minimize the geometric error:
%
%     d(points1[i], newPoints1[i])^2 + d(points2[i], newPoints2[i])^2
%
% (where `d(a,b)` is the geometric distance between points `a` and `b`)
% subject to the epipolar constraint
%
%     newPoints2' * F * newPoints1 = 0
%
% ## References
% [Hartley2004]:
% > R.I. Hartley and A. Zisserman. "Multiple View Geometry in Computer Vision"
% > Cambridge University Press, 2004.
%
% See also: cv.findFundamentalMat
%


function jac = p17_jac ( neqn, t, y )

%*****************************************************************************80
%
%% P17_JAC evaluates the jacobian for problem p17.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Input, real T, Y(NEQN), the arguments of the jacobian.
%
%    Output, real JAC(NEQN,NEQN), the jacobian matrix.
%
  jac = zeros ( neqn, neqn );

  d = ( sqrt ( ( y(1).^2 + y(2).^2 ) ) ).^5;

  jac(1,3) = 1.0;
  jac(2,4) = 1.0;
  jac(3,1) = ( 2.0 * y(1).^2 - y(2).^2 ) / d;
  jac(3,2) = 3.0 * y(1) * y(2) / d;
  jac(4,1) = 3.0 * y(1) * y(2) / d;
  jac(4,2) = ( - y(1).^2 + 2.0 * y(2).^2 ) / d;

  return
end


% [PYR, INDICES] = buildSCFpyrLevs(LODFT, LOGRAD, XRCOS, YRCOS, ANGLE, HEIGHT, NBANDS)
%
% Recursive function for constructing levels of a steerable pyramid.  This
% is called by buildSCFpyr, and is not usually called directly.

% Original code: Eero Simoncelli, 5/97.
% Modified by Javier Portilla to generate complex bands in 9/97.

function [pyr,pind] = buildSCFpyrLevs(lodft,log_rad,Xrcos,Yrcos,angle,ht,nbands);

if (ht <= 0)

  lo0 = ifft2(ifftshift(lodft));
  pyr = real(lo0(:));
  pind = size(lo0);

else

  bands = zeros(prod(size(lodft)), nbands);
  bind = zeros(nbands,2);

%  log_rad = log_rad + 1;
  Xrcos = Xrcos - log2(2);  % shift origin of lut by 1 octave.

  lutsize = 1024;
  Xcosn = pi*[-(2*lutsize+1):(lutsize+1)]/lutsize;  % [-2*pi:pi]
  order = nbands-1;
  %% divide by sqrt(sum_(n=0)^(N-1)  cos(pi*n/N)^(2(N-1)) )
  %% Thanks to Patrick Teo for writing this out :)
  const = (2^(2*order))*(factorial(order)^2)/(nbands*factorial(2*order));

%
%  Ycosn = sqrt(const) * (cos(Xcosn)).^order;
%
  % analityc version: only take one lobe
  alfa=	mod(pi+Xcosn,2*pi)-pi;
  Ycosn = 2*sqrt(const) * (cos(Xcosn).^order) .* (abs(alfa)<pi/2);

  himask = pointOp(log_rad, Yrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);

  for b = 1:nbands
    anglemask = pointOp(angle, Ycosn, Xcosn(1)+pi*(b-1)/nbands, Xcosn(2)-Xcosn(1));
    banddft = ((-i)^(nbands-1)) .* lodft .* anglemask .* himask;
    band = ifft2(ifftshift(banddft));

%    bands(:,b) = real(band(:));
    % analytic version: full complex value
    bands(:,b)=band(:);
    bind(b,:)  = size(band);
  end

  dims = size(lodft);
  ctr = ceil((dims+0.5)/2);
  lodims = ceil((dims-0.5)/2);
  loctr = ceil((lodims+0.5)/2);
  lostart = ctr-loctr+1;
  loend = lostart+lodims-1;

  log_rad = log_rad(lostart(1):loend(1),lostart(2):loend(2));
  angle = angle(lostart(1):loend(1),lostart(2):loend(2));
  lodft = lodft(lostart(1):loend(1),lostart(2):loend(2));
  YIrcos = abs(sqrt(1.0 - Yrcos.^2));
  lomask = pointOp(log_rad, YIrcos, Xrcos(1), Xrcos(2)-Xrcos(1), 0);

  lodft = lomask .* lodft;

  [npyr,nind] = buildSCFpyrLevs(lodft, log_rad, Xrcos, Yrcos, angle, ht-1, nbands);

  pyr = [bands(:); npyr];
  pind = [bind; nind];

end


function [ld, UC] = logdet(A, UC)

% LOGDET The log of the determinant when argument is positive definite.
% FORMAT
% DESC returns the log determinant of a positive definite matrix. If
% the matrix isn't quite positive definite the function adds 'jitter'
% to make it positive definite and gives out a warning message (this
% is done through JITCHOL).
% ARG A : the input positive definite matrix for which the log
% determinant is required.
% RETURN d : the log determinant of A computed using Cholesky
% decomposition.
% RETURN U : the Cholesky decomposition of A.
%
% FORMAT
% DESC returns the log determinant of a positive definite matrix given
% the Cholesky decomposition of A. If jitter is used then the
% amount of jitter used is returned.
% ARG A : the input positive definite matrix for which the log
% determinant is required.
% ARG U : the Cholesky decomposition of A.
% RETURN d : the log determinant of A computed using Cholesky
% decomposition.
% RETURN U : the Cholesky decomposition of A.
% RETURN jitter : the amount of jitter added.
%
% SEEALSO : jitChol, pdinv, chol
%
% COPYRIGHT : Neil D. Lawrence, 2003, 2004, 2005, 2006

% NDLUTIL

if nargin < 2
  UC=[];
end

% Obtain a Cholesky decomposition.
if isempty(UC)
  if nargout > 2
    [UC, jitter] = jitChol(A);
  else
    UC = jitChol(A);
  end
end

ld = 2*sum(log(diag(UC)));


function [J grad] = nnCostFunction(nn_params, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, ...
                                   X, y, lambda)
%NNCOSTFUNCTION Implements the neural network cost function for a two layer
%neural network which performs classification
%   [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size, num_labels, ...
%   X, y, lambda) computes the cost and gradient of the neural network. The
%   parameters for the neural network are "unrolled" into the vector
%   nn_params and need to be converted back into the weight matrices.
%
%   The returned parameter grad should be a "unrolled" vector of the
%   partial derivatives of the neural network.
%

% Reshape nn_params back into the parameters Theta1 and Theta2, the weight matrices
% for our 2 layer neural network
Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
                 hidden_layer_size, (input_layer_size + 1));

Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
                 num_labels, (hidden_layer_size + 1));

% Setup some useful variables
m = size(X, 1);

% You need to return the following variables correctly
J = 0;
Theta1_grad = zeros(size(Theta1));
Theta2_grad = zeros(size(Theta2));

% ====================== YOUR CODE HERE ======================
% Instructions: You should complete the code by working through the
%               following parts.
%
% Part 1: Feedforward the neural network and return the cost in the
%         variable J. After implementing Part 1, you can verify that your
%         cost function computation is correct by verifying the cost
%         computed in ex4.m

% Add ones to the X data matrix
X = [ones(m, 1) X];
% Convert y from (1-10) class into num_labels vector
yd = eye(num_labels);
y = yd(y,:);

%%% Map from Layer 1 to Layer 2
a1=X;
% Coverts to matrix of 5000 examples x 26 thetas
z2=X*Theta1';
% Sigmoid function converts to p between 0 to 1
a2=sigmoid(z2);

%%% Map from Layer 2 to Layer 3
% Add ones to the h1 data matrix
a2=[ones(m, 1) a2];
% Converts to matrix of 5000 exampls x num_labels
z3=a2*Theta2';
% Sigmoid function converts to p between 0 to 1
a3=sigmoid(z3);

% Compute cost
%logisf=(-y)'*log(a3)-(1-y)'*log(1-a3);
logisf=(-y).*log(a3)-(1-y).*log(1-a3); % Becos y is now a matrix, so use dot product, unlike above
%J=((1/m).*sum(sum(logisf)));	% This line is correct if there is no regularization
% Try with ...
% J=((1/m).*sum((logisf)));
% That will give J in 10 columns (it has summed m samples), so need to sum again

%% Regularized cost
Theta1s=Theta1(:,2:end);
Theta2s=Theta2(:,2:end);
J=((1/m).*sum(sum(logisf)))+(lambda/(2*m)).*(sum(sum(Theta1s.^2))+sum(sum(Theta2s.^2)));

% Part 2: Implement the backpropagation algorithm to compute the gradients
%         Theta1_grad and Theta2_grad. You should return the partial derivatives of
%         the cost function with respect to Theta1 and Theta2 in Theta1_grad and
%         Theta2_grad, respectively. After implementing Part 2, you can check
%         that your implementation is correct by running checkNNGradients
%
%         Note: The vector y passed into the function is a vector of labels
%               containing values from 1..K. You need to map this vector into a
%               binary vector of 1's and 0's to be used with the neural network
%               cost function.
%
%         Hint: We recommend implementing backpropagation using a for-loop
%               over the training examples if you are implementing it for the
%               first time.
%
% Set all the D to zeros
tridelta_1=0;
tridelta_2=0;

% Compute delta, tridelta and big D
	delta_3=a3-y;
    z2=[ones(m,1) z2];
	delta_2=delta_3*Theta2.*sigmoidGradient(z2);
    delta_2=delta_2(:,2:end);
	tridelta_1=tridelta_1+delta_2'*a1; % Same size as Theta1_grad (25x401)
    tridelta_2=tridelta_2+delta_3'*a2; % Same size as Theta2_grad (10x26)
	Theta1_grad=(1/m).*tridelta_1;
    Theta2_grad=(1/m).*tridelta_2;
    %Theta1_grad=0;
	%Theta2_grad=0;
%end

% Part 3: Implement regularization with the cost function and gradients.
%
%         Hint: You can implement this around the code for
%               backpropagation. That is, you can compute the gradients for
%               the regularization separately and then add them to Theta1_grad
%               and Theta2_grad from Part 2.
%

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

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

% Unroll gradients
grad = [Theta1_grad(:) ; Theta2_grad(:)];

end


function [model, L] = ppcaVb(X, q, prior)
% Perform variatioanl Bayeisan inference for probabilistic PCA model.
% Input:
%   X: d x n data matrix
%   q: dimension of target space
% Output:
%   model: trained model structure
%   L: variantional lower bound
% Reference:
%   Pattern Recognition and Machine Learning by Christopher M. Bishop
% Written by Mo Chen (sth4nth@gmail.com).
[m,n] = size(X);
if nargin < 3
    a0 = 1e-4;
    b0 = 1e-4;
    c0 = 1e-4;
    d0 = 1e-4;
else
    a0 = prior.a;
    b0 = prior.b;
    c0 = prior.c;
    d0 = prior.d;
end

if nargin < 2
    q = m-1;
end
tol = 1e-6;
maxIter = 500;
L = -inf(1,maxIter);

mu = mean(X,2);
Xo = bsxfun(@minus, X, mu);
s = dot(Xo(:),Xo(:));
I = eye(q);
% init parameters
a = a0+m/2;
c = c0+m*n/2;
Ealpha = 1e-4;
Ebeta = 1e-4;
EW = rand(q,m);
EWo = bsxfun(@minus,EW,mean(EW,2));
EWW = EWo*EWo'/m+EW*EW';
for iter = 2:maxIter
%     q(z)
    LZ = I+Ebeta*EWW;
    V = inv(chol(LZ));                   % inv(LZ) = V*V';
    EZ = LZ\EW*Xo*Ebeta;
    EZZ = n*(V*V')+EZ*EZ';
    KLZ = n*sum(log(diag(V)));           % KLZ = 0.5*n*log(det(inv(LZ)));
%     q(w)
    LW = diag(Ealpha)+Ebeta*EZZ;
    V = inv(chol(LW));                   % inv(LW) = V*V';
    EW = LW\EZ*Xo'*Ebeta;
    EWW = m*(V*V')+EW*EW';
    KLW = m*sum(log(diag(V)));           % KLW = 0.5*n*log(det(inv(LW)));
%     q(alpha)
    b = b0+diag(EWW)/2;
    Ealpha = a./b;
    KLalpha = -sum(a*log(b));
%     q(beta)
    WZ = EW'*EZ;
    d = d0+(s-2*dot(Xo(:),WZ(:))+dot(EWW(:),EZZ(:)))/2;
    Ebeta = c/d;
    KLbeta = -c*log(d);
%     q(mu)
%     Emu = Ebeta/(lambda+n*Ebeta)*sum(X-WZ,2);

%     lower bound
    L(iter) = KLalpha+KLbeta+KLW+KLZ;
    if L(iter)-L(iter-1) < tol*abs(L(iter-1)); break; end
end
L = L(2:iter);

model.Z = EZ;
model.W = EW;
model.apha = Ealpha;
model.beta = Ebeta;
model.a = a;
model.b = b;
model.c = c;
model.d = d;
model.mu = mu;


function ellipse_t = ellFit(x,y,axis_handle,colorStr)
% Finds the best fit to an ellipse for the given set of points.
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=3215&objectType=File
%
% Format:   ellipse_t = ellFit( x,y, [axis_handle])
%
% Input:    x,y         - a set of points in 2 column vectors. AT LEAST 5 points are needed !
%           axis_handle - optional. a handle to an axis, at which the estimated ellipse
%                         will be drawn along with it's axes
%
% Output:   ellipse_t - structure that defines the best fit to an ellipse
%                       a           - sub axis (radius) of the X axis of the non-tilt ellipse
%                       b           - sub axis (radius) of the Y axis of the non-tilt ellipse
%                       phi         - orientation in radians of the ellipse (tilt)
%                       X0          - center at the X axis of the non-tilt ellipse
%                       Y0          - center at the Y axis of the non-tilt ellipse
%                       X0_in       - center at the X axis of the tilted ellipse
%                       Y0_in       - center at the Y axis of the tilted ellipse
%                       long_axis   - size of the long axis of the ellipse
%                       short_axis  - size of the short axis of the ellipse
%                       status      - status of detection of an ellipse
%
% Note:     if an ellipse was not detected (but a parabola or hyperbola), then
%           an empty structure is returned
%
% Example:  (Verify recovery)
%     a = 1.45; b = 3.2; theta = 0.15; radSpacing = 0.05;
%     [x,y] = ellipsePoints(a,b,theta,radSpacing);
%     figure(1), plot(x,y,'-'); axis equal
%     ellS = ellFit(x,y);
%     [ellS.a, ellS.b, ellS.phi]
%     [a, b, theta]
%
%     a = 1.45; b = 3.2; theta = pi/5; radSpacing = 0.05;
%     [x,y] = ellipsePoints(a,b,theta,radSpacing);
%     figure(1), plot(x,y,'-'); axis equal
%     for ii=1:10
%       ellS = ellFit(x + randn(size(x))/5, y + randn(size(y))/5);
%       aHat(ii) = ellS.a; bHat(ii) = ellS.b; thetaHat(ii) =  ellS.phi;
%     end
%     [mean(aHat), mean(bHat), mean(thetaHat)]
%
%     ellS = ellFit(x,y,figure(1));

%
% =====================================================================================
%                  Ellipse Fit using Least Squares criterion
% =====================================================================================
% We will try to fit the best ellipse to the given measurements. the mathematical
% representation of use will be the CONIC Equation of the Ellipse which is:
%
%    Ellipse = a*x^2 + b*x*y + c*y^2 + d*x + e*y + f = 0
%
% The fit-estimation method of use is the Least Squares method (without any weights)
% The estimator is extracted from the following equations:
%
%    g(x,y;A) := a*x^2 + b*x*y + c*y^2 + d*x + e*y = f
%
%    where:
%       A   - is the vector of parameters to be estimated (a,b,c,d,e)
%       x,y - is a single measurement
%
% We will define the cost function to be:
%
%   Cost(A) := (g_c(x_c,y_c;A)-f_c)'*(g_c(x_c,y_c;A)-f_c)
%            = (X*A+f_c)'*(X*A+f_c)
%            = A'*X'*X*A + 2*f_c'*X*A + N*f^2
%
%   where:
%       g_c(x_c,y_c;A) - vector function of ALL the measurements
%                        each element of g_c() is g(x,y;A)
%       X              - a matrix of the form: [x_c.^2, x_c.*y_c, y_c.^2, x_c, y_c ]
%       f_c            - is actually defined as ones(length(f),1)*f
%
% Derivation of the Cost function with respect to the vector of parameters "A" yields:
%
%   A'*X'*X = -f_c'*X = -f*ones(1,length(f_c))*X = -f*sum(X)
%
% Which yields the estimator:
%
%       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%       |  A_least_squares = -f*sum(X)/(X'*X) ->(normalize by -f) = sum(X)/(X'*X)  |
%       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%
% (We will normalize the variables by (-f) since "f" is unknown and can be accounted for later on)
%
% NOW, all that is left to do is to extract the parameters from the Conic Equation.
% We will deal the vector A into the variables: (A,B,C,D,E) and assume F = -1;
%
%    Recall the conic representation of an ellipse:
%
%       A*x^2 + B*x*y + C*y^2 + D*x + E*y + F = 0
%
% We will check if the ellipse has a tilt (=orientation). The orientation is present
% if the coefficient of the term "x*y" is not zero. If so, we first need to remove the
% tilt of the ellipse.
%
% If the parameter "B" is not equal to zero, then we have an orientation (tilt) to the ellipse.
% we will remove the tilt of the ellipse so as to remain with a conic representation of an
% ellipse without a tilt, for which the math is more simple:
%
% Non tilt conic rep.:  A`*x^2 + C`*y^2 + D`*x + E`*y + F` = 0
%
% We will remove the orientation using the following substitution:
%
%   Replace x with cx+sy and y with -sx+cy such that the conic representation is:
%
%   A(cx+sy)^2 + B(cx+sy)(-sx+cy) + C(-sx+cy)^2 + D(cx+sy) + E(-sx+cy) + F = 0
%
%   where:      c = cos(phi)    ,   s = sin(phi)
%
%   and simplify...
%
%       x^2(A*c^2 - Bcs + Cs^2) + xy(2A*cs +(c^2-s^2)B -2Ccs) + ...
%           y^2(As^2 + Bcs + Cc^2) + x(Dc-Es) + y(Ds+Ec) + F = 0
%
%   The orientation is easily found by the condition of (B_new=0) which results in:
%
%   2A*cs +(c^2-s^2)B -2Ccs = 0  ==> phi = 1/2 * atan( b/(c-a) )
%
%   Now the constants   c=cos(phi)  and  s=sin(phi)  can be found, and from them
%   all the other constants A`,C`,D`,E` can be found.
%
%   A` = A*c^2 - B*c*s + C*s^2                  D` = D*c-E*s
%   B` = 2*A*c*s +(c^2-s^2)*B -2*C*c*s = 0      E` = D*s+E*c
%   C` = A*s^2 + B*c*s + C*c^2
%
% Next, we want the representation of the non-tilted ellipse to be as:
%
%       Ellipse = ( (X-X0)/a )^2 + ( (Y-Y0)/b )^2 = 1
%
%       where:  (X0,Y0) is the center of the ellipse
%               a,b     are the ellipse "radiuses" (or sub-axis)
%
% Using a square completion method we will define:
%
%       F`` = -F` + (D`^2)/(4*A`) + (E`^2)/(4*C`)
%
%       Such that:    a`*(X-X0)^2 = A`(X^2 + X*D`/A` + (D`/(2*A`))^2 )
%                     c`*(Y-Y0)^2 = C`(Y^2 + Y*E`/C` + (E`/(2*C`))^2 )
%
%       which yields the transformations:
%
%           X0  =   -D`/(2*A`)
%           Y0  =   -E`/(2*C`)
%           a   =   sqrt( abs( F``/A` ) )
%           b   =   sqrt( abs( F``/C` ) )
%
% And finally we can define the remaining parameters:
%
%   long_axis   = 2 * max( a,b )
%   short_axis  = 2 * min( a,b )
%   Orientation = phi
%
%

if notDefined('colorStr');
    colorStr = 'r';
end
% initialize
orientation_tolerance = 1e-3;

% empty warning stack
warning( '' );

% prepare vectors, must be column vectors
x = x(:);
y = y(:);

% remove bias of the ellipse - to make matrix inversion more accurate. (will be added later on).
mean_x = mean(x);
mean_y = mean(y);
x = x-mean_x;
y = y-mean_y;

% the estimation for the conic equation of the ellipse
X = [x.^2, x.*y, y.^2, x, y ];
a = sum(X)/(X'*X);

% check for warnings
if ~isempty( lastwarn )
    disp( 'stopped because of a warning regarding matrix inversion' );
    ellipse_t = [];
    return
end

% extract parameters from the conic equation
[a,b,c,d,e] = deal( a(1),a(2),a(3),a(4),a(5) );

% remove the orientation from the ellipse
if ( min(abs(b/a),abs(b/c)) > orientation_tolerance )

    orientation_rad = 1/2 * atan( b/(c-a) );
    cos_phi = cos( orientation_rad );
    sin_phi = sin( orientation_rad );
    [a,b,c,d,e] = deal(...
        a*cos_phi^2 - b*cos_phi*sin_phi + c*sin_phi^2,...
        0,...
        a*sin_phi^2 + b*cos_phi*sin_phi + c*cos_phi^2,...
        d*cos_phi - e*sin_phi,...
        d*sin_phi + e*cos_phi );
    [mean_x,mean_y] = deal( ...
        cos_phi*mean_x - sin_phi*mean_y,...
        sin_phi*mean_x + cos_phi*mean_y );
else
    orientation_rad = 0;
    cos_phi = cos( orientation_rad );
    sin_phi = sin( orientation_rad );
end

% check if conic equation represents an ellipse
test = a*c;
switch (1)
case (test>0),  status = '';
case (test==0), status = 'Parabola found';  warning( 'fit_ellipse: Did not locate an ellipse' );
case (test<0),  status = 'Hyperbola found'; warning( 'fit_ellipse: Did not locate an ellipse' );
end

% if we found an ellipse return it's data
if (test>0)

    % make sure coefficients are positive as required
    if (a<0), [a,c,d,e] = deal( -a,-c,-d,-e ); end

    % final ellipse parameters
    X0          = mean_x - d/2/a;
    Y0          = mean_y - e/2/c;
    F           = 1 + (d^2)/(4*a) + (e^2)/(4*c);
    [a,b]       = deal( sqrt( F/a ),sqrt( F/c ) );
    long_axis   = 2*max(a,b);
    short_axis  = 2*min(a,b);

    % rotate the axes backwards to find the center point of the original TILTED ellipse
    R           = [ cos_phi sin_phi; -sin_phi cos_phi ];
    P_in        = R * [X0;Y0];
    X0_in       = P_in(1);
    Y0_in       = P_in(2);

    % pack ellipse into a structure
    ellipse_t = struct( ...
        'a',a,...
        'b',b,...
        'phi',orientation_rad,...
        'X0',X0,...
        'Y0',Y0,...
        'X0_in',X0_in,...
        'Y0_in',Y0_in,...
        'long_axis',long_axis,...
        'short_axis',short_axis,...
        'status','' );
else
    % report an empty structure
    ellipse_t = struct( ...
        'a',[],...
        'b',[],...
        'phi',[],...
        'X0',[],...
        'Y0',[],...
        'X0_in',[],...
        'Y0_in',[],...
        'long_axis',[],...
        'short_axis',[],...
        'status',status );
end

% check if we need to plot an ellipse with it's axes.
if (nargin>2) && ~isempty( axis_handle ) && (test>0)

    % rotation matrix to rotate the axes with respect to an angle phi
    R = [ cos_phi sin_phi; -sin_phi cos_phi ];

    % the axes
    ver_line        = [ [X0 X0]; Y0+b*[-1 1] ];
    horz_line       = [ X0+a*[-1 1]; [Y0 Y0] ];
    new_ver_line    = R*ver_line;
    new_horz_line   = R*horz_line;

    % the ellipse
    theta_r         = linspace(0,2*pi);
    ellipse_x_r     = X0 + a*cos( theta_r );
    ellipse_y_r     = Y0 + b*sin( theta_r );
    rotated_ellipse = R * [ellipse_x_r;ellipse_y_r];

    % draw
    hold_state = get( axis_handle,'NextPlot' );
    set( axis_handle,'NextPlot','add' );
%     plot( new_ver_line(1,:),new_ver_line(2,:),colorStr );
%     plot( new_horz_line(1,:),new_horz_line(2,:),colorStr );
    plot( rotated_ellipse(1,:),rotated_ellipse(2,:),colorStr );
    set( axis_handle,'NextPlot',hold_state );
end


% Flush out the MATLAB.
close all;
clc;
clear all;

% Read the desired image file.
ImageData=imread('BC.jpg');

% Calculate the number of pixels.
NoOfPixel=size(ImageData,1)*size(ImageData,2);

% Display the original image.
figure,imshow(ImageData);
title(' Original Image without Histogram: ');

% Histogram image implementation.
HistogramImage=uint8(zeros(size(ImageData,1),size(ImageData,2)));

Frequency=zeros(256,1);

ProbabilityFrequency=zeros(256,1);

ProbabilityC=zeros(256,1);

Cumulative=zeros(256,1);

OutputZeros=zeros(256,1);

% Cumulative histogram for each and every pixel og image.
for a=1:size(ImageData,1)

    for b=1:size(ImageData,2)
        FinalValue=ImageData(a,b);

        Frequency(FinalValue+1)=Frequency(FinalValue+1)+1;

        ProbabilityFrequency(FinalValue+1)=Frequency(FinalValue+1)/NoOfPixel;
    end

end

FinalSum=0;

NumberBin=255;

% Distributation probability for each and every pixel.
for a=1:size(ProbabilityFrequency)
   FinalSum=FinalSum+Frequency(a);

   Cumulative(a)=FinalSum;

   ProbabilityC(a)=Cumulative(a)/NoOfPixel;

   OutputZeros(a)=round(ProbabilityC(a)*NumberBin);
end

% Final calculation.
for a=1:size(ImageData,1)

    for b=1:size(ImageData,2)
            HistogramImage(a,b)=OutputZeros(ImageData(a,b)+1);
    end

end

% Display the output image.
figure,imshow(HistogramImage);
title(' Final Image with Histogram: ');


% Calculate the log mel filter bank from waveform
% Author: Xiao Xiong
% Created: 4 Feb 2005
% Last modified: 4 Feb 2005

function [fbank] = wav2fbank(x, fs, frame_shift, nMel)
if nargin < 2
    fs = 8000;
end
if nargin < 3
    frame_shift = 0.01;
end
if nargin<4
    nMel = 23;
end

absX = wav2abs(x,fs,frame_shift);
fbank = log (abs2Mel(absX, fs, nMel));


function [ fa ] = gsp_cfa( T,fs )
%GSP_CFA Create frequency axis
%   Usage: fa = gsp_cfa(N);
%          fa = gsp_cfa(N,fs);
%
%   Input parameters:
%       N   : Number of samples
%       fs  : Sampling frequency (default 1)
%   Ouput parameters:
%       fa  : Frequency axis
%
%   This function create a normalized frequency axis corresponding to the
%   frequency of the function fft.
%

% Author: Nathanael Perraudin

if nargin<2
    fs = 1;
end

if mod(T,2)
    fa = linspace(-0.5+1/(2*T),0.5-1/(2*T),T);
else
    fa = linspace(-0.5,0.5-1/T,T);
end

fa = fa*fs;

fa = ifftshift(fa);
fa = fa(:);

end


function determ = herndon_determinant ( n )

%*****************************************************************************80
%
%% HERNDON_DETERMINANT returns the determinant of the Herndon matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Output, real DETERM, the determinant.
%
  determ = 6.0 / ( ( n + 1 ) * n * ( 5 - 2 * n ) );

  return
end


function p = predictOneVsAll(all_theta, X)
%PREDICT Predict whether the label is 0 or 1 using learned logistic
%regression parameters all_theta
%   p = PREDICT(all_theta, X) computes the predictions for X using a
%   threshold at 0.5 (i.e., if sigmoid(all_theta'*x) >= 0.5, predict 1)

m = size(X, 1);
num_labels = size(all_theta, 1);

% You need to return the following variables correctly
p = zeros(size(X, 1), 1);

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

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned logistic regression parameters (one-vs-all).
%               You should set p to a vector of predictions (from 1 to
%               num_labels).
%
% Hint: This code can be done all vectorized using the max function.
%       In particular, the max function can also return the index of the
%       max element, for more information see 'help max'. If your examples
%       are in rows, then, you can use max(A, [], 2) to obtain the max
%       for each row.
%

% Coverts to matrix of 5000 examples vs. num_lables (each sample has num_labels of corresponding prob
z=X*all_theta';
% Sigmoid function converts to p between 0 to 1
h=sigmoid(z);

% pval returns the highest value in each row, while p returns the position in each row
[pval, p]=max(h,[],2);

% Later in ex3 file, the p will be used to match the y and predict the training accuracy
% =========================================================================

end


function p = predict(theta, X)
%PREDICT Predict whether the label is 0 or 1 using learned logistic
%regression parameters theta
%   p = PREDICT(theta, X) computes the predictions for X using a
%   threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1)

m = size(X, 1); % Number of training examples

% You need to return the following variables correctly
p = zeros(m, 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned logistic regression parameters.
%               You should set p to a vector of 0's and 1's
%

h = sigmoid(X*theta);
ids = find(h>=0.5);
p(ids) = 1;
ids = find(h<0.5);
p(ids) = 0;

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

end


function determ = wilk21_determinant ( n )

%*****************************************************************************80
%
%% WILK21_DETERMINANT computes the determinant of the WILK21 matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Output, real DETERM, the determinant.
%
  d = zeros ( n, 1 );

  for i = 1 : n
    d(i) = round ( abs ( i - ( n + 1 ) / 2 ) );
  end

  determ_nm1 = d(n);

  if ( n == 1 )
    determ = determ_nm1;
    return
  end

  determ_nm2 = determ_nm1;
  determ_nm1 = d(n-1) * d(n) - 1.0;

  if ( n == 2 )
    determ = determ_nm1;
    return
  end

  for i = n - 2 : -1 : 1

    determ = d(i) * determ_nm1 - determ_nm2;

    determ_nm2 = determ_nm1;
    determ_nm1 = determ;

  end

  return
end


function turnDir=turnOrientation(v1,v2,v3)
%%TURNORIENTATION Given 3 two-dimensional vertices in order, determine
%                 whether they form a left turn (go counterclockwise).
%                 Such a determination is necessary for determining
%                 whether a polygon is convex and plays a role in
%                 finding the convex hull of a set of points.
%
%INPUTS: v1, v2, v3 A set of 3 2XN matrices, of N vertex sets in the order
%                   [x;y] These are 2-dimensional vertices in order,
%                   whereby one wishes to determine whether the angle
%                   v1-v2-v3 is going counterclockwise (left) or clockwise
%                   (right) for each set of vertices.
%
%OUTPUTS: turnDir  An NX1 vector where the ith element is is 1 if the ith
%                  set of vertices form a counterclockwise angle, -1 if
%                  they are going clockwise and 0 if they are collinear or
%                  if two of them coincide.
%
%An implementation is given ehre in Matlab. However, the implementation in
%C++ might be more accurate, assuming that one's compilter implements the
%long double datatype as an IEEE-754 souble extended precision datatype.
%A notable exception is Microsoft's Visual Studio (as of 2017), which maps
%long doubles to doubles (64 bits rather than the 80-bit size of Intel/
%AMD floating point registers) as noted in
%https://docs.microsoft.com/en-us/cpp/c-language/type-long-double
%Additionally, the function exactSignOfSumCPP is used to provide the sign
%of an error-free sum. Unfortunately, since the IEEE-754 double extended
%precision datatype only provides a 64-bit mantissa, which is not much of
%an extension over the 54-bit mantissa of a standard double precision
%floating point number, and is not enough to assure no finite precision
%rounding in the products that go into the sum, one cannot guarantee zero
%finite precision errors in this function. On the other hand, if the
%inputs are single-precision (promoted to doubles, since the function does
%not take singles) floating point numbers, the result is exact.
%
%The cross product rule for 3D vectors a and b says that
%norm(cross(a,b))=norm(a)*norm(b)*sin(theta)
%where theta is the positive angle between the vectors. However, If the
%vectors are 2D, (set the z-components to zero), then the cross product
%only have one nonzero component in the z-direction and that component is
%equal to det([a,b]) (for 2D a and b). The interesting thing now, is that
%the sign of the determinant will tell you whether the subsequent vectors
%are going counterclockwise or clockwise. This function returns -1 if the
%vectors are going counterclockwise, 0 if they are exactly collinear and 1
%if they are clockwise.
%
%The Matlab implementation can be used without a compilation. The compiled
%version of the algorithm can be obtained using the
%CompileCLibraries function.
%
%The algorithm is run in Matlab using the command format
%turnDir=turnOrientation(v1,v2,v3);
%
%December 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

    S=zeros(6,1);
    S(1)=v3(1)*v1(2);
    S(2)=v1(1)*v2(2);
    S(3)=v2(1)*v3(2);
    S(4)=-v3(1)*v2(2);
    S(5)=-v1(1)*v3(2);
    S(6)=-v2(1)*v1(2);

    turnDir=exactSignOfSum(S);
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.


clear all
close all

d1=3;
d2=5;
N=100;

disp('Model order selection');

%m=min([d1,d2])
m=3;

% Generate true factor matrices
W1=10*randn(d1,m);
W2=10*randn(d2,m);

% Observation noise covariance
sig=1;
E1=sig*randn(d1,N);
E2=sig*randn(d2,N);

if m==0
    X1=E1;
    X2=E2;
else
    Z=randn(m,N);
    X1=W1*Z+E1;
    X2=W2*Z+E2;
end

for i=1:4,
    CVA = spm_cva_prob (X1,X2,i-1);
    L(i)=CVA.L;
    bic(i)=CVA.bic;
    aic(i)=CVA.aic;
end
figure
plot([0:3],L);
hold on
plot([0:3],bic,'r');
plot([0:3],aic,'g');
xlabel('Number of Canonical Vectors');
legend('LogLike','BIC','AIC');


function xycoords = latlon2xy(latlon,centerpoint)
    % convert lat,lon list into x,y given a lat-lon centerpoint
    %
    %This function will take coordinates given in latitude and longitude
    %and convert them to and x,y coordinate system with x pointing east, y
    %pointing north.

    %The zero point will be set at the point given in centerpoint, where
    %centerpoint is entered as [lat lon].

    lat = latlon(:,1);
    lon = latlon(:,2);

    %Defining the y and x coordinates of each lat and lon

    y = deg2km(lat - centerpoint(1));

    x = deg2km(lon - centerpoint(2)).*cosd(lat);

    %Outputting a vector with column1 = x coords, column2 = y coords

    xycoords = [x(:) y(:)];
end


function out = nsamdf_nonlinear_measure(data,fs,winLenRel,shiftLenRel,lagRel,degree,doPlot)
% nsamdf_nonlinear_measure computes the nonlinearity measure L through nsAMDF
% (nonlinear average magnitude difference function), developed by:
%
% Ozkurt et al. (2020), "Identification of nonlinear features in cortical and
% subcortical signals of Parkinson's Disease patients via a novel efficient
% measure", Neuroimage.
%
% Please refer to and cite this paper if you utilize this function in your work.
%
%---INPUTS:
%
% data = One dimensional input time-series (it can be raw, but it is a good idea to low-pass filter it to get rid of high frequency nuisance)
%        For the neural data (LFP, MEG) in the aferomentioned paper, we
%        low-passed the raw data for 40 Hz. The data should be long enough for proper estimation of nonlinearity.
%
% winlen = window length (a long enough segment is important to estimate the nonlinearity)
%          We chose the window length as 14 sec., i.e., winlen = 14*fs
%
% shiftlen = This amounts to window length - overlap length btw windows
%            We chose it as half the window length, i.e., shiftlen = 0.5*winlen
%
% lag = TMaximum lag for nsAMDF, we chose it as 1 sec, i.e., lag = fs.
%
% fs = sampling frequency of the data
%
% degree = The chosen degree p should ideally be large enough to capture the highest order of nonlinearity within the data.
%          We chose p=7 for in our case of Parkinsonian data in the paper.
%
% doPlot = true to plot nsAMDF sequences, otherwise just assign it false
%
%---OUTPUTS:
%
% L: nonlinearity measure
%
% s2: normalized nsAMDF for the degree 2
%
% sd: normalized nsAMDF for the chosen degree greater than 2
%
%
% Required subfunctions are NormedSingleCurveLengthWindowed.m & NormedSingleCurveLength.m
%
%
%   Authored by Tolga Esat Ozkurt, 2020. (tolgaozkurt@gmail.com)

%-------------------------------------------------------------------------------
% Set defaults:

if nargin < 2
    fs = 1;
end
if nargin < 3
    winLenRel = 14;
end
windowLength = winLenRel*fs;
if nargin < 4
    shiftLenRel = 0.5;
end
shiftLength = shiftLenRel*windowLength;
if nargin < 5
    lagRel = 1;
end
lag = fs*lagRel;
if nargin < 6
    degree = 7;
end
if nargin < 7
    doPlot = false
end

%-------------------------------------------------------------------------------
% nsAMDF for p=2:
s2 = NormedSingleCurveLengthWindowed(data,windowLength,shiftLength,lag,fs,2);
out.s2 = s2 ./ max(s2); % normalized

% nsAMDF for p=degree:
sd = NormedSingleCurveLengthWindowed(data,windowLength,shiftLength,lag,fs,degree);
out.sd = sd ./ max(sd); % normalized

% If you like, you can bandpass filter s2 and sd for the specific frequency band
% of nonlinear effect both to compute L and plot them as such

out.L = norm(s2 - sd);

%-------------------------------------------------------------------------------
if doPlot
    figure
    plot(s2,'b')
    hold on
    plot(sd,'g')
end

end


% dimension of ambient space
n = 6;
% number of subspaces = number of clusters
ns = 2;
% dimensions of individual subspaces 1 and 2
d1  = 2;
d2 = 2;
% number of signals in individual subspaces
s1 = 10;
s2 = 10;
% total number of signals
S = s1 + s2;
% A random basis for first subspace;
basis1 = randn(n,d1);
% coefficients for s1 vectors chosen randomly in subspace 1
coeffs1 = randn(d1,s1);
% Random signals from first subspace
X1 = basis1 * coeffs1;
% A random basis for second subspace
basis2 = randn(n,d2);
% coefficients for s2 vectors chosen randomly in subspace 2
coeffs2 = randn(d2,s2);
% Random signals from first subspace
X2 = basis2 * coeffs2;
% Prepare the overall set of signals
X = [X1 X2];
% ground through clustering data
true_labels = [1*ones(s1,1) ; 2*ones(s2,1)];
% the largest dimension amongst all subspaces
K = max(d1, d2);
X = spx.norm.normalize_l2(X);
C = spx.fast.gomp_spr(X, K, 2);

solver = spx.pursuit.single.OrthogonalMatchingPursuit(X, K);
C2 = zeros(S, S);
for s=1:S
    solver.IgnoredAtom = s;
    result = solver.solve(X(:, s));
    C2(:, s) = result.z;
end
max(C2 - C)
max(abs(X - X * C))


function r = invwishrand(S,nu);
%INVWISHRND Random matrices from inverse Wishard distribution.
%
%   R = INVWISHRAND(S,N) returns a matrix of random numbers chosen
%   from the central inverse Wishard distribution with parameters S and NU.
%
%   S is a symmetric positive definite scale matrix
%   NU is degrees of freedom
%
%   Note: E[R]=S*nu/(nu-k-1)
%
%	See also WISHRAND
%
% Copyright (c) 1999 Aki Vehtari

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

if nargin < 2
  error('Requires two input arguments.');
end;

[d d2] = size(S);
if d ~= d2
  error('Matrix S must be square');
end

[t,p]=chol(S);
if p < 0
  error('Matrix S must be positive definite.');
end

r=inv(wishrand(inv(S),nu));


function y = sphere_characteristic ( m, n, x )

%*****************************************************************************80
%
%% SPHERE_CHARACTERISTIC evaluates the characteristic function of a sphere.
%
%  Discussion:
%
%    The dimension of the sphere is arbitrary, and set by the input value M.
%
%    The sphere is assumed to have center at the origin and radius 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 May 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points to check.
%
%    Input, real X(M,N), the coordinates of points to be checked.
%
%    Output, real Y(N,1), is 1 if the point is inside, 0 otherwise.
%
  y = sqrt ( sum ( x.^2, 1 ) );

  y = y';

  y = ( y < 1.0 );

  return
end


%  高斯消去法 Gaussian_Elimination
function [x] = my_ge(A, b)

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

m = zeros(n);
%消元过程
for k = 1:n-1
  for i = k+1:n
    m(i,k) = A(i,k)/A(k,k);
    A(i,:) = A(i,:) - m(i,k) * A(k,:);
    b(i) = b(i) - m(i,k) * b(k);
  end
end
%回代过程
x(n) = b(n)/A(n,n);
for k = n-1 : -1 : 1
    summary = 0;
    for j = k+1 : n
        summary = summary + A(k,j) * x(j);
    end
    x(k) = (b(k) - summary) / A(k,k);
end


function [ lat, long ] = xy2latlong( x, y, ref_lat, ref_long )
% converts cartesian coordinates x,y (in km) to lat/long
% ref_lat and ref_long is the geodetic reference point for plane approximation of the earth surface

earth_circumf = 40074;

lat = (y * 360 / earth_circumf) + ref_lat;
long = ( (x*360) / (earth_circumf * cos(ref_lat*pi/180)) ) + ref_long;

end


function pass = test_kron(pref)
% Test the chebfun/kron() command.

if ( nargin < 1 )
    pref = chebfunpref();
end

tol = 200*pref.cheb2Prefs.chebfun2eps;

%% Kronecker products resulting in CHEBFUN2 objects

% Rank 1 chebfun2
f = chebfun(@(x) x.^2, pref);
g = chebfun(@(y) sin(y), pref);

h1 = chebfun2(@(x,y) x.^2.*sin(y));
h2 = chebfun2(@(x,y) y.^2.*sin(x));

pass(1) = (norm(h1 - kron(f', g)) < tol);
pass(2) = (norm(h2 - kron(f, g')) < tol);
pass(3) = (norm(h1 - g*f') < tol);
pass(4) = (norm(h2 - f*g') < tol);

% Different domain in x and y
d = [-2 pi -pi 2];
f = chebfun(@(x) x.^2, d(1:2), pref);
g = chebfun(@(y) sin(y), d(3:4), pref);

h1 = chebfun2(@(x,y) x.^2.*sin(y), d);
h2 = chebfun2(@(x,y) y.^2.*sin(x), [d(3:4) d(1:2)]);

pass(5) = ( norm(h1 - kron(f', g)) < tol);
pass(6) = (norm(h2 - kron(f, g')) < tol);
pass(7) = ( norm(h1 - g*f') < tol);
pass(8) = (norm(h2 - f*g') < tol);

% Quasimatrices and rank 4 chebfun2
x = chebfun('x', [-1 1], pref);
F = [1 x x.^2 x.^4];
G = [1 cos(x) sin(x) x.^5];

h1 = chebfun2(@(x,y) 1 + x.*cos(y) + x.^2.*sin(y) + x.^4.*y.^5);
h2 = chebfun2(@(x,y) 1 + y.*cos(x) + y.^2.*sin(x) + y.^4.*x.^5);

pass(9) = (norm(h1 - kron(F', G)) < tol);
pass(10) = (norm(h2 - kron(F, G')) < tol);
pass(11) = (norm(h1 - G*F') < tol);
pass(12) = (norm(h2 - F*G') < tol);

% Different domains and quasimatrices
x = chebfun('x',[-2 1], pref);
y = chebfun('x',[-1 1], pref);
d = [-2 1 -1 1];
F = [1 x x.^2 x.^4];
G = [1 cos(y) sin(y) y.^5];
h1 = chebfun2(@(x,y) 1 + x.*cos(y) + x.^2.*sin(y) + x.^4.*y.^5,d);
h2 = chebfun2(@(x,y) 1 + y.*cos(x) + y.^2.*sin(x) + y.^4.*x.^5,[d(3:4) d(1:2)]);

pass(13) = (norm(h1 - kron(F', G)) < tol);
pass(14) = (norm(h2 - kron(F, G')) < tol);
pass(15) = (norm(h1 - G*F') < tol);
pass(16) = (norm(h2 - F*G') < tol);

end


function[varargout]=instmom(varargin)
%INSTMOM  Univariate and multivariate instantaneous moments.
%   don't need this because it really doesn't seep things up much from
%   using anatrans and instmome
%
%   [A,OMEGA,UPSILON]=INSTMOM(X), where X is an analytic signal, computes
%   the amplitude A, instantaneous *radian* frequency OMEGA, and
%   instantaneous bandwidth assuming a unit sample rate.
%
%   X is an array with the first dimension being "time".  Thus, X can be a
%   matrix of analytic signals oriented as column vectors, or a 2- or 3-D
%   wavelet transform such as output by WAVETRANS.
%
%   The output arrays are the same size as X.
%
%   The instantaneous frequency, bandwidth, and curvature are defined as
%
%            A    = abs X
%          OMEGA  = d/dt Im ln X = d/dt arg X
%         UPSILON = d/dt Re ln X = d/dt ln abs X
%
%   where i=SQRT(-1) as usual.
%
%   INSTMOM(X,DIM) computes the moments along dimension DIM, instead of
%   the default of computing the moments along the rows (DIM=1).
%
%   For details, see
%
%       Lilly & Olhede (2010), "Bivariate instantaneous frequency and
%            bandwidth", IEEE Trans. Sig. Proc., 58 (2), 591--603.
%   _____________________________________________________________________
%
%   Sample interval
%
%   INSTMOM(DT,...) uses sample interval DT, where DT is a scalar, for
%   computing time derivatives.  DT=1 is the default.
%   _____________________________________________________________________
%
%   Joint instantaneous moments
%
%   INSTMOM can also calculate the joint instananeous moments of
%   multivariate signals, as defined in Lilly and Olhede (2010).
%
%   [JA,JOMEGA,JUPSILON]=INSTMOM(X1,X2,...,XN,DIM) returns the *joint*
%   instantaneous moments calculated across the N signals X1,X2,... XN,
%   based on the univariate instantaneous moments along dimension DIM.
%
%   The joint instantaneous amplitude JA is the root-mean-square of the
%   component amplitudes across dimension JDIM, while JOMEGA is power-
%   weighted average of the component instantaneous frequencies.
%
%   For details and for the definition of the joint instantaneous bandwidth
%   JUPSILON, see Lilly and Olhede (2010).
%
%   [JA,JOMEGA,JUPSILON]=INSTMOM(X,DIM,JDIM) also works, where the joint
%   instantaneous moments are calculated across dimensions JDIM of X.
%
%   The joint instantaneous moments JA, JOMEGA, and JUPSILON then have the
%   same size as X, except along dimension JDIM where they have only one
%   entry.  Note that DIM is no longer optional when JDIM is used.
%   _____________________________________________________________________
%
%   Instantaneous curvature
%
%   INSTMOM can also return the next-higher order instantaneous moment,
%   which is more rarely encountered.
%
%   [A,OMEGA,UPSILON,XI]=INSTMOM(X) returns the instantaneous curvature XI,
%   defined as
%
%            XI   = d^2/dt^2 abs X / abs X + i d^2/dt^2 arg X
%                 = UPSILON^2 + d/dt UPSILON + i d/dt OMEGA
%
%   Similarly [JA,JOMEGA,JUPSILON,JXI]=INSTMOM(X,DIM,JDIM) returns the
%   joint instantaneous curvature JXI for the multivariate signal X.
%
%   For details on the univariate and joint instantaneous curvature, see
%
%       Lilly and Olhede (2012a), "Analysis of modulated multivariate
%            oscillations", IEEE Trans. Sig. Proc., 60 (2), 600--612.
%   _____________________________________________________________________
%
%   Boundary conditions
%
%   The first and last points must be treated differently, as the central
%   difference is not defined there.  Three different methods can be used.
%
%   INSTMOM(...,STR) specifies the method: STR= 'endpoint' (the default),
%   'periodic', or 'nans'.  See VDIFF for details.
%   _____________________________________________________________________
%
%   'instmom --f' generates some sample figures.
%
%   Usage: [a,om]=instmom(x);
%          [a,om,up,xi]=instmom(dt,x);
%          [a,om,up,xi]=instmom(dt,x,dim);
%          [a,om,up,xi]=instmom(dt,x1,x2,x3,x4,dim);
%          [a,om,up,xi]=instmom(dt,x,dim,jdim);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2007--2019 J.M. Lilly --- type 'help jlab_license' for details

%   _____________________________________________________________________
%
%   Higher-order modulation functions
%
%   [OMEGA,RHO1,...RHON]=INSTMOM(X) also outputs the higher-order
%   instantaneous modulation functions.  RHO1 is identical to the
%   bandwidth, and RHO2 is called the curvature.
%
%   For details see
%
%      Lilly and Olhede (2010).  On the analytic wavelet transform.
%
%   Note that the modulation functions are defined in their non-normalized
%   form, that is, not divided by powers of the instananeous frequency,
%   unlike in Lilly and Olhede (2010).
%
%   _____________________________________________________________________

if strcmpi(varargin{1}, '--t')
    instmom_test,return
elseif strcmpi(varargin{1}, '--f')
    type makefigs_instmom
    makefigs_instmom;
    return
end

if length(varargin{1})==1
    dt=varargin{1};
    varargin=varargin(2:end);
else
    dt=1;
end

str='endpoint';
dim=1;
jdim=[];
for i=1:4
    if ischar(varargin{end})
        str=varargin{end};
        varargin=varargin(1:end-1);
    else
        if length(varargin{end})==1
            if length(varargin{end-1})==1
                dim=varargin{end-1};
                jdim=varargin{end};
                varargin=varargin(1:end-2);
            else
                dim=varargin{end};
                varargin=varargin(1:end-1);
            end
        end
    end
end

N=length(varargin);
if N==1
    x=varargin{1};
else
    jdim=lnsd(varargin{1})+1;
    sizex1=size(varargin{1});
    sizex1=sizex1(1:jdim-1);
    x=zeros([sizex1 N]);
    for i=1:N
         x=vindexinto(x,varargin{i},i,jdim);
    end
end

%Note: there are different ways to reasonably define the instantaneous
%frequency as a vdiff of the signal.  These differ greatly actually.
%Diffing the unwrapped angle seems to give the best results.  If you take
%the Im of the diffed log, you will break the wavelet phase algorithm!

%You definitely don't want to just do diff(x).  This differences the real
%and imaginary parts separately, which are themselves rapidly varying.

om=vdiff(unwrap(angle(x),[],dim),dim,str)./dt;
up=vdiff(log(abs(x)),dim,str)./dt;
eta=om-sqrt(-1)*up;

varargout{1}=abs(x);
varargout{2}=om;
nmax=nargout-2;

%I prefer this version, though difference is minor
%if nmax>=1
%   varargout(3)=frac(1,abs(x)).*vdiff(vdiff(abs(x),1,str),1,str)./dt./dt+sqrt(-1)*vdiff(om,1,str)./dt;
%end

if nmax>=1
    etadiff=cell(nmax,1);
    polyargs=cell(nmax,1);
    bcell=cell(nmax,1);

    etadiff{1}=vdiff(eta,dim,str)./dt;
    polyargs{1}=up;

    for n=2:nmax
        etadiff{n}=vdiff(etadiff{n-1},dim,str)./dt;
        polyargs{n}=sqrt(-1)*etadiff{n-1};
    end

    temp=bellpoly(polyargs);
    for n=1:length(temp)
        varargout{n+2}=temp{n};
    end
end

%When JDIM is input, this tells me to output joint quantities
if ~isempty(jdim)
    if nargout==1
        varargout{1}=jointmom(x,jdim);
    elseif nargout==2
        [varargout{1},varargout{2}]=jointmom(x,varargout{2},jdim);
    elseif nargout==3
        [varargout{1},varargout{2},varargout{3}]=jointmom(x,varargout{2},varargout{3},jdim);
    elseif nargout==4
        [varargout{1},varargout{2},varargout{3},varargout{4}]=jointmom(x,varargout{2},varargout{3},varargout{4},jdim);
    end
end

function[varargout]=jointmom(varargin)
%JOINTMOM  Joint instantaneous frequency, bandwidth, and curvature.
%
%   OMEGAX=JOINTMOM(X,OMEGA,DIM) where X is an array of multiple analytic
%   signals and OMEGA is an array of their instantaneous frequencies, gives
%   the joint instaneous frequency OMEGAX averaged over dimension DIM.
%
%   X is presumed to have time oriented in rows.  The output matrix OMEGAX
%   are the same size as X except along dimension DIM, where the output
%   matrices will have length one.  X and OMEGA are the same size.
%
%   [OMEGAX,UPSILONX]=JOINTMOM(X,UPSILON,DIM) also works, where UPSILON
%   are the individual bandwidths, and UPSILONX is the joint quantity.
%   UPSILON is the same size as X and OMEGA.
%
%   Finally [OMEGAX,UPSILONX,XIX]=JOINTMOM(X,UPSILON,XI,DIM) also returns
%   the joint instantaneous curvature XIX given individual curvatures XI.
%
%   For details, see
%
%       Lilly & Olhede (2010), "Bivariate instantaneous frequency and
%            bandwidth", IEEE Trans. Sig. Proc., 58 (2), 591--603.
%
%   See also INSTMOM.
%
%   Usage: [a,om]=jointmom(x,om,dim);
%          [a,om,up]=jointmom(x,om,up,dim);
%          [a,om,up,xi]=jointmom(x,om,xi,dim);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2009--2014 J.M. Lilly --- type 'help jlab_license' for details

dim=varargin{end};
x=varargin{1};
varargin=varargin(2:end-1);

if ~isempty(varargin)
    om=varargin{1};
end
if length(varargin)>1
    upsilon=varargin{2};
end
if length(varargin)>2
   xi=varargin{3};
end

varargout{1}=sqrt(vmean(abs(x).^2,dim));
if nargout>1
    varargout{2}=vmean(om,dim,squared(x));
    ombar=vrep(varargout{2},size(x,dim),dim);
end
if nargout>2
    varargout{3}=sqrt(vmean(abs(upsilon+sqrt(-1)*(om-ombar)).^2,dim,squared(x)));
end
if nargout>3
    varargout{4}=sqrt(vmean(abs(xi+2*sqrt(-1)*upsilon.*(om-ombar)-(om-ombar).^2).^2,dim,squared(x)));
end
if nargout>4
     error('Sorry, INSTMOM only outputs the first two deviation vectors for joint moments.')
end

function[]=instmom_test

load npg2006
use npg2006

[a1,om1,up1,c1]=instmom(cv);
[a2,om2,up2,c2]=instmom(permute(cv,[2 1]),2);

reporttest('INSTMOM moments computed along different dimensions match', aresame([om1 up1 c1],[om2(:) up2(:) c2(:)]));
jointmom_test;

function[]=jointmom_test
load solomon
use solomon

[x,z]=anatrans(x,z);

[ax,omx,upx]=instmom(x);
[az,omz,upz]=instmom(z);

ombar=frac(abs(x).^2.*omx+abs(z).^2.*omz,abs(x).^2+abs(z).^2);
upbar=sqrt(frac(abs(x).^2.*(upx.^2+(omx-ombar).^2)+abs(z).^2.*(upz.^2+(omz-ombar).^2),abs(x).^2+abs(z).^2));

[a,om,up]=instmom([x z],1,2);

reporttest('INSTMOM joint moments using Solomon Islands frequency',aresame(om,ombar,1e-8))
reporttest('INSTMOM joint moments using Solomon Islands bandwidth',aresame(up,upbar,1e-8))

[a2,om2,up2]=instmom(x,z,1);

reporttest('INSTMOM joint moments alternate form',aresame([a om up],[a2 om2 up2]))