function[L,ia,ib,num]=blocklen(x,delta)
%BLOCKLEN Counts the lengths of 'blocks' in an array.
%
%   Suppose X is a column vector which contains blocks of identical
%   values, e.g. X=[0 0 0 1 1 3 2 2 2]';
%
%   L=BLOCKLEN(X) counts the lengths of contiguous blocks containing
%   identical values of X, and returns an array L of size SIZE(X).
%   Each elements of L specifies the length of the block to which the
%   corresponding element of X belongs.
%
%   In the above example, L=[3 3 3 2 2 1 3 3 3]';
%
%   [L,IA,IB,NUM]=BLOCKLEN(X) optionally returns indices IA and IB
%   into the first and last elements, respectively, of each block, as
%   as well as the block number NUM. NUM is the same size as L.
%
%   [...]=BLOCKLEN(X,D) defines the junction between two blocks as
%   locations where ABS(DIFF(X))>D.  Thus D=1 is a 'rate of change'
%   definition, and X=[1 2 3 5 6 10 16 17 18]'; will yield the same
%   result for L as in the previous example.
%
%   See also BLOCKNUM.
%
%   Usage: [L,ia,ib]=blocklen(x);
%   _________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2000--2014 J.M. Lilly --- type 'help jlab_license' for details

% 06.09.04 JML fixed incorrect IA, IB output length

if strcmpi(x,'--t')
  blocklentest;return;
end

if nargin==1
  delta=0;
end

ii=(1:length(x))';

index=find(diff(x)~=delta);
ia=[1;index+1];
ib=[index;length(ii)];

L=zeros(size(ii));
L(ia)=ib-ia+1;
L=cumsum(L);

L0=zeros(size(ii));
ib2=ib(1:end-1);
ia2=ia(1:end-1);
L0(ib2+1)=ib2-ia2+1;
L0=cumsum(L0);
L=L-L0;

if nargout ==4
    num=zeros(size(x));
    num(ia)=1;
    num=cumsum(num);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function[]=blocklentest
x=   [0 0 0 1 1 3 2 2 2]';
y=   [3 3 3 2 2 1 3 3 3]';
num= [1 1 1 2 2 3 4 4 4]';

[y2,ia2,ib2,num2]=blocklen(x);
reporttest('BLOCKLEN with D==0',all(y==y2)&&all(num==num2))

x=[1 2 3 5 6 10 16 17 18]';
[y2,ia2,ib2,num2]=blocklen(x,1);
reporttest('BLOCKLEN with D==1',all(y==y2)&&all(num==num2))


function [CORR, TABLE] = CorrTable(x,vnames,pairwise)
% =======================================================================
% Computes the correlation matrix of a matrix of time series with titles
% =======================================================================
% out = CorrTable(x,vnames)
% -----------------------------------------------------------------------
% INPUT
%   - x: matrix (rows x cols) [double]
%   - vnames: array (1 x cols) with names of the (cols) series [cell]
% -----------------------------------------------------------------------
% OPTIONAL INPUT
%   - pairwise: default 0, change to 1 to compute pairwise correlations
% -----------------------------------------------------------------------
% OUTPUT
%   - CORR: correlation matrix [double]
%   - TABLE: table of correlation matrix with titles [cell]
% -----------------------------------------------------------------------
% EXAMPLE
%   x = rand(50,2);
%   [CORR, TABLE] = CorrTable(x,{'Consumption','Investment'})
% =======================================================================
% VAR Toolbox 3.0
% Ambrogio Cesa-Bianchi
% ambrogiocesabianchi@gmail.com
% March 2015. Updated November 2020
% -----------------------------------------------------------------------

% If no dimension is specified, set it to 1
if ~exist('pairwise','var')
    pairwise = 0;
end

% vnames must be a row vector
if size(vnames,1)>1
    vnames = vnames';
end

% Compute correlation
if pairwise==0
    CORR = corr(x);
elseif pairwise==1
    CORR = corr(x,'rows','pairwise');
end
[r, ~] = size(CORR);

% Place NaNs on the upper triangular
CORR(find(triu(CORR))) = NaN;
jj = 1;
for ii=1:r
    CORR(ii,jj) = 1;
    jj = jj +1;
end

% Save position of NaNs
nans = isnan(CORR);

% Transform table into cell array
TAB = num2cell(CORR);

% Add vnames on top
TAB = [vnames ; TAB];

% Add vnames on the left
aux = [{''} vnames]';
TABLE = [aux TAB];

% Print using mprint
info.cvnames = char(vnames);
info.rvnames = char([{' '} vnames]);
mprint(CORR,info);


function [meantheta,R,sigma,confangle,kappa]=anglemean(theta);
% calculates the mean of angles
%
%    [meantheta,anglestrength,sigma,confangle,kappa]=anglemean(theta);
%
% anglestrength: can be thought of as the inverse variance. [varies between 0 and one]
% sigma: circular standard deviation
% confangle: a 95% confidence angle (confidence of the mean value)
% kappa: an estimate of kappa in the Von Mises distribution
%
% check: http://www.cosy.sbg.ac.at/~reini/huber_dutra_freitas_igarss_01.pdf
%
% Aslak Grinsted 2002
theta=mod(theta(:),2*pi);
n=length(theta);
S=sum(sin(theta));
C=sum(cos(theta));
meantheta=atan2(S,C);

if nargout<2
    return
end
%if ((S>C)&(C>0))
%    meantheta=atan(S/C);
%elseif (C<0)
%    meantheta=atan(S/C)+pi;
%else
%    meantheta=atan(S/C)+2*pi;
%end
%meantheta=mod(meantheta,2*pi);
Rsum=sqrt(S^2+C^2);
R=Rsum/n;

if (R<.53)
    kappa=2*R+R^3+5*R^5/6;
elseif (R<.85)
    kappa=-0.4+1.39*R+0.43/(1-R);
else
    kappa=1/(R^3-4*R^2+3*R);
end

%
%
% circular standard deviation:
sigma=sqrt(-2*log(R));

if nargout<4
    return
end

%conflim=.95;
%a=(length(theta)-Rsum)/chi2pdf()

%this is true if the
chi2=3.841; % = chi2inv(.95,1)
if ((R<.9)&(R>sqrt(chi2/(2*n))))
    confangle=acos(sqrt(2*n*(2*Rsum^2-n*chi2)/(4*n-chi2))/Rsum);
elseif (R>.9)
    confangle=acos(sqrt(n^2-(n^2-Rsum^2)*exp(chi2/n))/Rsum);
else %R is really really small ...
    confangle=pi/2;
    warning('Confidence angle not well determined.')
    %this is not good, but not important because the confidence is so low anyway...
end


function D = eig3(A)
% function D = eig3(A)
%
% Compute in one shot the eigen-values of multiples (3 x 3) matrices
%
% INPUT:
%   A: (3 x 3 x n) array
% OUTPUT:
%   D: (3 x n). EIG3 returns in D(:,k) three eigen-values of A(:,:,k)
%
% See also: CardanRoots, eig2, eig
%
% Author: Bruno Luong <brunoluong@yahoo.com>
% History:
%     Original 20-May-2010

if size(A,1) ~= 3 || size(A,2) ~= 3
    error('A must be [3x3xn] array');
end

A = reshape(A, 9, []).';

P3 = 1;
% Trace
P2 = -(A(:,1)+A(:,5)+A(:,9));
% Principal minors
M11 = A(:,5).*A(:,9) - A(:,8).*A(:,6);
M22 = A(:,9).*A(:,1) - A(:,3).*A(:,7);
M33 = A(:,1).*A(:,5) - A(:,4).*A(:,2);
P1 = (M11 + M22 + M33);
% Determinant
P0 = - A(:,1).*M11 ...
     + A(:,4).*(A(:,2).*A(:,9)-A(:,8).*A(:,3)) ...
     - A(:,7).*(A(:,2).*A(:,6)-A(:,5).*A(:,3));

D = CardanRoots(P3, P2, P1, P0).';

end


function d = DistanceToSO3(mat)
% *** CHAPTER 3: RIGID-BODY MOTIONS ***
% Takes mat: A 3x3 matrix.
% Returns the Frobenius norm to describe the distance of mat from the SO(3)
% manifold.
% Computes the distance from R to the SO(3) manifold using the following
% method:
% If det(mat) <= 0, return a large number.
% If det(mat) > 0, return norm(mat' * mat - I).
% Example Inputs:
%
% clear; clc;
% mat = [1.0, 0.0,   0.0;
%        0.0, 0.1, -0.95;
%        0.0, 1.0,   0.1];
% d = DistanceToSO3(mat)
%
% Output:
% d =
%     0.0884

if det(mat) > 0
	d = norm(mat' * mat - eye(3), 'fro');
else
    d = 1e+9;
end
end


function [gx,gy]=gaussgradient(IM,sigma)
%GAUSSGRADIENT Gradient using first order derivative of Gaussian.
%  [gx,gy]=gaussgradient(IM,sigma) outputs the gradient image gx and gy of
%  image IM using a 2-D Gaussian kernel. Sigma is the standard deviation of
%  this kernel along both directions.
%
%  Contributed by Guanglei Xiong (xgl99@mails.tsinghua.edu.cn)
%  at Tsinghua University, Beijing, China.

%determine the appropriate size of kernel. The smaller epsilon, the larger
%size.
epsilon=1e-2;
halfsize=ceil(sigma*sqrt(-2*log(sqrt(2*pi)*sigma*epsilon)));
size=2*halfsize+1;
%generate a 2-D Gaussian kernel along x direction
for i=1:size
    for j=1:size
        u=[i-halfsize-1 j-halfsize-1];
        hx(i,j)=gauss(u(1),sigma)*dgauss(u(2),sigma);
    end
end
hx=hx/sqrt(sum(sum(abs(hx).*abs(hx))));
%generate a 2-D Gaussian kernel along y direction
hy=hx';
%2-D filtering
gx=imfilter(IM,hx,'replicate','conv');
gy=imfilter(IM,hy,'replicate','conv');

function y = gauss(x,sigma)
%Gaussian
y = exp(-x^2/(2*sigma^2)) / (sigma*sqrt(2*pi));

function y = dgauss(x,sigma)
%first order derivative of Gaussian
y = -x * gauss(x,sigma) / sigma^2;


function [topics, w] = createsyntheticdata (nu, eta, K, W, L)

  % Get the number of documents to generate.
  D = length(L);

  % Generate the word proportions for each topic from the prior.
  topics = zeros(W,K);
  for k = 1:K
    topics(:,k) = dirichletrnd(eta);
  end

  % Generate the documents.
  w = cell(D,1);
  for d = 1:D

    % Generate the topic proportions from the prior.
    t = dirichletrnd(nu)';

    % Generate the topic associated with each word.
    k = sample(t,L(d));

    % Generate the word tokens.
    w{d} = int32(sample_vector(topics,k));
  end


function sp = spdim(n, d, options)
% SPDIM   Computes the number of sparse grid points
%    SP = SPDIM(N,D) Computes the number of points of the sparse
%    grid of dimension D and level N.
%
%    SP = SPDIM(N,D,OPTIONS) Computes the number of points as
%    above, but with default grid type replaced by the grid type
%    specified in OPTIONS, an argument created with the SPSET
%    function. See SPSET for details.
%
%    See also SPINTERP, SPGRID, SPVALS.

% Author : Andreas Klimke
% Version: 1.2
% Date   : November 18, 2007

% Change log:
% V1.0   : September 24, 2003
%          Initial version
% V1.1   : June 15, 2004
%          Added new grid type : Chebyshev distributed nodes
%          (at the extrema of the Chebyshev polynomials)
% V1.2   : November 18, 2007
%          Added new grid type : Gauss-Patterson

% ------------------------------------------------------------
% Sparse Grid Interpolation Toolbox
% Copyright (c) 2006 W. Andreas Klimke, Universitaet Stuttgart
% Copyright (c) 2007-2008 W. A. Klimke. All Rights Reserved.
% See LICENSE.txt for license.
% email: klimkeas@ians.uni-stuttgart.de
% web  : http://www.ians.uni-stuttgart.de/spinterp
% ------------------------------------------------------------

if nargin < 3, options = []; end

if d == 0
	% By definition; useful when computing recurrence formulae such
  % as Bungartz, "Finite Elements of Higher Order on Sparse
  % Grids", p.35, 1998.
	sp = 1;
	return;
end

gridtype = spget(options, 'GridType', 'Clenshaw-Curtis');

if strcmpi(gridtype, 'clenshaw-curtis')
	sp = spdimcc(n,d);
elseif strcmpi(gridtype, 'maximum')
	sp = spdimm(n,d);
elseif strcmpi(gridtype, 'noboundary')
	sp = spdimm(n,d,0);
elseif strcmpi(gridtype, 'chebyshev')
	% number of nodes same as CC-grid
	sp = spdimcc(n,d);
elseif strcmpi(gridtype, 'gauss-patterson')
	% number of nodes same as NB-grid
	sp = spdimm(n,d,0);
else
	error('MATLAB:spinterp:badopt',['Unknown grid type ''' gridtype '''.']);
end


function B=evalBSplinePolys(t,x,k,idx)
%%EVALBSPLINEPOLYS Given a set of at least 2*(k-1) knots in non-decreasing
%                  order (some can be repeated), evaluate all associated
%                  scalar order-k b-spline polynomials that might be
%                  nonzero. These are B_{idx-k+1,k}(x) to B_{idx,k}(x). The
%                  first subscript refers to the knots used in determining
%                  the polynomial and the second subscript refers to the
%                  order of the polynomial. The center index of the knots
%                  is idx and must be k-1<=idx<length(t)-(k-1). These
%                  polynomial evaluations can be used in B-spline
%                  interpolation. This function only gives accurate results
%                  if t(idx)<=x<=t(idx+1). Outside of that range, consider
%                  the function evalBSplinePoly, which evaluates the
%                  polynomials one at a time.
%
%INPUTS: t A 1XnumKnots or numKnotsX1 vector containing the knots. The
%          knots must be sorted in ascending order. It is possible for the
%          knots to be repeated. However, it is required that
%          t(idx)<t(idx+1). If more than the minimum number of knots needed
%          for a given order k are passed, then the extra knots will be
%          ignored. Which knots are "extra" depends on the idx input. These
%          must be real.
%        x The numPointsX1 or 1XnumPoints set of points at which the
%          polynomials should be evaluated. It is assumed that
%          t(idx)<=x<=t(idx+1) for all points. Outside of this range, the
%          results are invalid. These must be real.
%        k Optionally, the order of the B-spline polynomials. If this
%          parameter is omitted, then the default of fix(length(t)/2)+1 are
%          used. This is the highest order that can be used with the given
%          number of knots. This is a positive real value.
%      idx This optional input specifies where in terms of the knots the
%          B-spline polynomials are centered. The default if omitted or an
%          empty matrix is passed is k-1. If t is length 2*(k-1), then idx
%          must be k-1 or be omitted. In general idx is limited to
%          k-1<=idx<length(t)-(k-1).
%
%OUTPUTS: B A kXnumPoints matrix contianing the B-spline polynomials values
%           B_{idx-k+1,k}(x) to B_{idx,k}(x) evaluated at each value in x.
%           These values are real.
%
%B-spline polynomials are discussed in detail in Chapter IX of [1]. The are
%most simply expressed by the recursion starting with B_{idx,0}(x)=1 for
%t(idx)<=x<=t(idx+1) (and is zero otherwise) and then
%B_{idx,k}(x)=((x-t(idx))/(t(idx+k)-t(idx)))*B_{idx,k-1}(x)+((t(idx+k+1)-x)/(t(idx+k+1)-t(idx+1)))*B_{idx+1,k-1}(x)
%An algorithm to efficiently implement such a recursion is described in
%Chapter X of [1] and is implemented here. This function has been
%implemented such that when faced with knots such that t(idx)=t(idx+1), all
%of the B values are zero, because the non-finite term is replaced with
%zero. Except in such an instance of repeated knots, sum(B)==1.
%
%REFERENCES:
%[1] C. de Boor, A Practical Guide to Splines. New York: Springer-Verlag,
%    1978.
%
%April 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

kKnots=fix(length(t)/2)+1;

if(nargin<3||isempty(k))
    k=kKnots;
end

if(kKnots<k)
   error('There are not enough points to obtain B-spline polynomials of the desired order.')
end

if(nargin<4||isempty(idx))
   idx=k-1;
end

if(idx<k-1)
    error('The value of iIdx is too small.')
elseif(idx>length(t)-(k-1))
    error('The value of iIdx is too large.')
end

%This is doing if(any(x<t(idx)|x>t(idx+1)) However, finite precision errors
%can make things slightly off and create unnecessary warnings, so the
%comparisons with a tolerance help to avoid that.
epsMult=4;
if(any(-(x-t(idx))>epsMult*eps(x)|(x-t(idx+1))>epsMult*eps(x)))
    warning('Points are outside of the valid region implied by iIdx. Function results can be inaccurate.')
end

x=x(:)';
numPoints=length(x);

B=zeros(k,numPoints);

deltaR=zeros(k-1,numPoints);
deltaL=zeros(k-1,numPoints);

B(1,:)=1;
for j=1:(k-1)
    deltaR(j,:)=t(idx+j)-x;
    deltaL(j,:)=x-t(idx+1-j);

    recurVal=zeros(1,numPoints);
    for r=1:j
        term=B(r,:)./(deltaR(r,:)+deltaL(j+1-r,:));
        B(r,:)=recurVal+deltaR(r,:).*term;

        recurVal=deltaL(j+1-r,:).*term;
    end
    B(j+1,:)=recurVal;
end

end

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


function int_val = spline_linear_int ( ndata, tdata, ydata, a, b )

%*****************************************************************************80
%
%% SPLINE_LINEAR_INT evaluates the integral of a piecewise linear spline.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NDATA, the number of data points defining the spline.
%
%    Input, real TDATA(NDATA), YDATA(NDATA), the values of the independent
%    and dependent variables at the data points.  The values of TDATA should
%    be distinct and increasing.
%
%    Input, real A, B, the interval over which the integral is desired.
%
%    Output, real INT_VAL, the value of the integral.
%
  int_val = 0.0;

  if ( a == b )
    return;
  end

  a_copy = min ( a, b );
  b_copy = max ( a, b );
%
%  Find the interval [ TDATA(A_LEFT), TDATA(A_RIGHT) ] that contains, or is
%  nearest to, A.
%
  [ a_left, a_right ] = r8vec_bracket ( ndata, tdata, a_copy );
%
%  Find the interval [ TDATA(B_LEFT), TDATA(B_RIGHT) ] that contains, or is
%  nearest to, B.
%
  [ b_left, b_right ] = r8vec_bracket ( ndata, tdata, b_copy );
%
%  If A and B are in the same interval...
%
  if ( a_left == b_left )

    tval = ( a_copy + b_copy ) / 2.0;

    yp = ( ydata(a_right) - ydata(a_left) ) / ...
         ( tdata(a_right) - tdata(a_left) );

    yval = ydata(a_left) + ( tval - tdata(a_left) ) * yp;

    int_val = yval * ( b_copy - a_copy );

    return;
  end
%
%  Otherwise, integrate from:
%
%  A               to TDATA(A_RIGHT),
%  TDATA(A_RIGHT)  to TDATA(A_RIGHT+1),...
%  TDATA(B_LEFT-1) to TDATA(B_LEFT),
%  TDATA(B_LEFT)   to B.
%
%  Use the fact that the integral of a linear function is the
%  value of the function at the midpoint times the width of the interval.
%
  tval = ( a_copy + tdata(a_right) ) / 2.0E+00;

  yp = ( ydata(a_right) - ydata(a_left) ) / ...
       ( tdata(a_right) - tdata(a_left) );

  yval = ydata(a_left) + ( tval - tdata(a_left) ) * yp;

  int_val = int_val + yval * ( tdata(a_right) - a_copy );

  for i_left = a_right : b_left - 1

    tval = ( tdata(i_left+1) + tdata(i_left) ) / 2.0E+00;

    yp = ( ydata(i_left+1) - ydata(i_left) ) / ...
         ( tdata(i_left+1) - tdata(i_left) );

    yval = ydata(i_left) + ( tval - tdata(i_left) ) * yp;

    int_val = int_val + yval * ( tdata(i_left + 1) - tdata(i_left) );

  end

  tval = ( tdata(b_left) + b_copy ) / 2.0E+00;

  yp = ( ydata(b_right) - ydata(b_left) ) / ...
       ( tdata(b_right) - tdata(b_left) );

  yval = ydata(b_left) + ( tval - tdata(b_left) ) * yp;

  int_val = int_val + yval * ( b_copy - tdata(b_left) );

  if ( b < a )
    int_val = -int_val;
  end

  return
end


function wts = cliqf ( nt, t, kind, alpha, beta, a, b, lo )

%*****************************************************************************80
%
%% CLIQF computes a classical quadrature formula, with optional printing.
%
%  Discussion:
%
%    This routine computes all the weights of an interpolatory
%    quadrature formula with
%    1. only simple knots and
%    2. a classical weight function with any valid A and B, and
%    3. optionally prints the knots and weights and a check of the moments.
%
%    To evaluate this quadrature formula for a given function F,
%    call routine EIQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, real T(NT), the knots.
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev Type 1,     (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,+oo)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-oo,+oo)   |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,+oo)     (x-a)^alpha*(x+b)^beta
%    9, Chebyshev Type 2,     (a,b)       ((b-x)*(x-a))^(+0.5)
%
%    Input, real ALPHA, the value of Alpha, if needed.
%
%    Input, real BETA, the value of Beta, if needed.
%
%    Input, real A, B, the interval endpoints.
%
%    Input, integer LO, indicates what is to be done.
%    > 0, compute and print weights and moments check.
%    = 0, compute weights.
%    < 0, compute and print weights.
%
%    Output, real WTS(NT), the weights.
%
  key = 1;
  mlt = zeros(nt,1);
  mlt(1:nt) = 1;
  ndx = zeros(nt,1);

  wts = ciqf ( nt, t, mlt, nt, ndx, key, kind, alpha, beta, a, b, lo );

  return
end


function [A,b,x] = heat(n,kappa)
%HEAT Test problem: inverse heat equation.
%
% [A,b,x] = heat(n,kappa)
%
% A first kind Volterra integral equation with [0,1] as
% integration interval.  The kernel is K(s,t) = k(s-t) with
%    k(t) = t^(-3/2)/(2*kappa*sqrt(pi))*exp(-1/(4*kappa^2*t)) .
% Here, kappa controls the ill-conditioning of the matrix:
%    kappa = 5 gives a well-conditioned problem
%    kappa = 1 gives an ill-conditioned problem.
% The default is kappa = 1.
%
% An exact soltuion is constructed, and then the right-hand side
% b is produced as b = A*x.

% Reference: A. S. Carasso, "Determining surface temperatures from interior
% observations", SIAM J. Appl. Math. 42 (1982), 558-574.  See also L. Elden,
% "The numerical solution of a non-characteristic Cauchy problem for a
% parabolic equation"; in P. Deuflhand and E. Hairer (Eds.), "Numerical
% Treatment of Inverse Problems in Differential and Integral Equations",
% Birkhauser, 1983.

% Discretization by means of simple quadrature (midpoint rule).

% Per Christian Hansen, IMM, Sep, 13, 2001.

% Set default kappa.
if (nargin==1), kappa = 1; end

% Initialization.
h = 1/n; t = h/2:h:1;
c = h/(2*kappa*sqrt(pi));
d = 1/(4*kappa^2);

% Compute the matrix A.
k = c*t.^(-1.5).*exp(-d./t);
r = zeros(1,length(t)); r(1) = k(1); A = toeplitz(k,r);

% Compute the vectors x and b.
if (nargout>1)
  x = zeros(n,1);
  for i=1:n/2
    ti = i*20/n;
    if (ti < 2)
      x(i) = 0.75*ti^2/4;
    elseif (ti < 3)
      x(i) = 0.75 + (ti-2)*(3-ti);
    else
      x(i) = 0.75*exp(-(ti-3)*2);
    end
  end
  x(n/2+1:n) = zeros(1,n/2);
  b = A*x;
end


function a = dif2_inverse ( n )

%*****************************************************************************80
%
%% DIF2_INVERSE returns the inverse of the DIF2 matrix.
%
%  Formula:
%
%    if ( I <= J )
%      A(I,J) = I * (N-J+1) / (N+1)
%    else
%      A(I,J) = J * (N-I+1) / (N+1)
%
%  Example:
%
%    N = 4
%
%            4 3 2 1
%    (1/5) * 3 6 4 2
%            2 4 6 3
%            1 2 3 4
%
%  Properties:
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is persymmetric: A(I,J) = A(N+1-J,N+1-I).
%
%    det ( A ) = 1 / ( N + 1 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

  for i = 1 : n
    for j = 1 : n
      if ( i <= j )
        a(i,j) = ( i * ( n - j + 1 ) ) / ( n + 1 );
      else
        a(i,j) = ( j * ( n - i + 1 ) ) / ( n + 1 );
      end
    end
  end

  return
end


function varargout = gabrielGraph(pts)
%GABRIELGRAPH  Gabriel Graph of a set of points
%
%   EDGES = gabrielGraph(PTS)
%   Computes the Gabriel graph of the input set of points PTS. The Gabriel
%   graph is based on the euclidean Delaunay triangulation, and keeps only
%   edges whose circumcircle does not contain any other input point than
%   the edge extremities.
%
%   [NODES EDGES] = gabrielGraph(PTS)
%   Also returns the initial set of points;
%
%   Example
%     pts = rand(100, 2);
%     edges = gabrielGraph(pts);
%     figure; drawPoint(pts);
%     hold on; axis([0 1 0 1]); axis equal;
%     drawGraph(pts, edges);
%
%   See also
%     drawGraph, delaunayGraph
%

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

% compute Delaunay triangulation
if verLessThan('matlab', '8.1')
    % Code for versions before R2013a
    dt = DelaunayTri(pts); %#ok<DDELTRI>
else
    % Code for versions R2013a and later
    dt = delaunayTriangulation(pts);
end

% extract edges (N-by-2 array)
eds = dt.edges();

% radius of the circule circumscribed to each edge
rads = edgeLength([pts(eds(:,1), :) pts(eds(:,2), :)]) / 2;

% extract middle point of each edge
midPts = midPoint(pts(eds(:,1), :), pts(eds(:,2), :));

% distance between midpoints and all points
% closest points should be edge vertices
dists = minDistancePoints(midPts, pts);

% geometric tolerance (adapted to point set extent)
tol = max(max(pts) - min(pts)) * eps;

% keep only edges whose circumcircle does not contain any other point
keep = dists >= rads - tol;
edges = eds(keep, :);

if nargout < 2
    varargout = {edges};
else
    varargout = {pts, edges};
end


function [ x, seed ] = triangle_sample ( a, b, c, seed )

%*****************************************************************************80
%
%% TRIANGLE_SAMPLE samples the Triangle PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, C, the parameters of the PDF.
%    A <= B <= C and A < C.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real X, a sample of the PDF.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  [ cdf, seed ] = r8_uniform_01 ( seed );

  x = triangle_cdf_inv ( cdf, a, b, c );

  return
end


function fX=SchurMatFunEval(f,X)
%%SCHURMATFUNEVAL Evaluate the matrix function f(X), where the function f
%         is a function that has a Taylor series representation using the
%         Schur-Parlett method. In this approach, f(x) only needs to be
%         evaluated on _scalar_ quantities. Thus, this function can be used
%         to turn scalar functions into matrix functions. Matrix functions
%         with a Taylor series expansions satisfy the identities
%         X*f(X)=f(X)*X and f(inv(B)*X*B)=B*f(X)*inv(B) and include
%         functions such as the matrix exponential and square root.
%
%INPUTS: f A function handle that takes a scalar input and returns a scalar
%          output.
%        X The real or complex nXn matrix that should be evaluated via the
%          function f.
%
%OUTPUTS: fX The value f(X), where the function f applied to scalar terms
%            is applied to the matrix X. This is not the same as applying f
%            to every scalar element in X.
%
%This function implements Algorithm 9.1.1 of Chapter 9.1.4 of [1].
%
%EXAMPLE:
%Here, we show that the result agrees with the mpow function to take a
%matrix square root.
% X=randn(6,6);
% f=@(x)sqrt(x);
% fX=SchurMatFunEval(f,X);
% diffVal=fX-mpower(X,1/2)
%One will see that the entries in diffVal are all on the order of 1e-14 or
%less, indicating that the two are probably equal within finite precision
%bounds.
%
%REFERENCES:
%[1] G. H. Golub and C. F. Van Loan, Matrix Computations, 4th ed.
%    Baltimore: Johns Hopkins University Press, 2013.
%
%January 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

n=length(X);

%We must use the 'complex' option or else T is not guaranteed to be
%upper triangular.
[Q,T]=schur(X,'complex');

%The diagonal terms.
F=zeros(n,n);
for i=1:n
    F(i,i)=f(T(i,i));
end

for p=1:(n-1)
    for i=1:(n-p)
        j=i+p;
        s=T(i,j)*(F(j,j)-F(i,i));
        for k=(i+1):(j-1)
            s=s+T(i,k)*F(k,j)-F(i,k)*T(k,j);
        end
        F(i,j)=s/(T(j,j)-T(i,i));
    end
end

if(isreal(X))
    fX=real(Q*F*Q');
else
    fX=Q*F*Q';
end
end

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


function [ x, seed ] = beta_binomial_sample ( a, b, c, seed )

%*****************************************************************************80
%
%% BETA_BINOMIAL_SAMPLE samples the Beta Binomial CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, parameters of the PDF.
%    0.0D+00 < A,
%    0.0D+00 < B.
%
%    Input, integer C, a parameter of the PDF.
%    0 <= C.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, integer X, a sample of the PDF.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  [ cdf, seed ] = r8_uniform_01 ( seed );

  x = beta_binomial_cdf_inv ( cdf, a, b, c );

  return
end


function r8plu_mul_test ( )

%*****************************************************************************80
%
%% R8PLU_MUL_TEST tests R8PLU_MUL;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2009
%
%  Author:
%
%    John Burkardt
%
  n = 5;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8PLU_MUL_TEST\n' );
  fprintf ( 1, '  R8PLU_MUL computes the product A*x=b\n' );
  fprintf ( 1, '  using the compressed PLU factors of A.\n' );
  fprintf ( 1, '  Using initial random number seed = %d\n', seed );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Matrix order N = %d\n', n );
%
%  Set the matrix.
%
  [ a, seed ] = r8mat_uniform_01 ( n, n, seed );

  r8mat_print ( n, n, a, '  The matrix A:' );
%
%  Set the right hand side B1.
%
  for i = 1 : n
    x(i) = i;
  end

  b(1:n) = a(1:n,1:n) * x(1:n)';

  r8vec_print ( n, b, '  The right hand side B (computed from A):' );
%
%  Factor the matrix.
%
  [ pivot, lu, info ] = r8mat_to_r8plu ( n, a );
%
%  Compute the matrix-vector product.
%
  b = r8plu_mul ( n, pivot, lu, x );

  r8vec_print ( n, b, '  The right hand side B (computed from PLU):' );

  return
end


 function y = fractional_delay(x, delay)
%function y = fractional_delay(x, delay)
%|
%| given N samples x[n] of a real, periodic, band-limited signal x(t),
%| compute sinc interpolated samples of delayed signal y(t) = x(t - delay)
%| each column of x can be shifted by a different amount if delay is a vector.
%| in
%|	x	[N L]
%|	delay	[L]
%| out
%|	y	[N L]
%|
%| see laakso:96:stu for more ideas.
%|
%| Copyright 2003-11-1, Jeff Fessler, The University of Michigan
%| Extend to allow x to have multiple columns, 2003-11-2, Yingying Zhang.

if nargin < 1, ir_usage, end
if streq(x, 'test'), fractional_delay_test, return, end
if size(x,2) ~= length(delay)
	error 'Need size(x) = [N L]; length(delay) = L'
end

dims = size(x);
N = dims(1);
L = dims(2);
if length(dims) > 2, error 'x must be 1d or 2d', end
X = fft(x); % fft of each column

% it is important to choose the k indices appropriately!
if rem(N,2) % odd
	k = [-(N-1)/2:(N-1)/2]';
else
	k = [-N/2:(N/2-1)]';
end

c = exp(-1i * 2*pi/N * k * delay(:)'); % [N L] outer product

if ~rem(N,2) % even
	mid = 1;
	c(mid,:) = real(c(mid,:)); % this is the other key trick!
end

c = ifftshift(c, 1); % ifftshift differs from fftshift for odd N!

Y = X .* c;
y = ifft(Y);

% fractional_delay_test
% self test
function fractional_delay_test

Nlist = [5 6];
im clf, pl = @(i) subplot(240+i);
for ii=1:2
	N = Nlist(ii);
	n = [0:(N-1)]';
	xt = @(t, N) sinc_periodic(t, N);
	x = xt(n, N);
	xx = [x x];
	delay = [3.7; -2.2];
	y = fractional_delay(xx, delay);

	t = linspace(0,2*N,401);
	yt1 = xt(t-delay(1),N);
	yt2 = xt(t-delay(2),N);

	if im
	pl(0+ii), plot(t, xt(t,N), '-', n, xx(:,1), 'o')
	axis([0 2*N -0.4 1.1]), titlef('N=%d 1st input', N)
	pl(2+ii), plot(t, xt(t,N), '-', n, xx(:,2), 'o')
	axis([0 2*N -0.4 1.1]), titlef('N=%d 2nd input', N)
	pl(4+ii), plot(t, yt1, '-', n, real(y(:,1)), 's', n, imag(y(:,1)), '.')
	axis([0 2*N -0.4 1.1]), titlef('delay=%g 1st input',delay(1))
	pl(6+ii), plot(t, yt2, '-', n, real(y(:,2)), 's', n, imag(y(:,2)), '.')
	axis([0 2*N -0.4 1.1]), titlef('delay=%g 2nd input',delay(2))
	end
end


%% Machine Learning Online Class
%  Exercise 1: Linear regression with multiple variables
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the
%  linear regression exercise.
%
%  You will need to complete the following functions in this
%  exericse:
%
%     warmUpExercise.m
%     plotData.m
%     gradientDescent.m
%     computeCost.m
%     gradientDescentMulti.m
%     computeCostMulti.m
%     featureNormalize.m
%     normalEqn.m
%
%  For this part of the exercise, you will need to change some
%  parts of the code below for various experiments (e.g., changing
%  learning rates).
%

%% Initialization

%% ================ Part 1: Feature Normalization ================

%% Clear and Close Figures
clear all; close all; clc

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

%% Load Data
data = csvread('ex1data2.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);

% Print out some data points
fprintf('First 10 examples from the dataset: \n');
fprintf(' x = [%.0f %.0f], y = %.0f \n', [X(1:10,:) y(1:10,:)]');

fprintf('Program paused. Press enter to continue.\n');
pause;

% Scale features and set them to zero mean
fprintf('Normalizing Features ...\n');

[X mu sigma] = featureNormalize(X);

% Add intercept term to X
X = [ones(m, 1) X];

%% ================ Part 2: Gradient Descent ================

% ====================== YOUR CODE HERE ======================
% Instructions: We have provided you with the following starter
%               code that runs gradient descent with a particular
%               learning rate (alpha).
%
%               Your task is to first make sure that your functions -
%               computeCost and gradientDescent already work with
%               this starter code and support multiple variables.
%
%               After that, try running gradient descent with
%               different values of alpha and see which one gives
%               you the best result.
%
%               Finally, you should complete the code at the end
%               to predict the price of a 1650 sq-ft, 3 br house.
%
% Hint: By using the 'hold on' command, you can plot multiple
%       graphs on the same figure.
%
% Hint: At prediction, make sure you do the same feature normalization.
%

fprintf('Running gradient descent ...\n');

% Choose some alpha value
alpha = 0.3;
num_iters = 100;

% Init Theta and Run Gradient Descent
theta = zeros(3, 1);
[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters);

% Plot the convergence graph
figure;
plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2);
xlabel('Number of iterations');
ylabel('Cost J');

% Display gradient descent's result
fprintf('Theta computed from gradient descent: \n');
fprintf(' %f \n', theta);
fprintf('\n');

% Estimate the price of a 1650 sq-ft, 3 br house
% ====================== YOUR CODE HERE ======================
% Recall that the first column of X is all-ones. Thus, it does
% not need to be normalized.
price = 0; % You should change this

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

fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ...
         '(using gradient descent):\n $%f\n'], price);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% ================ Part 3: Normal Equations ================

fprintf('Solving with normal equations...\n');

% ====================== YOUR CODE HERE ======================
% Instructions: The following code computes the closed form
%               solution for linear regression using the normal
%               equations. You should complete the code in
%               normalEqn.m
%
%               After doing so, you should complete this code
%               to predict the price of a 1650 sq-ft, 3 br house.
%

%% Load Data
data = csvread('ex1data2.txt');
X = data(:, 1:2);
y = data(:, 3);
m = length(y);

% Add intercept term to X
X = [ones(m, 1) X];

% Calculate the parameters from the normal equation
theta = normalEqn(X, y);

% Display normal equation's result
fprintf('Theta computed from the normal equations: \n');
fprintf(' %f \n', theta);
fprintf('\n');

% Estimate the price of a 1650 sq-ft, 3 br house
% ====================== YOUR CODE HERE ======================
price = 0; % You should change this

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

fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ...
         '(using normal equations):\n $%f\n'], price);


function dist = imDistanceMap(img, varargin)
%IMDISTANCEMAP Compute chamfer distance using scanning algorithm
%
%   Usage:
%   RES = imDistanceMap(BIN);
%   where BIN is a binary images, computes for each foreground pixel the
%   minimum distance to the background.
%   The function propagates distances to orthogonal and diagonal pixels,
%   using weights equal to 1 for orthogonal pixels, and sqrt(2) for
%   diagonal markers. The result RES is given in a double array the same
%   size as BIN.
%
%   RES = imDistanceMap(LBL);
%   The function can be applied to a label image LBL, where the values of
%   LBL correspond to region indices. In that case, the result RES
%   corresponds to the superposition of the results on computed on each
%   label.
%
%
%   Methods:
%   The function uses scanning algorithm, by applying one forward and one
%   backward scan.
%
%   RES = imDistanceMap(..., WEIGHTS);
%   Specifies different weights for computing distance between 2 pixels.
%   WEIGHTS is a 2 elements array, with WEIGHTS(1) corresponding to the
%   distance between two orthonal pixels, and WEIGHTS(2) corresponding to
%   the distance between two diagonal pixels.
%   Possible choices
%   WEIGHTS = [1 sqrt(2)]   -> quasi-euclidean distance
%   WEIGHTS = [1 Inf]       -> "Manhattan" or "cityblock" distance
%   WEIGHTS = [1 1]         -> "Chessboard" distance
%   WEIGHTS = [3 4]         -> Borgerfors' weights
%   WEIGHTS = [5 7]         -> close approximation of sqrt(2)
%   WEIGHTS = [5 7 11]      -> Uses an additional weight for chess-knight
%                              shifts around each pixel( default)
%
%   Note: when specifying weights, the result has the same class/data type
%   than the array of weights. It is possible to balance between speed and
%   memory usage:
%   - if weights are double (the default), the memory usage is larger, but
%       the result can be given in pixel units
%   - if weights are integer (for Borgefors weights, for example), the
%       memory usage is reduced, but representation limit of datatype can
%       be easily reached. One needs to divide by the first weight to get
%       result comparabale with natural distances.
%       For uint8, using [3 4] weigths, the maximal computable distance is
%       around 255/3 = 85 pixels. Using 'int16'  seems to be a good
%       tradeoff, the maximal distance with [3 4] weights is around 11000
%       pixels.
%
%   RES = imDistanceMap(..., 'normalize', TF);
%   If TF is true, normalizes the resulting map by the first weight.
%   Default is true.
%
%   RES = imDistanceMap(..., 'verbose', true);
%   Displays info on iterations.
%
%   Examples:
%   % Computes distance map on closed circles, with Borgefors Metric
%     img = imread('circles.png');
%     se = strel('disk', 6);
%     img2 = imclose(img, se);
%     dist = imDistanceMap(img2, [3 4]);
%     imshow(dist, []); colormap jet;
%
%   % uses the examples from bwdist with different distances
%     img = ones(255, 255);
%     img(126, 126) = 0;
%     res1 = imDistanceMap(img);
%     res2 = imDistanceMap(img, [1 inf]);
%     res3 = imDistanceMap(img, [1 1]);
%     res4 = imDistanceMap(img, [1 1.5]);
%     figure;
%     subplot(221); subimage(mat2gray(res1));
%     hold on; imcontour(res1); title('quasi-euclidean');
%     subplot(222); subimage(mat2gray(res2));
%     hold on; imcontour(res2); title('city-block');
%     subplot(223); subimage(mat2gray(res3));
%     hold on; imcontour(res3); title('chessboard');
%     subplot(224); subimage(mat2gray(res4));
%     hold on; imcontour(res4); title('approx euclidean');
%
%
%   See also:
%     bwdist, imGeodesicDistanceMap, imSeparateParticles
%

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% Created: 2012-08-20,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2012 INRA - Cepia Software Platform.

%   HISTORY
%   2010-08-25 fix memory allocation for large images, add vebosity option
%   2012-08-20 adapt imChamferDistance to create imDistanceMap
%   2018-02-22 add management of contiguous labels, and of three weights

%% Process input arguments

% default weights for orthogonal or diagonal
weights = [5 7 11];

normalize = true;

% extract user-specified weights
if ~isempty(varargin)
    weights = varargin{1};
    varargin(1) = [];
end

% extract verbosity option
verbose = false;
if length(varargin) > 1
    varName = varargin{1};
    if ~ischar(varName)
        error('Require options as name-value pairs');
    end

    if strcmpi(varName, 'normalize')
        normalize = varargin{2};
    elseif strcmpi(varName, 'verbose')
        verbose = varargin{2};
    else
        error(['unknown option: ' varName]);
    end
end

%% Initialisations

% determines type of output from type of weights
outputType = class(weights);

% small check up to avoid degenerate cases
w1 = weights(1);
w2 = weights(2);
if w2 < w1
    w2 = 2 * w1;
end

% shifts in directions i and j for (1) forward and (2) backward iterations
if length(weights) == 2
    nShifts = 4;
    di1 = [-1 -1 -1  0];
    dj1 = [-1  0  1 -1];
    di2 = [+1 +1 +1  0];
    dj2 = [-1  0  1 +1];
    ws =  [w2 w1 w2 w1];

elseif length(weights) == 3
    nShifts = 8;
    w3 = weights(3);
    di1 = [-2 -2 -1 -1 -1 -1 -1  0];
    dj1 = [-1 +1 -2 -1  0  1 +2 -1];
    di2 = [+2 +2 +1 +1 +1 +1 +1  0];
    dj2 = [-1 +1 +2 +1  0 -1 -2 +1];
    ws =  [w3 w3 w3 w2 w1 w2 w3 w1];
end

% allocate memory for result
dist = ones(size(img), outputType);

% init result: either max value, or 0 for marker pixels
if isinteger(w1)
    dist(:) = intmax(outputType);
else
    dist(:) = inf;
end
dist(~img) = 0;

% size of image
[D1, D2] = size(img);

%% Forward iteration

if verbose
    disp('Forward iteration %d');
end

for i = 1:D1
    for j = 1:D2
        % computes only for pixels within a region
        if img(i, j) == 0
            continue;
        end

        % compute minimal propagated distance
        newVal = dist(i, j);
        for k = 1:nShifts
            % coordinate of neighbor
            i2 = i + di1(k);
            j2 = j + dj1(k);

            % check bounds
            if i2 < 1 || i2 > D1 || j2 < 1 || j2 > D2
                continue;
            end

            % compute new value
            if img(i2, j2) == img(i, j)
                % neighbor in same region
                % -> add offset weight to neighbor distance
                newVal = min(newVal, dist(i2, j2) + ws(k));
            else
                % neighbor in another region
                % -> initialize with the offset weight
                newVal = min(newVal, ws(k));
            end

        end

        % if distance was changed, update result
        dist(i,j) = newVal;
    end

end % iteration on lines

%% Backward iteration

if verbose
    disp('Backward iteration');
end

for i = D1:-1:1
    for j = D2:-1:1
        % computes only for foreground pixels
        if img(i, j) == 0
            continue;
        end

        % compute minimal propagated distance
        newVal = dist(i, j);
        for k = 1:nShifts
            % coordinate of neighbor
            i2 = i + di2(k);
            j2 = j + dj2(k);

            % check bounds
            if i2 < 1 || i2 > D1 || j2 < 1 || j2 > D2
                continue;
            end

            % compute new value
            if img(i2, j2) == img(i, j)
                % neighbor in same region
                % -> add offset weight to neighbor distance
                newVal = min(newVal, dist(i2, j2) + ws(k));
            else
                % neighbor in another region
                % -> initialize with the offset weight
                newVal = min(newVal, ws(k));
            end

        end

        % if distance was changed, update result
        dist(i,j) = newVal;
    end

end % line iteration

if normalize
    dist(dist>0) = dist(dist>0) / w1;
end


function Pvalue=myfisher33(x)
%P=MYFISHER33(X)- Fisher's Exact Probability Test on 3x3 matrix.
%Fisher's exact test of 3x3 contingency tables permits calculation of
%precise probabilities in situation where, as a consequence of small cell
%frequencies, the much more rapid normal approximation and chi-square
%calculations are liable to be inaccurate. The Fisher's exact test involves
%the computations of several factorials to obtain the probability of the
%observed and each of the more extreme tables. Factorials growth quickly,
%so it's necessary use logarithms of factorials. This computations is very
%easy in Matlab because x!=gamma(x+1) and log(x!)=gammaln(x+1). This
%function is now fully vectorized to speed up the computation.
% Syntax: 	myfisher33(x)
%
%     Inputs:
%           X - 3x3 data matrix
%     Outputs:
%           P - 2-tailed p-value
%
%   Example:
%
%                A   B   C
%           -------------------
%      X         4   1   1
%           -------------------
%      Y         1   3   1
%           -------------------
%      Z         0   1   5
%           -------------------
%
%   x=[4 1 1; 1 3 1; 0 1 5];
%
%   Calling on Matlab the function:
%             myfisher33(x)
%
% 3x3 matrix Fisher's exact test: 301 tables were evaluated
% -------------------------------------------------------
% 2-tail p-value = 0.0322177822
% -------------------------------------------------------
%
%           Created by Giuseppe Cardillo
%           giuseppe.cardillo-edta@poste.it
%
% To cite this file, this would be an appropriate format:
% Cardillo G. (2007) MyFisher33: a very compact routine for Fisher's exact
% test on 3x3 matrix
% http://www.mathworks.com/matlabcentral/fileexchange/15482

%Input Error handling
if ~isequal(size(x),[3 3])
    error('Input matrix must be a 3x3 matrix')
end
if ~all(isfinite(x(:))) || ~all(isnumeric(x(:)))
    error('Warning: all X values must be numeric and finite')
end
if ~isequal(x(:),round(x(:)))
    error('Warning: X data matrix values must be whole numbers')
end

Rs=sum(x,2); %rows sum
Cs=sum(x); %columns sum
N=sum(Rs); %Number of observations

%If necessed, rearrange matrix
if ~issorted(Cs)
    [Cs,ind]=sort(Cs);
    x=x(:,ind);
end
if ~issorted(Rs)
    [Rs,ind]=sort(Rs);
    x=x(ind,:);
end

Kf=sum(gammaln([Rs' Cs]+1))-gammaln(N+1); %The costant factor K=log(prod(R!)*prod(C!)/N!)
zf=gammaln(x+1); %compute log(x!)
op=exp(Kf-sum(zf(:))); %compute the p-value of the observed matrix

% First step: Compute all possible primary tables (play on the first two
% degrees of freedom)
I=0:1:min(Rs(1),Cs(1)); %all possible values of X(1,1)
J=min(Rs(1)-I,Cs(2)); %max value of X(1,2) given X(1,1)
et=sum(J+1); %primary tables to evaluate
m1=zeros(et,3); %matrix preallocation
%set the arrays of indices
idxAstop=cumsum(J+1);
idxAstart=[1 idxAstop(1:end-1)+1];
%Build-up the matrix
for K=1:length(I)
    m1(idxAstart(K):idxAstop(K),1)=I(K);
    m1(idxAstart(K):idxAstop(K),2)=0:1:J(K);
end
%Put all the possible values of X(1,3) given X(1,1) and X(1,2)
m1(:,3)=Rs(1)-sum(m1(:,1:2),2);

%Second step:
%Compute all possible secondary tables (play on the second two
% degrees of freedom)
m2=repmat(Cs,et,1);
Cs2=m2-m1; %Residual sum of rows given the first row
L=min(Rs(2),Cs2(:,1)); %find the max values of X(2,1) given X(1,1) and X(1,2)
KK=max(L)+1; %Remember that zero is a possible value...
%matrix preallocation
UpB=zeros(et,KK);
for K=1:KK
%find the max values of X(2,2) given X(1,1), X(1,2) and X(2,2)
    UpB(:,K)=min(Cs2(:,2),Rs(2)-(K-1));
end
%matrix preallocation
LoB=zeros(et,KK); InT=repmat(NaN,et,KK);
sectab=zeros(1,et); %array preallocation
for K=1:et
    %find the min values of X(2,2) given X(1,1), X(1,2) and X(2,2)
    z=L(K)+1;
    a=0:1:L(K);
    LoB(K,1:z)=max(0,Rs(2)-a-Cs2(K,3));
    %Compute the range of variation of X(2,2)
    InT(K,1:z)=UpB(K,1:z)-LoB(K,1:z)+1;
    %Compute how many secondary tables are generated from each primary table
    sectab(K)=sum(InT(K,1:z),2);
end
et2=sum(sectab); %total tables to evaluate
%Matrix and vector preallocation
M=zeros(et2,9);
%Set indices
InT=InT'; InT(isnan(InT))=[];
idxAstop=cumsum(InT(:))';
idxAstart=[1 idxAstop(1:end-1)+1];
idxBstop=cumsum(sectab); idxBstart=[1 idxBstop(1:end-1)+1];
%Build-up the secondary tables
z=1;
for K=1:et
    %Expand the primary table
    M(idxBstart(K):idxBstop(K),1:3)=repmat(m1(K,:),sectab(K),1);
    I=0:1:L(K); %values of X(2,1) given X(1,1) and X(1,2)
    %Put them in the matrix in the correct position
    for J=1:length(I)
        M(idxAstart(z):idxAstop(z),4)=I(J);
        M(idxAstart(z):idxAstop(z),5)=LoB(K,J):1:UpB(K,J); %values of X(2,2) given X(1,1), X(1,2) and X(2,2)
        z=z+1;
    end
end
%Complete the table
M(:,6)=Rs(2)-sum(M(:,4:5),2);
M(:,7:9)=repmat(Cs,et2,1)-M(:,1:3)-M(:,4:6);
zf=gammaln(M+1); %compute log(x!)
np=exp(Kf-sum(zf,2)); %compute the p-value of each possible matrix
P=sum(np(np<op));

%display results
tr=repmat('-',1,55); %Set up the divisor
fprintf('3x3 matrix Fisher''s exact test: %0.0f tables were evaluated\n',et2)
disp(tr)
fprintf('2-tail p-value = %0.10f\n',P);
disp(tr)
if nargout
    Pvalue=P;
end


function [Rot] = AxisAngle2Rot(axisAngle)

    theta = norm(axisAngle, 2);

    nx = axisAngle / theta;

    nx = [    0  -nx(3)  nx(2);
           nx(3)     0  -nx(1);
          -nx(2)  nx(1)     0 ];

    Rot = eye(3) + sin(theta) * nx + (1-cos(theta))*nx^2;


function sphere_stereograph_test03 ( )

%*****************************************************************************80
%
%% SPHERE_STEREOGRAPH_TEST03 checks that the two functions are inverses.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 November 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPHERE_STEREOGRAPH_TEST03\n' );
  fprintf ( 1, '  SPHERE_STEREOGRAPH2 maps from sphere to plane.\n' );
  fprintf ( 1, '  SPHERE_STEREOGRAPH2_INVERSE is the inverse map.\n' );
  fprintf ( 1, '  Check that these two functions are inverses.\n' );

  m = 3;
  n = 100;
  seed = 123456789;

  [ focus, seed ] = r8vec_uniform_01 ( m, seed );
  [ center, seed ] = r8vec_uniform_01 ( m, seed );
  r = norm ( focus - center );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Using radius = %f\n', r );
  fprintf ( 1, '  center = (%f,%f,%f)\n', center );
  fprintf ( 1, '  focus =  (%f,%f,%f)\n', focus );
%
%  Check #1.
%
  p1 = uniform_on_sphere01_map ( m, n, seed );
  p1 = repmat ( center, 1, n ) + r * p1;

  q = sphere_stereograph2 ( p1, focus, center );

  p2 = sphere_stereograph2_inverse ( q, focus, center );

  dif = sqrt ( sum ( ( p1 - p2 ).^2, 1 ) );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Map points from sphere to plane to sphere.\n' );
  fprintf ( 1, '  Maximum difference for %d points was %f\n', n, max ( dif ) );
%
%  Check #2.
%  We have to work hard to get random points on the plane, since
%  all we know to begin with is the point of tangency and the normal.
%
  tang = 2 * center - focus;
  normal = center - focus;
  [ pr, pq ] = plane_normal_basis_3d ( tang, normal );
  q1 = zeros(m,n);
  alpha = rand(1,n);
  beta = rand(1,n);
  tt = repmat ( tang, 1, n );

  q1(1:m,1:n) = tt + pr(1:m,1) * alpha(1,1:n) + pq(1:m,1) * beta(1,1:n);
  p = sphere_stereograph2_inverse ( q1, focus, center );
  q2 = sphere_stereograph2 ( p, focus, center );

  dif = sqrt ( sum ( ( q1 - q2 ).^2, 1 ) );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Map points from plane to sphere to plane.\n' );
  fprintf ( 1, '  Maximum difference for %d points was %f\n', n, max ( dif ) );

  return
end


function centroids = computeCentroids(X, idx, K)
%COMPUTECENTROIDS returs the new centroids by computing the means of the
%data points assigned to each centroid.
%   centroids = COMPUTECENTROIDS(X, idx, K) returns the new centroids by
%   computing the means of the data points assigned to each centroid. It is
%   given a dataset X where each row is a single data point, a vector
%   idx of centroid assignments (i.e. each entry in range [1..K]) for each
%   example, and K, the number of centroids. You should return a matrix
%   centroids, where each row of centroids is the mean of the data points
%   assigned to it.
%

% Useful variables
[m n] = size(X);

% You need to return the following variables correctly.
centroids = zeros(K, n);

% ====================== YOUR CODE HERE ======================
% Instructions: Go over every centroid and compute mean of all points that
%               belong to it. Concretely, the row vector centroids(i, :)
%               should contain the mean of the data points assigned to
%               centroid i.
%
% Note: You can use a for-loop over the centroids to compute this.
%

for k=1:K
    % use logical arrays for indexing
    % see http://www.mathworks.com/help/matlab/math/matrix-indexing.html#bq7egb6-1
    indexes = idx == k;
    centroids(k, :) = mean(X(indexes, :));
end;

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

end


function polynomial_scale_test ( )

%*****************************************************************************80
%
%% POLYNOMIAL_SCALE_TEST tests POLYNOMIAL_ScALE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 October 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'POLYNOMIAL_SCALE_TEST\n' );
  fprintf ( 1, '  POLYNOMIAL_SCALE scales a polynomial by a multiplier S.\n' );

  m = 3;
  o = 6;
  c = [ 7.0, - 5.0, 9.0, 11.0, 0.0, - 13.0 ];
  e = [ 1, 2, 4, 5, 12, 33 ];

  fprintf ( 1, '\n' );
  title = '  P(X) = ';
  polynomial_print ( m, o, c, e, title );

  s = - 0.5;
  fprintf ( 1, '\n' );
  fprintf ( '  Apply scale factor S = %g\n', s );
  [ o, c, e ] = polynomial_scale ( s, m, o, c, e );

  fprintf ( 1, '\n' );
  title = '  S * P(X) = ';
  polynomial_print ( m, o, c, e, title );

  return
end


function a = hilbert_fun ( m, n )

%*****************************************************************************80
%
%% HILBERT_FUN assembles a copy of the Hilbert matrix using SPMD workers.
%
%  Discussion:
%
%    The matrix is assembled in blocks.  Each SPMD worker builds one
%    block, and the client worker assembles the pieces into a single
%    array.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 February 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of the matrix
%    to be generated.
%
%    Output, real A(M,N), the Hilbert matrix.
%
  spmd
    ilo = 1;
    ihi = m;
    jlo = floor ( ( ( labindex ( ) - 1 ) * n ) / numlabs ( ) ) + 1;
    jhi = floor ( (   labindex ( )       * n ) / numlabs ( ) );
    a_block = hilbert_block ( ilo, jlo, ihi, jhi );
  end
%
%  The client collects the stripes into a single matrix.
%
  a = [ a_block{:} ];

  return
end
function a = hilbert_block ( ilo, jlo, ihi, jhi )

%*****************************************************************************80
%
%% HILBERT_BLOCK returns a block of the Hilbert matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 February 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ILO, JLO, IHI, JHI, the row and column of the first
%    and last entries in the block.
%
%    Output, real A(1:IHI+1-ILO,1:JHI+1-JLO), the block of the Hilbert matrix.
%
  a = zeros ( ihi + 1 - ilo, jhi + 1 - jlo );

  i = ilo:ihi;

  for j = jlo : jhi
    a(i+1-ilo,j+1-jlo) = i / j;
  end

  return
end


function out = ir_dct8(x, adj)
%| 2D DCT of each 8x8 block
%| set adj=1 for adjoint (transpose)

if nargin < 1, ir_usage, end
if nargin < 2, adj = false; end

if streq(x, 'test'), ir_dct8_test, return, end

dc = ir_dctmtx(8);
if adj
	dc = dc';
end

out = zeros(size(x));
[nx ny] = size(x);
for by=1:floor(ny/8)
	for bx=1:floor(nx/8)
		ix = (bx-1)*8+(1:8);
		iy = (by-1)*8+(1:8);
		block = x(ix,iy);
		tmp = (dc * block) * dc';
		out(ix,iy) = tmp;
	end
end

end

function ir_dct8_test
	nx = 32;
	ny = 16;
	X = rand(nx,ny);
	d1 = ir_dct8(X);
%	im(d1)

	b8 = dctmtx(8);
	bx = kron(eye(nx/8), b8);
	by = kron(eye(ny/8), b8);
	d2 = bx * X * by';
%	im(d2)
	assert(max_percent_diff(d1, d2) < 1e-12)

	d3 = kron(by, bx) * X(:);
	d3 = reshape(d3, nx, ny);
%	im(d3)
	assert(max_percent_diff(d1, d3) < 1e-12)
end


function cfArray = ERBSpace(lowFreq, highFreq, N)
% function cfArray = ERBSpace(lowFreq, highFreq, N)
% This function computes an array of N frequencies uniformly spaced between
% highFreq and lowFreq on an ERB scale.  N is set to 100 if not specified.
%
% See also linspace, logspace, MakeERBCoeffs, MakeERBFilters.
%
% For a definition of ERB, see Moore, B. C. J., and Glasberg, B. R. (1983).
% "Suggested formulae for calculating auditory-filter bandwidths and
% excitation patterns," J. Acoust. Soc. Am. 74, 750-753.

if nargin < 1
	lowFreq = 100;
end

if nargin < 2
	highFreq = 44100/4;
end

if nargin < 3
	N = 100;
end

% Change the following three parameters if you wish to use a different
% ERB scale.  Must change in MakeERBCoeffs too.
EarQ = 9.26449;				%  Glasberg and Moore Parameters
minBW = 24.7;
order = 1;

% All of the followFreqing expressions are derived in Apple TR #35, "An
% Efficient Implementation of the Patterson-Holdsworth Cochlear
% Filter Bank."  See pages 33-34.
cfArray = -(EarQ*minBW) + exp((1:N)'*(-log(highFreq + EarQ*minBW) + ...
		log(lowFreq + EarQ*minBW))/N) * (highFreq + EarQ*minBW);


function b = r8sp_mv ( m, n, nz_num, row, col, a, x )

%*****************************************************************************80
%
%% R8SP_MV multiplies an R8SP matrix by an R8VEC.
%
%  Discussion:
%
%    The R8SP storage format stores the row, column and value of each nonzero
%    entry of a sparse matrix.
%
%    It is possible that a pair of indices (I,J) may occur more than
%    once.  Presumably, in this case, the intent is that the actual value
%    of A(I,J) is the sum of all such entries.  This is not a good thing
%    to do, but I seem to have come across this in MATLAB.
%
%    The R8SP format is used by CSPARSE ("sparse triplet"), DLAP/SLAP
%    ("nonsymmetric SLAP triad"), by MATLAB, and by SPARSEKIT ("COO" format).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 January 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of
%    the matrix.
%
%    Input, integer NZ_NUM, the number of nonzero elements in
%    the matrix.
%
%    Input, integer ROW(NZ_NUM), COL(NZ_NUM), the row and
%    column indices of the nonzero elements.
%
%    Input, real A(NZ_NUM), the nonzero elements of the matrix.
%
%    Input, real X(N), the vector to be multiplied by A.
%
%    Output, real B(M), the product vector A*X.
%
  b = zeros(m,1);

  for k = 1 : nz_num

    i = row(k);
    j = col(k);
    b(i) = b(i) + a(k) * x(j);

  end

  return
end


% Calculate the dot product of coefficient vectors of two polynomials
%
%  Syntax:  (pdot is the shortened alias for PolynomialDotProduct)
%    >> d = PolynomialDotProduct(f,g)
%    >> d = pdot(f,g)
%
%   Input:   f --- (string)            polynomial
%            g --- (string)            polynomial
%
%  Output:   d --- (numeric)  dot product of coeffcient vectors of f and g
%
%  Example:  >> d = pdot('3+x*y-y^3*x^2+x^5','5-4*x^2*y^3+9*x*y')
%            d =
%                  28


function [r,lon,lat] = SHMapToGrid(vec,res,lmax,location)

% [r,lon,lat] = SHMapToGrid(vec,res[,lmax,location])
%
% Maps a vector of spherical harmonic coefficients to grid.
% To use with multi-layer vectors, specify the array lmax.
% Grid is generated with the default resolution 10 degrees.
% By default, the spherical harmonics are computed at the
% centers of the cells. This behaviour can be modified by
% setting location='corner' and any value of res in degrees

if nargin < 2
    res = 10;
end

if nargin < 3
    lmax = SHn2lm(length(vec));
end

if nargin < 4
    location = 'center';
end

if strcmp(location,'center')
    shift = res/2;
    lon=linspace(shift,360-shift,360/res);
    lat=linspace(90-shift,-90+shift,180/res)';
    colat = 90 - lat;
elseif strcmp(location,'corner')
    lon=linspace(0,360,360/res+1);
    lat=linspace(90,-90,180/res+1)';
    colat = 90 - lat;
else
    error('location argument must be "center" or "corner"');
end

nlon=length(lon);
nlat=length(lat);
nrad=length(lmax);

r=zeros(nlat,nlon,nrad);

for i=1:nlon
    for j=1:nlat
        [SHvec,i1,i2] = SHCreateYVec(lmax,lon(i),colat(j),'deg');
        for k=1:nrad
            r(j,i,k)= vec(i1(k):i2(k))'*SHvec(i1(k):i2(k));
        end
    end
end

% if nargout > 1
%     [lon,lat] = meshgrid(lon,lat);
% end


function hermite_exactness ( quad_filename, degree_max, option )

%*****************************************************************************80
%
%% MAIN is the main program for HERMITE_EXACTNESS.
%
%  Discussion:
%
%    This program investigates a standard Gauss-Hermite quadrature rule
%    by using it to integrate monomials over (-oo,+oo), and comparing the
%    approximate result to the known exact value.
%
%    The user specifies:
%    * the "root" name of the R, W and X files that specify the rule;
%    * DEGREE_MAX, the maximum monomial degree to be checked.
%    * the OPTION (unweighted/physicist weight/probabilist weight)
%
%    OPTION indicates the weight function and normalization:
%    0, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    1, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    2, Integral ( -oo < x < +oo ) x^n exp(-x*x/2)             dx.
%    3, Integral ( -oo < x < +oo ) x^n exp(-x*x)   / sqrt (pi) dx.
%    4, Integral ( -oo < x < +oo ) x^n exp(-x*x/2) / sqrt(2pi) dx.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 June 2013
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HERMITE_EXACTNESS\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Investigate the polynomial exactness of a Gauss-Hermite\n' );
  fprintf ( 1, '  quadrature rule by integrating exponentially weighted\n' );
  fprintf ( 1, '  monomials up to a given degree over the (-oo,+oo) interval.\n' );
%
%  Get the quadrature file root name:
%
  if ( 1 <= nargin )

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS:\n' );

    quad_filename = input ( '  Enter the "root" name of the quadrature files: ' );

  end
%
%  Create the names of:
%    the quadrature X file;
%    the quadrature W file;
%    the quadrature R file;
%
  quad_x_filename = strcat ( quad_filename, '_x.txt' );
  quad_w_filename = strcat ( quad_filename, '_w.txt' );
  quad_r_filename = strcat ( quad_filename, '_r.txt' );
%
%  The second command line argument is the maximum degree.
%
  if ( 2 <= nargin )

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS:\n' );

    degree_max = input ( '  Please enter the maximum degree to check: ' );

  end
%
%  The third command line argument is OPTION.
%
  if ( 3 <= nargin )

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS:\n' );
    fprintf ( 1, '  OPTION specifies the weight function w(x):\n' );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  0, rho(x) = 1\n' );
    fprintf ( 1, '  1, rho(x) = exp ( -x*x  )\n' );
    fprintf ( 1, '  2, rho(x) = exp ( -x*x/2)\n' );
    fprintf ( 1, '  3, rho(x) = exp ( -x*x  ) / sqrt( pi)\n' );
    fprintf ( 1, '  4, rho(x) = exp ( -x*x/2) / sqrt(2pi)\n' );
    fprintf ( 1, '\n' );
    option = input ( '  Please enter OPTION: ' );

  end

  if ( option < 0 || 4 < option )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS - Fatal error!\n' );
    fprintf ( 1, '  Illegal value of OPTION.\n' );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end
%
%  Summarize the input.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HERMITE_EXACTNESS: User input:\n' );
  fprintf ( 1, '  Quadrature rule X file = "%s".\n', quad_x_filename );
  fprintf ( 1, '  Quadrature rule W file = "%s".\n', quad_w_filename );
  fprintf ( 1, '  Quadrature rule R file = "%s".\n', quad_r_filename );
  fprintf ( 1, '  Maximum degree to check = %d\n', degree_max );
%
%  Read the X file.
%
  [ dim_num, order ] = r8mat_header_read ( quad_x_filename );

  if ( dim_num ~= 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS - Fatal error!\n' );
    fprintf ( 1, '  The spatial dimension should be 1.\n');
    fprintf ( 1, '  The spatial dimension in the X file is %d\n', dim_num );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial dimension = %d\n', dim_num );
  fprintf ( 1, '  Number of points  = %d\n', order );

  x = r8mat_data_read ( quad_x_filename, dim_num, order );
%
%  Read the W file.
%
  [ dim_num2, point_num ] = r8mat_header_read ( quad_w_filename );

  if ( dim_num2 ~= 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS - Fatal error!\n' );
    fprintf ( 1, '  The quadrature weight file should have exactly\n');
    fprintf ( 1, '  one value on each line.\n' );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end

  if ( point_num ~= order )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS - Fatal error!\n' );
    fprintf ( 1, '  The quadrature weight file should have exactly\n' );
    fprintf ( 1, '  the same number of lines as the abscissa file.\n' );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end

  w = r8mat_data_read ( quad_w_filename, 1, order );
%
%  Read the R file.
%
  [ dim_num2, point_num ] = r8mat_header_read ( quad_r_filename );

  if ( dim_num2 ~= dim_num )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'v - Fatal error!\n' );
    fprintf ( 1, '  The quadrature region file should have the same\n' );
    fprintf ( 1, '  number of values on each line as the abscissa file\n' );
    fprintf ( 1, '  does.\n' );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end

  if ( point_num ~= 2 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HERMITE_EXACTNESS - Fatal error!\n' );
    fprintf ( 1, '  The quadrature region file should have two lines.\n' );
    error ( 'HERMITE_EXACTNESS - Fatal error!' );
  end

  r = r8mat_data_read ( quad_r_filename, dim_num, 2 );
%
%  Print the input quadrature rule.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Test a Gauss-Hermite quadrature rule of\n' );
  fprintf ( 1, '  ORDER = %d\n', order );
  fprintf ( 1, '\n' );
  if ( option == 0 )
    fprintf ( 1, '  OPTION = 0, the unweighted rule for:\n' );
    fprintf ( 1, '  Integral ( -oo < x < +oo ) f(x) dx\n' );
  elseif ( option == 1 )
    fprintf ( 1, '  OPTION = 1, the physicist weighted rule for:\n' );
    fprintf ( 1, '  Integral ( -oo < x < +oo ) f(x) * exp(-x*x) dx\n' );
  elseif ( option == 2 )
    fprintf ( 1, '  OPTION = 2, the probabilist weighted rule for:\n' );
    fprintf ( 1, '  Integral ( -oo < x < +oo ) f(x) * exp(-x*x/2) dx\n' );
  elseif ( option == 3 )
    fprintf ( 1, '  OPTION = 3, the physicist normalized weighted rule for:\n' );
    fprintf ( 1, '  Integral ( -oo < x < +oo ) f(x) * exp(-x*x) / sqrt(pi) dx\n' );
  elseif ( option == 4 )
    fprintf ( 1, '  OPTION = 4, the probabilist normalized weighted rule for:\n' );
    fprintf ( 1, '  Integral ( -oo < x < +oo ) f(x) * exp(-x*x/2) / sqrt(2 pi) dx\n' );
  end
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Weights W:\n' );
  fprintf ( 1, '\n' );
  for i = 1 : order
    fprintf ( 1, '  w(%d) = %24.16f\n', i, w(i) );
  end
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Abscissas X:\n' );
  fprintf ( 1, '\n' );
  for i = 1 : order
    fprintf ( 1, '  x(%d) = %24.16f\n', i, x(i) );
  end
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Region R:\n' );
  fprintf ( 1, '\n' );
  for i = 1 : 2
    fprintf ( 1, '  r(%d) = %e\n', i, r(i) );
  end
%
%  Explore the monomials.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  A Gauss-Hermite rule would be able to exactly\n' );
  fprintf ( 1, '  integrate monomials up to and including \n' );
  fprintf ( 1, '  degree = %d\n', 2 * order - 1 );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Degree      Error\n' );
  fprintf ( 1, '\n' );

  for degree = 0 : degree_max

    quad_error = hermite_monomial_quadrature ( degree, order, option, w, x );

    fprintf ( 1, '  %2d  %24.16f\n', degree, quad_error );

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

  return
end
function column_num = file_column_count ( input_file_name )

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

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

  while ( 1 )

    line = fgetl ( input_unit );

    if ( line == -1 )
      break;
    end

    if ( s_len_trim ( line ) == 0 )

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

    else
      got_one = TRUE;
      break;
    end

  end

  fclose ( input_unit );

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

  column_num = s_word_count ( line );

  return
end
function row_num = file_row_count ( input_file_name )

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

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

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

  record_num = 0;

  while ( 1 )

    line = fgetl ( input_unit );

    if ( line == -1 )
      break;
    end

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

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

  end

  fclose ( input_unit );

  return
end
function value = hermite_integral ( n, option )

%*****************************************************************************80
%
%% HERMITE_INTEGRAL evaluates a monomial Hermite integral.
%
%  Discussion:
%
%    H(n,1) = Integral ( -oo < x < +oo ) x^n exp(-x^2) dx
%    H(n,1) is 0 for n odd.
%    H(n,1) = (n-1)!! * sqrt(pi) / 2^(n/2) for n even.
%
%    H(n,2) = Integral ( -oo < x < +oo ) x^n exp(-x^2/2) dx
%    H(n,2) is 0 for n odd.
%    H(n,2) = (n-1)!! * sqrt(2*pi) for n even.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the integral.
%    0 <= N.
%
%    Input, integer OPTION, the integral has the form:
%    0, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    1, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    2, Integral ( -oo < x < +oo ) x^n exp(-x*x/2)             dx.
%    3, Integral ( -oo < x < +oo ) x^n exp(-x*x)   / sqrt (pi) dx.
%    4, Integral ( -oo < x < +oo ) x^n exp(-x*x/2) / sqrt(2pi) dx.
%
%    Output, real VALUE, the value of the integral.
%
  if ( n < 0 )

    value = - r8_huge ( );

  elseif ( mod ( n, 2 ) == 1 )

    value = 0.0;

  elseif ( option == 0 )

    value = r8_factorial2 ( n - 1 ) * sqrt ( pi ) / 2.0^( n / 2 );

  elseif ( option == 1 )

    value = r8_factorial2 ( n - 1 ) * sqrt ( pi ) / 2.0^( n / 2 );

  elseif ( option == 2 )

    value = r8_factorial2 ( n - 1 ) * sqrt ( 2.0 * pi );

  elseif ( option == 3 )

    value = r8_factorial2 ( n - 1 ) / 2.0^( n / 2 );

  elseif ( option == 4 )

    value = r8_factorial2 ( n - 1 );

  end

  return
end
function quad_error = hermite_monomial_quadrature ( expon, order, option, w, x )

%*****************************************************************************80
%
%% HERMITE_MONOMIAL_QUADRATURE applies a quadrature rule to a monomial.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer EXPON, the exponent.
%
%    Input, intege ORDER, the number of points in the rule.
%
%    Input, integer OPTION, the integral has the form:
%    0, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    1, Integral ( -oo < x < +oo ) x^n exp(-x*x)               dx.
%    2, Integral ( -oo < x < +oo ) x^n exp(-x*x/2)             dx.
%    3, Integral ( -oo < x < +oo ) x^n exp(-x*x)   / sqrt (pi) dx.
%    4, Integral ( -oo < x < +oo ) x^n exp(-x*x/2) / sqrt(2pi) dx.
%
%    Input, real W(ORDER), the quadrature weights.
%
%    Input, real X(ORDER), the quadrature points.
%
%    Output, real QUAD_ERROR, the quadrature error.
%

%
%  Get the exact value of the integral of the unscaled monomial.
%
  exact = hermite_integral ( expon, option );
%
%  Evaluate the unweighted monomial at the quadrature points.
%
  if ( option == 0 )
    value(1:order) = exp ( - x(1:order).^2 ) .* x(1:order).^expon;
  elseif ( option == 1 )
    value(1:order) = x(1:order).^expon;
  elseif ( option == 2 )
    value(1:order) = x(1:order).^expon;
  elseif ( option == 3 )
    value(1:order) = x(1:order).^expon;
  elseif ( option == 4 )
    value(1:order) = x(1:order).^expon;
  end
%
%  Compute the weighted sum.
%
  quad = ( w(1:order) * value(1:order)' );
%
%  Absolute error for cases where exact integral is zero,
%  Relative error otherwise.
%
  if ( exact == 0.0 )
    quad_error = abs ( quad );
  else
    quad_error = abs ( quad - exact ) / abs ( exact );
  end

  return
end
function value = r8_factorial2 ( n )

%*****************************************************************************80
%
%% R8_FACTORIAL2 computes the double factorial function.
%
%  Discussion:
%
%    FACTORIAL2( N ) = Product ( N * (N-2) * (N-4) * ... * 2 )  (N even)
%                    = Product ( N * (N-2) * (N-4) * ... * 1 )  (N odd)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 February 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the argument of the double factorial function.
%    If N is less than 1, VALUE is returned as 1.
%
%    Output, real VALUE, the value of N!!.
%
  value = 1;

  if ( n < 1 )
    return
  end

  while ( 1 < n )
    value = value * n;
    n = n - 2;
  end

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

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

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

  input_unit = fopen ( input_filename );

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

  i = 0;

  while ( i < n )

    line = fgets ( input_unit );

    if ( line == -1 )
      break;
    end

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

    elseif ( s_len_trim ( line ) == 0 )

    else

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

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

    end

  end

  fclose ( input_unit );

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

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

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

  n = file_row_count ( input_filename );

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

  return
end
function len = s_len_trim ( s )

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

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

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

  word_num = 0;
  s_length = length ( s );

  if ( s_length <= 0 )
    return;
  end

  blank = TRUE;

  for i = 1 : s_length

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

  end

  return
end
function timestamp ( )

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

  return
end


% Demo for spm_rar; robust autogregressive modelling

close all

secs=3;
ns=128;
t=[1/ns:1/ns:secs];
N=length(t);

% Generate Gaussian-Mixture Noise
m=2;
mix.m=m;
mix.state(1).prior=0.9;
mix.state(2).prior=0.1;
mix.state(1).m=0;
mix.state(2).m=0;
mix.state(1).C=1;
mix.state(2).C=100;
[noise,gamma_true]=spm_samp_mix(mix,N);
new_index=randperm(N);
noise=noise(new_index);
gamma_true=gamma_true(new_index);

% Convolve noise with AR filter
a_true=[-1.8517,1.3741,0.1421,-0.6852,0.3506];
p_true=length(a_true);
y=filter(1,[1,a_true],noise);
y=y(1:N);

% Fit AR model
ar=spm_ar(y,p_true);

% Fit Robust AR model
[rar,yclean] = spm_rar(y,p_true,m);

rar3=spm_rar(y,p_true,3);
rar4=spm_rar(y,p_true,4);

% Get model evidences
fm=[ar.fm,rar.fm,rar3.fm,rar4.fm];
fm=fm-mean(fm);

figure
subplot(2,2,1);
plot(t,y);
title('Data');
subplot(2,2,3);
hist(noise,20);
title('Noise histogram');
subplot(2,2,2);
[tmp,outlier]=min(rar.pi);
standard=m+1-outlier;
plot(gamma_true);
title('Outliers');
axis([0 N -0.1 1.1]);
subplot(2,2,4);
bar(fm);
title('Model evidence');
xlabel('m');

disp(' ');
disp('OUTLIER DETECTION:');
pos_prob=rar.gamma(outlier,find(gamma_true==1));
sens=length(find(pos_prob>0.5))/length(pos_prob);

neg_prob=rar.gamma(standard,find(gamma_true==0));
spec=length(find(neg_prob>0.5))/length(neg_prob);

disp(sprintf('Proportion of outliers correctly detected = %1.2f',sens));
disp(sprintf('Proportion of standards correctly detected = %1.2f',spec));

disp(' ');
disp('ACCURACY OF AR COEFFICIENT ESTIMATION:');
d_ar=norm(ar.a_mean-a_true');
d_rar=norm(rar.posts.a_mean-a_true');
disp(sprintf('Error for AR=%1.3f',d_ar));
disp(sprintf('Error for RAR=%1.3f',d_rar));
disp(sprintf('Ratio E_RAR/E_AR=%1.3f',d_rar/d_ar));

% figure;plot(y);hold on;plot(yclean,'r');
% legend('Original','Clean');


function r = multirnd(theta,k)
%MULTIRND - Random vector from multinomial distribution.
%   r = multirnd(theta,k) returns a vector randomly selected
%   from the multinomial distribution with parameter vector
%   theta, and count k (i.e. sum(r) = k).
%
%   Note: if k is unspecified, then it is assumed k=1.
%
%   Author: David Ross
%

%--------------------------------------------------------
% Check the arguments.
%--------------------------------------------------------
error(nargchk(1,2,nargin));

% make sure theta is a vector
if ndims(theta) > 2 | all(size(theta) > 1)
    error('theta must be a vector');
end

% if theta is a row vector, convert it to a column vector
if size(theta,1) == 1
    theta = theta';
end

% make sure k is a scalar?

% if the number of samples has not been provided, set
% it to one
if nargin == 1
    k = 1;
end

%--------------------------------------------------------
% Main...
%--------------------------------------------------------
n = length(theta);
theta_cdf = cumsum(theta);

r = zeros(n,1);
random_vals = rand(k,1);

for j = 1:k
    index = min(find(random_vals(j) <= theta_cdf));
    r(index) = r(index) + 1;
end


function checkFactors(min_number, max_number)
%CHECKFACTORS   Return the maximum prime factor for a range of numbers.
%
% DESCRIPTION:
%       checkFactors loops through the given range of numbers and finds the
%       numbers with the smallest maximum prime factors. This allows
%       suitable grid sizes to be selected to maximise the speed of the FFT
%       (this is fastest for FFT lengths with small prime factors).
%
% USAGE:
%       checkFactors(min_number, max_number)
%
% ABOUT:
%       author      - Bradley Treeby
%       date        - 20th April 2011
%       last update - 8th July 2013
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2014 Bradley Treeby and Ben Cox

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

% extract factors
facs = zeros(1, max_number - min_number);
fac_max = facs;
for index = min_number:max_number;
    facs(index - min_number + 1) = length(factor(index));
    fac_max(index - min_number + 1) = max(factor(index));
end

% plot factors
figure;
subplot(2, 1, 1), bar(min_number:max_number, facs);
set(gca, 'XLim', [(min_number -0.5) (max_number + 0.5)]);
title('number of factors');
subplot(2, 1, 2), bar(min_number:max_number, fac_max);
set(gca, 'XLim', [(min_number -0.5) (max_number + 0.5)]);
title('largest factor');

% compute best factors in range
disp('Numbers with a maximum prime factor of 2');
ind = min_number + find(fac_max == 2) - 1;
disp(num2str(ind));
disp('Numbers with a maximum prime factor of 3');
ind = min_number + find(fac_max == 3) - 1;
disp(num2str(ind));
disp('Numbers with a maximum prime factor of 5');
ind = min_number + find(fac_max == 5) - 1;
disp(num2str(ind));
disp('Numbers with a maximum prime factor of 7');
ind = min_number + find(fac_max == 7) - 1;
disp(num2str(ind));
disp('Numbers to avoid (prime numbers)');
nums = min_number:max_number;
disp(num2str(nums(fac_max == nums)));


function [bestEpsilon bestF1] = selectThreshold(yval, pval)
%SELECTTHRESHOLD Find the best threshold (epsilon) to use for selecting
%outliers
%   [bestEpsilon bestF1] = SELECTTHRESHOLD(yval, pval) finds the best
%   threshold to use for selecting outliers based on the results from a
%   validation set (pval) and the ground truth (yval).
%

bestEpsilon = 0;
bestF1 = 0;
F1 = 0;

stepsize = (max(pval) - min(pval)) / 1000;
for epsilon = min(pval):stepsize:max(pval)

    % ====================== YOUR CODE HERE ======================
    % Instructions: Compute the F1 score of choosing epsilon as the
    %               threshold and place the value in F1. The code at the
    %               end of the loop will compare the F1 score for this
    %               choice of epsilon and set it to be the best epsilon if
    %               it is better than the current choice of epsilon.
    %
    % Note: You can use predictions = (pval < epsilon) to get a binary vector
    %       of 0's and 1's of the outlier predictions

    cvPrediction = pval<epsilon;
    tp = sum((cvPrediction == 1) & (yval == 1));
    fp = sum((cvPrediction == 1) & (yval == 0));
    fn = sum((cvPrediction == 0) & (yval == 1));
    precision = tp/(tp+fp);
    recision = tp/(tp+fn);
    F1 = (2*precision*recision)/(precision+recision);

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

    if F1 > bestF1
       bestF1 = F1;
       bestEpsilon = epsilon;
    end
end

end


function bivand2_test ( )

%*****************************************************************************80
%
%% BIVAND2_TEST tests BIVAND2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BIVAND2_TEST:\n' );
  fprintf ( 1, '  Compute a bidimensional Vandermonde matrix\n' );
  fprintf ( 1, '  associated with the product polynomials of\n' );
  fprintf ( 1, '  maximum degree less than N.\n' );

  n = 3;
  nn = n^2;

  alpha = [ 1.0; 2.0; 3.0 ];
  beta = [ 10.0; 20.0; 30.0 ];

  r8vec_print ( n, alpha, '  Vandermonde vector ALPHA:' );
  r8vec_print ( n, beta, '  Vandermonde vector BETA:' );

  a = bivand2 ( n, alpha, beta );

  r8mat_print ( nn, nn, a, '  Bidimensional Vandermonde matrix:' );

  return
end


function result = torus_square_14c ( func, r1, r2 )

%*****************************************************************************80
%
%% TORUS_SQUARE_14C approximates an integral in a "square" torus in 3D.
%
%  Discussion:
%
%    A 14-th degree 960 point formula is used.
%
%  Integration region:
%
%    Points (X,Y,Z) such that:
%
%      R1 - R2 <= SQRT ( X**2 + Y**2 ) <= R1 + R2,
%       -R2 <= Z <= R2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 May 2004
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Arthur H Stroud,
%    Approximate Calculation of Multiple Integrals,
%    Prentice Hall, 1971.
%
%  Parameters:
%
%    Input, external FUNC, the name of the user supplied
%    function of three variables which is to be integrated, of the form:
%      function value = func ( x, y, z )
%
%    Input, real R1, R2, the radii that define the torus.
%
%    Output, real RESULT, the approximate integral of the function.
%
  norder = 8;

  [ rtab, weight ] = legendre_set ( norder );

  w = 1.0E+00 / ( 60.0E+00 * r1 );
  quad = 0.0E+00;

  for n = 1 : 15

    angle = 2.0E+00 * pi * n / 15.0E+00;
    cth = cos ( angle );
    sth = sin ( angle );

    for i = 1 : norder

      u = r1 + rtab(i) * r2;
      x = u * cth;
      y = u * sth;

      for j = 1 : norder
        z = rtab(j) * r2;
        quad = quad + u * w * weight(i) * weight(j) * feval ( func, x, y, z );
      end

    end

  end

  volume = torus_square_volume_3d ( r1, r2 );
  result = quad * volume;

  return
end