function [ c, discrepancy ] = partition_brute ( n, w )

%*****************************************************************************80
%
%% PARTITION_BRUTE approaches the partition problem using brute force.
%
%  Discussion:
%
%    We are given a set of N integers W.
%
%    We seek to partition W into subsets W0 and W1, such that the subsets
%    have equal sums.
%
%    The "discrepancy" is the absolute value of the difference between the
%    two sums, and will be zero if we have solved the problem.
%
%    For a given set of integers, there may be zero, one, or many solutions.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 May 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the size of the set.
%
%    Input, integer W(N), the integers.
%
%    Output, integer C(N), indicates the proposed solution.
%    C(I) is 0 for items in set W0 and 1 for items in set W1.
%
%    Output, integer DISCREPANCY, the discrepancy.
%
  w = w(:);
  w_sum = sum ( w(1:n) );
  discrepancy = w_sum;

  d = [];
  rank = -1;

  while ( 1 )

    [ d, rank ] = subset_next ( n, d, rank );

    if ( rank == -1 )
      break
    end

    d_discrepancy = abs ( w_sum - 2 * d' * w );

    if ( d_discrepancy < discrepancy )
      discrepancy = d_discrepancy;
      c(1:n) = d(1:n);
    end

    if ( discrepancy == 0 )
      break
    end

  end

  return
end


function [week,sec_of_week] = gps_time(julday)
% GPS_TIME   Conversion of Julian Day number to GPS week and
%	                Seconds of Week as reckoned from midnight between
%                  Saturday  and Sunday

% Written by Kai Borre
% January 7, 2016

    a = floor(julday+.5);
    b = a+1537;
    c = floor((b-122.1)/365.25);
    e = floor(365.25*c);
    f = floor((b-e)/30.6001);
    d = b-e-floor(30.6001*f)+rem(julday+.5,1);
    day_of_week = rem(floor(julday+.5),7);
    week = floor((julday-2444244.5)/7);
    % We add +1 as the GPS week starts at Saturday midnight
    sec_of_week = (rem(d,1)+day_of_week+1)*86400;
%%%%%%% end gps_time.m	%%%%%%%%%%%%%


function [e0,e1,theta] = det2MM(im,sigmaI,sigmaO)
% function [e0,e1,theta] = det2MM(im,sigmaI,sigmaO)
%
% Compute the eigenspectrum of the spatially averaged second moment
% matrix.
%
% INPUT
%	im	Image.
%	sigmaI	Inner scale (sigma for image derivatives).
%	sigmaO	Outer scale (sigma for spatial averaging).
%
% OUTPUT
%	e0,e1	Smaller,larger eigenvalues.
%	theta	Orientation of fist eigenvector + pi/2
%		(i.e. orientation of possible edge).
%
% David R. Martin <dmartin@eecs.berkeley.edu>
% March 2003

if ndims(im)>2, im = rgb2gray(im); end;
idiag = norm(size(im));

if nargin<2, sigmaI=2; end
if nargin<3, sigmaO=sigmaI; end % Scott Konishi says this is close
                                % to optimal.
sigmaI = max(0.5,sigmaI);
sigmaO = max(0.5,sigmaO);

% compute x and y image derivatives at inner scale
fb = cell(2,1);
fb{1} = oeFilter(sigmaI,3,pi/2,1);
fb{2} = fb{1}';
fim = fbRun(fb,im);
dx = fim{1};
dy = fim{2};

% compute smoothed squared image derivatives at outer scale
f = oeFilter(sigmaO,3);
dx2 = applyFilter(f,dx.^2);
dy2 = applyFilter(f,dy.^2);
dxy = applyFilter(f,dx.*dy);

% compute eigenvalues of the spatially averaged 2nd moment matrix
% and the orientations of the eigenvectors
k = sqrt( (dx2-dy2).^2 + 4.*dxy.^2 );
eig0 = (dx2 + dy2 - k) / 2;
eig1 = (dx2 + dy2 + k) / 2;
t0 = atan2( dx2-eig0, -dxy );
t1 = atan2( dx2-eig1, -dxy );

% order eigenvalues by their absolute value, so e0<=e1, and pick
% out the orientation corresponding to the largest eigenvalue
x = (abs(eig1) > abs(eig0));
e0 = abs(eig0.*x + eig1.*~x);
e1 = abs(eig1.*x + eig0.*~x);
theta = t1.*x + t0.*~x;
theta = mod(theta+pi/2,pi);

% check postconditions
if any(e0>e1), error('e0>e1'); end


function [di, dj] = gradient_2d(M, mask)
% [di dj] = gradient_2d(M)
% [di dj] = gradient_2d(M, mask)
%
% Approximate the gradient of a two-dimensional function represented by M(i,j), using
% a 3x3 plane fitting algorithm.
%
%                         PARAMETERS
%
% M Matrix of function values, M(i,j) = f(i,j), the spacing is assumed to be uniform.
%
% mask (Optional) Matrix of the same size of M, with zero values in positions of M to be ignored by the
%                 gradient computations.
%
%                        RETURN VALUES
%
% di First component of the gradient: di(i,j) is the approximated [d/di f](i,j)
%
% dj Second component of the gradient: dj(i,j) is the approximated [d/dj f](i,j)
%
%                        LIMITATIONS
%
% To avoid ill-conditioned solutions, the mask is ignored near the "edges" of M,
% so this may result in artifacts in some cases. Leaving a "safety" border
% on the edges should be more than enough to prevent the issue.
%
% Author: Luca Vezzaro (elvezzaro@gmail.com)

	nr = size(M, 1);
	nc = size(M, 2);

	if nargin < 2
		mask = ones(nr, nc);
	end

	v = zeros(3,1);

	% The used algorithm is simple: the evaluation point is set
	% as the origin, and a plane is fitted to the 8 nearest positions,
	% centered on the origin. On the boundary, there are less values,
	% but the method is the same.

	% First the "corners"

	p(1,:) = [1 0]; v(1) = M(2,1) - M(1,1);
	p(2,:) = [0 1]; v(2) = M(1,2) - M(1,1);
	p(3,:) = [1 1]; v(3) = M(2,2) - M(1,1);

	n = p \ v;

	di(1,1) = n(1);
	dj(1,1) = n(2);

	p(1,:) = [0 -1]; v(1) =  M(1,nc-1) - M(1,nc);
	p(2,:) = [1 -1]; v(2) =  M(2,nc-1) - M(1,nc);
	p(3,:) = [1 0];  v(3) =  M(2,nc)   - M(1,nc);

	n = p \ v;

	di(1,nc) = n(1);
	dj(1,nc) = n(2);

	p(1,:) = [-1 0]; v(1) = M(nr-1,1) - M(nr,1);
	p(2,:) = [-1 1]; v(2) = M(nr-1,2) - M(nr,1);
	p(3,:) = [0 1];  v(3) = M(nr,2)   - M(nr,1);

	n = p \ v;

	di(nr,1) = n(1);
	dj(nr,1) = n(2);

	p(1,:) = [-1 -1]; v(1) = M(nr-1,nc-1) - M(nr,nc);
	p(2,:) = [0 -1];  v(2) = M(nr,nc-1)   - M(nr,nc);
	p(3,:) = [-1 0];  v(3) = M(nr-1,nc)   - M(nr,nc);

	n = p \ v;

	di(nr,nc) = n(1);
	dj(nr,nc) = n(2);

	% Then, the boundaries

	for j=2:nc-1
		p(1,:) = [0 -1]; v(1) = M(1,j-1) - M(1,j);
		p(2,:) = [1 -1]; v(2) = M(2,j-1) - M(1,j);
		p(3,:) = [1 0];  v(3) = M(2,j)   - M(1,j);
		p(4,:) = [0 1];  v(4) = M(1,j+1) - M(1,j);
		p(5,:) = [1 1];  v(5) = M(2,j+1) - M(1,j);

		n = p \ v;

		di(1,j) = n(1);
		dj(1,j) = n(2);

		p(1,:) = [-1 -1]; v(1) = M(nr-1,j-1) - M(nr,j);
		p(2,:) = [0 -1];  v(2) = M(nr,j-1)   - M(nr,j);
		p(3,:) = [-1 0];  v(3) = M(nr-1,j)   - M(nr,j);
		p(4,:) = [-1 1];  v(4) = M(nr-1,j+1) - M(nr,j);
		p(5,:) = [0 1];   v(5) = M(nr,j+1)   - M(nr,j);

		n = p \ v;

		di(nr,j) = n(1);
		dj(nr,j) = n(2);
	end

	for i=2:nr-1
		p(1,:) = [-1 0]; v(1) = M(i-1,1) - M(i,1);
		p(2,:) = [1 0];  v(2) = M(i+1,1) - M(i,1);
		p(3,:) = [-1 1]; v(3) = M(i-1,2) - M(i,1);
		p(4,:) = [0 1];  v(4) = M(i,2)   - M(i,1);
		p(5,:) = [1 1];  v(5) = M(i+1,2) - M(i,1);

		n = p \ v;

		di(i,1) = n(1);
		dj(i,1) = n(2);

		p(1,:) = [-1 -1]; v(1) = M(i-1,nc-1) - M(i,nc);
		p(2,:) = [0 -1];  v(2) = M(i,nc-1)   - M(i,nc);
		p(3,:) = [1 -1];  v(3) = M(i+1,nc-1) - M(i,nc);
		p(4,:) = [-1 0];  v(4) = M(i-1,nc)   - M(i,nc);
		p(5,:) = [1 0];   v(5) = M(i+1,nc)   - M(i,nc);

		n = p \ v;

		di(i,nc) = n(1);
		dj(i,nc) = n(2);
	end

	% And finally the remaining function values
	for i=2:nr-1
		for j=2:nc-1
			if mask(i,j) ~= 0
				k = 1;

				if mask(i-1,j-1) ~= 0
					p(k,:) = [-1 -1]; v(k) = M(i-1,j-1) - M(i,j);
					k = k + 1;
				end

				if mask(i-1,j) ~= 0
					p(k,:) = [-1 0];  v(k) = M(i-1,j)   - M(i,j);
					k = k + 1;
				end

				if mask(i-1,j+1) ~= 0
					p(k,:) = [-1 1];  v(k) = M(i-1,j+1) - M(i,j);
					k = k + 1;
				end

				if mask(i,j-1) ~= 0
					p(k,:) = [0 -1];  v(k) = M(i,j-1)   - M(i,j);
					k = k + 1;
				end

				if mask(i,j+1) ~= 0
					p(k,:) = [0 1];   v(k) = M(i,j+1)   - M(i,j);
					k = k + 1;
				end

				if mask(i+1,j-1) ~= 0
					p(k,:) = [1 -1];  v(k) = M(i+1,j-1) - M(i,j);
					k = k + 1;
				end

				if mask(i+1,j) ~= 0
					p(k,:) = [1 0];   v(k) = M(i+1,j)   - M(i,j);
					k = k + 1;
				end

				if mask(i+1,j+1) ~= 0
					p(k,:) = [1 1];   v(k) = M(i+1,j+1) - M(i,j);
					k = k + 1;
				end

				if k > 2
					n = p(1:k-1,:) \ v(1:k-1);

					di(i,j) = n(1);
					dj(i,j) = n(2);
				else
					di(i,j) = 0;
					dj(i,j) = 0;
				end
			else
				di(i,j) = 0;
				dj(i,j) = 0;
			end
		end
	end


function ell = equivalentEllipsoid(points)
% Equivalent ellipsoid of a set of 3D points.
%
%   ELL = equivalentEllipsoid(PTS)
%   Compute the equivalent ellipsoid of the set of points PTS. The result
%   is an ellipsoid defined by:
%   ELL = [XC YC ZC  A B C  PHI THETA PSI]
%   where [XC YC ZY] is the center, [A B C] are the lengths of the
%   semi-axes (in decreasing order), and [PHI THETA PSI] are Euler angles
%   representing  the ellipsoid orientation, in degrees.
%
%   Example
%     pts = randn(300, 3);
%     pts = transformPoint3d(pts, createScaling3d([6 4 2]));
%     pts = transformPoint3d(pts, createRotationOx(pi/6));
%     pts = transformPoint3d(pts, createRotationOy(pi/4));
%     pts = transformPoint3d(pts, createRotationOz(pi/3));
%     pts = transformPoint3d(pts, createTranslation3d([5 4 3]));
%     elli = equivalentEllipsoid(pts);
%     figure; drawPoint3d(pts); axis equal;
%     hold on; drawEllipsoid(elli, ...
%         'drawEllipses', true, 'EllipseColor', 'b', 'EllipseWidth', 3);
%
%   See also
%     spheres, drawEllipsoid, equivalentEllipse, principalAxes
%     rotation3dToEulerAngles

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

% number of points
n = size(points, 1);

% compute centroid
center = mean(points);

% compute the covariance matrix
covPts = cov(points)/n;

% perform a principal component analysis with 2 variables,
% to extract equivalent axes
[U, S] = svd(covPts);

% extract length of each semi axis
radii = sqrt(5) * sqrt(diag(S)*n)';

% sort axes from greater to lower
[radii, ind] = sort(radii, 'descend');

% format U to ensure first axis points to positive x direction
U = U(ind, :);
if U(1,1) < 0
    U = -U;
    % keep matrix determinant positive
    U(:,3) = -U(:,3);
end

% convert axes rotation matrix to Euler angles
angles = rotation3dToEulerAngles(U);

% concatenate result to form an ellipsoid object
ell = [center, radii, angles];


function [ w, x ] = gm_rule_set ( rule, dim_num, point_num )

%*****************************************************************************80
%
%% GM_RULE_SET sets a Grundmann-Moeller rule.
%
%  Discussion:
%
%    This is a revised version of the calculation which seeks to compute
%    the value of the weight in a cautious way that avoids intermediate
%    overflow.  Thanks to John Peterson for pointing out the problem on
%    26 June 2008.
%
%    This rule returns weights and abscissas of a Grundmann-Moeller
%    quadrature rule for the DIM_NUM-dimensional unit simplex.
%
%    The dimension POINT_NUM can be determined by calling GM_RULE_SIZE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 June 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Axel Grundmann, Michael Moeller,
%    Invariant Integration Formulas for the N-Simplex
%    by Combinatorial Methods,
%    SIAM Journal on Numerical Analysis,
%    Volume 15, Number 2, April 1978, pages 282-290.
%
%  Parameters:
%
%    Input, integer RULE, the index of the rule.
%    0 <= RULE.
%
%    Input, integer DIM_NUM, the spatial dimension.
%    1 <= DIM_NUM.
%
%    Input, integer POINT_NUM, the number of points in the rule.
%
%    Output, real W(POINT_NUM), the weights.
%
%    Output, real X(DIM_NUM,POINT_NUM), the abscissas.
%
  s = rule;
  d = 2 * s + 1;
  k = 0;
  n = dim_num;
  one_pm = 1;

  for i = 0 : s

    weight =  one_pm;

    for j = 1 : max ( n, d, d + n - i )

      if ( j <= n )
        weight = weight *  ( j );
      end
      if ( j <= d )
        weight = weight * ( d + n - 2 * i );
      end
      if ( j <= 2 * s )
        weight = weight / 2.0;
      end
      if ( j <= i )
        weight = weight / j;
      end
      if ( j <= d + n - i )
        weight = weight / j;
      end

    end

    one_pm = - one_pm;

    beta_sum = s - i;
    more = 0;
    beta = [];
    h = 0;
    t = 0;

    while ( 1 )

      [ beta, more, h, t ] = comp_next ( beta_sum, dim_num + 1, ...
        beta, more, h, t );

      k = k + 1;

      w(k) = weight;

      x(1:dim_num,k) = ( 2 * beta(2:dim_num+1)' + 1 ) / ( d + n - 2 * i );

      if ( ~more )
        break
      end

    end

  end

  return
end


function [c1,c2]= binaryfit(phi,U,epsilon)
% compute c1 c2 for optimal binary fitting
% input:
%    U: input image
%    phi: level set function
%    epsilon: parameter for computing smooth Heaviside and dirac function
% output:
%    c1: a constant to fit the image U in the region phi>0
%    c2: a constant to fit the image U in the region phi<0

H = Heaviside(phi,epsilon); % compute the Heaveside function values

a = H .* U;
numer_1 = sum(a(:));
denom_1 = sum(H(:));
c1 = numer_1 / denom_1;

b = (1-H) .* U;
numer_2 = sum(b(:));
c = 1-H;
denom_2 = sum(c(:));
c2 = numer_2 / denom_2;


function [center, U, obj_fcn] = fcm(data, cluster_n, options)
%FCM Data set clustering using fuzzy c-means clustering.
%
%   [CENTER, U, OBJ_FCN] = FCM(DATA, N_CLUSTER) finds N_CLUSTER number of
%   clusters in the data set DATA. DATA is size M-by-N, where M is the number of
%   data points and N is the number of coordinates for each data point. The
%   coordinates for each cluster center are returned in the rows of the matrix
%   CENTER. The membership function matrix U contains the grade of membership of
%   each DATA point in each cluster. The values 0 and 1 indicate no membership
%   and full membership respectively. Grades between 0 and 1 indicate that the
%   data point has partial membership in a cluster. At each iteration, an
%   objective function is minimized to find the best location for the clusters
%   and its values are returned in OBJ_FCN.
%
%   [CENTER, ...] = FCM(DATA,N_CLUSTER,OPTIONS) specifies a vector of options
%   for the clustering process:
%       OPTIONS(1): exponent for the matrix U             (default: 2.0)
%       OPTIONS(2): maximum number of iterations          (default: 100)
%       OPTIONS(3): minimum amount of improvement         (default: 1e-5)
%       OPTIONS(4): info display during iteration         (default: 1)
%   The clustering process stops when the maximum number of iterations
%   is reached, or when the objective function improvement between two
%   consecutive iterations is less than the minimum amount of improvement
%   specified. Use NaN to select the default value.
%
%   Example
%       data = rand(100,2);
%       [center,U,obj_fcn] = fcm(data,2);
%       plot(data(:,1), data(:,2),'o');
%       hold on;
%       maxU = max(U);
%       % Find the data points with highest grade of membership in cluster 1
%       index1 = find(U(1,:) == maxU);
%       % Find the data points with highest grade of membership in cluster 2
%       index2 = find(U(2,:) == maxU);
%       line(data(index1,1),data(index1,2),'marker','*','color','g');
%       line(data(index2,1),data(index2,2),'marker','*','color','r');
%       % Plot the cluster centers
%       plot([center([1 2],1)],[center([1 2],2)],'*','color','k')
%       hold off;
%
%   See also FCMDEMO, INITFCM, IRISFCM, DISTFCM, STEPFCM.

%   Roger Jang, 12-13-94, N. Hickey 04-16-01
%   Copyright 1994-2018 The MathWorks, Inc.

if nargin ~= 2 && nargin ~= 3
	error(message("fuzzy:general:errFLT_incorrectNumInputArguments"))
end

data_n = size(data, 1);

% Change the following to set default options
default_options = [2;	% exponent for the partition matrix U
		100;	% max. number of iteration
		1e-5;	% min. amount of improvement
		1];	% info display during iteration

if nargin == 2
	options = default_options;
else
	% If "options" is not fully specified, pad it with default values.
	if length(options) < 4
		tmp = default_options;
		tmp(1:length(options)) = options;
		options = tmp;
	end
	% If some entries of "options" are nan's, replace them with defaults.
	nan_index = find(isnan(options)==1);
	options(nan_index) = default_options(nan_index);
	if options(1) <= 1
		error(message("fuzzy:general:errFcm_expMustBeGtOne"))
	end
end

expo = options(1);		% Exponent for U
max_iter = options(2);		% Max. iteration
min_impro = options(3);		% Min. improvement
display = options(4);		% Display info or not

obj_fcn = zeros(max_iter, 1);	% Array for objective function

U = initfcm(cluster_n, data_n);			% Initial fuzzy partition
% Main loop
for i = 1:max_iter
	[U, center, obj_fcn(i)] = stepfcm(data, U, cluster_n, expo);
	if display
		fprintf('Iteration count = %d, obj. fcn = %f\n', i, obj_fcn(i));
	end
	% check termination condition
	if i > 1
		if abs(obj_fcn(i) - obj_fcn(i-1)) < min_impro, break; end
	end
end

iter_n = i;	% Actual number of iterations
obj_fcn(iter_n+1:max_iter) = [];


function inside = triangle_contains_point_2d ( t, p )

%*****************************************************************************80
%
%% TRIANGLE_CONTAINS_POINT_2D finds if a point is inside a triangle in 2D.
%
%  Discussion:
%
%    The routine assumes that the vertices are given in counter-clockwise
%    order.
%
%    The routine determines if a point P is "to the right of" each of the lines
%    that bound the triangle.  It does this by computing the cross product
%    of vectors from a vertex to its next vertex, and to P.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real T(2,3), the triangle vertices.
%    The vertices should be given in counter clockwise order.
%
%    Input, real P(2), the point to be checked.
%
%    Output, logical INSIDE, is TRUE if the point is inside
%    the triangle or on its boundary.
%
  dim_num = 2;

  inside = 0;

  if ( 0.0 < ( p(1)   - t(1,1) ) * ( t(2,2) - t(2,1) ) ...
           - ( t(1,2) - t(1,1) ) * ( p(2)   - t(2,1) ) );
    return
  end

  if ( 0.0 < ( p(1)   - t(1,2) ) * ( t(2,3) - t(2,2) ) ...
           - ( t(1,3) - t(1,2) ) * ( p(2)   - t(2,2) ) );
    return
  end

  if ( 0.0 < ( p(1)   - t(1,3) ) * ( t(2,1) - t(2,3) ) ...
           - ( t(1,1) - t(1,3) ) * ( p(2)   - t(2,3) ) );
    return
  end

  inside = 1;

  return
end


 function cx = cheby_u_poly ( m, n, x )

%*****************************************************************************80
%
%% CHEBY_U_POLY evaluates Chebyshev polynomials U(n,x).
%
%  Differential equation:
%
%    (1-X*X) Y'' - 3 X Y' + N (N+2) Y = 0
%
%  First terms:
%
%    U(0,X) =   1
%    U(1,X) =   2 X
%    U(2,X) =   4 X^2 -   1
%    U(3,X) =   8 X^3 -   4 X
%    U(4,X) =  16 X^4 -  12 X^2 +  1
%    U(5,X) =  32 X^5 -  32 X^3 +  6 X
%    U(6,X) =  64 X^6 -  80 X^4 + 24 X^2 - 1
%    U(7,X) = 128 X^7 - 192 X^5 + 80 X^3 - 8X
%
%  Recursion:
%
%    U(0,X) = 1,
%    U(1,X) = 2 * X,
%    U(N,X) = 2 * X * U(N-1,X) - U(N-2,X)
%
%  Norm:
%
%    Integral ( -1 <= X <= 1 ) ( 1 - X^2 ) * U(N,X)^2 dX = PI/2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 January 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of evaluation points.
%
%    Input, integer N, the highest polynomial to compute.
%
%    Input, real X(M,1), the evaluation points.
%
%    Output, real V(M,N+1), the values of the Chebyshev polynomials
%    0 through N at X(1:M).
%
  if ( n < 0 )
    v = [];
    return
  end

  v = zeros ( m, n + 1 );

  v(1:m,1) = 1.0;

  if ( n < 1 )
    return
  end

  x = x(:);

  v(1:m,2) = 2.0 * x(1:m,1);

  for j = 2 : n
    v(1:m,j+1) = 2.0 * x(1:m,1) .* v(1:m,j) - v(1:m,j-1);
  end

  return
end


function chx = bbp_pi ( d )

%*****************************************************************************80
%
%% BBP_PI implements the Bailey-Borwein-Plouffe algorithm.
%
%  Discussion:
%
%    The BBP algorithm can be used to compute a a few hex digits of pi starting
%    at any position.
%
%    In particular, bbp_pi ( d ) is a char string of hex digits d+1 through
%    d+13 in the hexadecimal expansion of pi.
%
%    This function does not require extended precision arithmetic or
%    symbolic computation.
%
%    The results are usually accurate to about 11 or 12 of the 13 digits.
%
%    This program is derived from a C program by David H. Bailey dated
%    2006-09-08, http://www.experimentalmath.info/bbp-codes/piqpr8.c
%
%    For many other references: Google "BBP Pi".
%
%  Licensing:
%
%    Copyright (c) 2011, The MathWorks, Inc.
%    All rights reserved.
%
%    Redistribution and use in source and binary forms, with or without
%    modification, are permitted provided that the following conditions are
%    met:
%
%        * Redistributions of source code must retain the above copyright
%          notice, this list of conditions and the following disclaimer.
%        * Redistributions in binary form must reproduce the above copyright
%          notice, this list of conditions and the following disclaimer in
%          the documentation and/or other materials provided with the distribution
%        * Neither the name of the The MathWorks, Inc. nor the names
%          of its contributors may be used to endorse or promote products derived
%          from this software without specific prior written permission.
%
%    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
%    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
%    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
%    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
%    POSSIBILITY OF SUCH DAMAGE.
%
%  Modified:
%
%    27 February 2012
%
%  Author:
%
%    Cleve Moler
%
%  Reference:
%
%    Cleve Moler,
%    Cleve's Corner, "Computing Pi",
%    http://www.mathworks.com/company/newsletters/news_notes/2011/
%
%  Parameters:
%
%    Input, integer D, the number of decimal digits desired.
%
%    Output, symbolic P, the value of pi to D digits.
%
   s1 = series ( 1, d );
   s2 = series ( 4, d );
   s3 = series ( 5, d );
   s4 = series ( 6, d );
   P = 4. * s1 - 2. * s2 - s3 - s4;
   P = P - floor ( P ) + 1.;
   chx = hexchar ( P, 13 );

  return
end
function s = series ( m, d )

%*****************************************************************************80
%
%% SERIES
%
% s = series(m,d) = sum_k 16^(d-k)/(8*k+m)
% using the modular powering technique.
%
  s = 0;
  k = 0;
  t = Inf;

  while k < 13 || t > eps
    ak = 8 * k + m;
    if k < d
      t = powmod(16, d - k, ak) / ak;
     else
       t = 16^(d - k) / ak;
     end
     s = mod(s + t, 1);
     k = k + 1;
   end

  return
end
function r = powmod ( b, p, a )

%*****************************************************************************80
%
%% POWMOD computes mod(b^p,a) without computing b^p.
%
  persistent twop

  if isempty ( twop )
    twop = 2.^(0:25)';
  end

  if a == 1
    r = 0;
    return
  end

  n = find ( p <= twop, 1, 'first' );

  pt = twop ( n );
  r = 1;
  for j = 1 : n
    if p >= pt
      r = mod ( b * r, a );
      p = p - pt;
    end
    pt = 0.5 * pt;
    if pt >= 1
      r = mod ( r * r, a );
    end
  end

  return
end
function chx = hexchar ( s, n )

%*****************************************************************************80
%
%% HEXCHAR returns hex digits.
%
% chx(s,n) = string of the first n hex digits of s.
%
  hx = '0123456789ABCDEF';

  s = abs ( s );

  for j = 1 : n
    s = 16. * mod ( s, 1 );
    chx(j) = hx ( floor ( s ) + 1 );
  end

  return
end


function [nInput,inputMin,inputMax, nTarget, targetMin, targetMax] = preNorm(input, target, inputMax)
% Preprocesses data so that minimum is -1 and maximum is 1.
%
%% Syntax
%   [nInput,inputMin,inputMax] = preNorm(input);
%   [nInput,inputMin,inputMax,nTarget,targetMin,targetMax] = preNorm(input, target);
%   [nInput] = preNorm(input,inputMin,inputMax);
%
%
%% Description
% Function normalizes inputs so that they fall in the interval [-1,1].
% Algorithm:  nInput = 2*(input-inputMin)/(inputMax-inputMin) - 1; If the
% data needs to be normalzed using previously computed minimums and
% maximums, we use: nInput = preNorm(input,inputMin,inputMax);
%
% Input:
% * input           ... the n x D input matrix
% * target/inputMin ... the target vector/if there are 3 input arguments it
%                       will be considered as a vector of minimums
% * inputMax        ... maximums
%
% Output:
% * nInput      ... the n x D normalized input matrix
% * inputMin    ... the row vector containing minimums for each dimension
% * inputMax    ... the row vector containing maximums for each dimension
% * nTarget     ... the normalized target vector
% * targetMin   ... the target minimum
% * targetMax   ... the target maximum
%
% See also:
% postNorm, postNormVar

%% Signature
% * Written by Tomaz Sustar, January 2012

if nargin > 3
  error('Wrong number of arguments.');
end

if nargin==3 % normalize targets if given
  inputMin = target;
  [nInput,inputMin,inputMax] = normalize(input,inputMin,inputMax); %normalize input
else
  [nInput,inputMin,inputMax] = normalize(input); %normalize input
end

if nargin==2 % normalize targets if given
  [nTarget, targetMin, targetMax] = normalize(target);
end

function [nInput,inputMin,inputMax] = normalize(input, inputMin, inputMax)
[n, D] = size(input); % n - number of mesurements, D - input space dimenson

if nargin ~= 3
  inputMin = min(input); % row vector of minimiums
  inputMax = max(input); % row vector of maximums
end

isequal = inputMin==inputMax;
notequal = ~isequal;
if sum(isequal) ~= 0
  warning('Some maximums and minimums are equal. Those inputs will not be transformed.');
  inputMin0 = inputMin.*notequal - 1*isequal; % where equal set minimums to -1
  inputMax0 = inputMax.*notequal + 1*isequal; % and maximums to +1 so the data will not be transformed
else
  inputMin0 = inputMin;
  inputMax0 = inputMax;
end

nInput = 2*(input-repmat(inputMin0,n,1))./repmat((inputMax0-inputMin0),n,1) - 1; % normalize


function [H,mu,SR]=standardEpanechnikovKernelBW(param1,N)
%%STANDARDEPANECHNIKOVKERNELBW Estimate the (univariate or multivariate)
%           kernel bandwidth when approximating a set of samples whose
%           underlying density is (or is approximated as) Gaussian with an
%           Epanechnikov kernel. The Epanechnikov kernel has certain
%           desirable optimality properties.
%
%INPUTS: param1 If inputType=0, then this is:
%              xi A numDimXN set of samples of the distribution from which
%                 a Gaussian kernel estimator should interpolate a PDF. For
%                 multidimensional estimation, there must be >=numDim
%                 samples. Specifically, the sample covariance matrix must
%                 be positive definite.
%              If inputType=1, then this is:
%              SR A root covariance matrix such that SR*SR' equals the
%                 (exact or approximated) covariance matrix of the PDF
%                 being approximated.
%            N If this parameter is provided, then param1 is assumed to be
%              SR and N is the number of samples that are being smoothed.
%              Otherwise, if this is omitted or an empty matrix is passed,
%              param1 is xi.
%
%OUTPUTS: H The numDimXnumDim kernel bandwidth.
%         mu If xi is given, then this is the sample mean. Otherwise, this
%            is an empty matrix.
%         SR The root covariance matrix from the input or computed from xi.
%
%The formulae for the optimal bandwidth of an Epanechnikov kernel given
%samples from an underlying Gaussian distribution is given in Equation 2.3
%of [1]. The function EpanechnikovKernel implements the Epanechnikov
%kernel.
%
%REFERENCES:
%[1] C. Musso, N. Oudjane, and F. LeGland, "Improving regularised particle
%    filters," in Sequential Monte Carlo Methods in Practice, A. Doucet, J.
%    F. G. de Freitas, and N. J. Gordon, Eds., Ch. 12, New York:
%    Springer-Verlag, 2001.
%
%March 2019 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2)
    N=[];
end

nx=size(param1,1);%Dimensionality.

if(isempty(N))%xi is given
    xi=param1;
    N=size(xi,2);
    [mu,S]=calcMixtureMoments(xi);
    SR=cholSemiDef(S,'lower',1);%Not fully triangular. but S=SR*SR'
else%SR is given and N must be given.
    mu=[];
    SR=param1;
end

cn=hypersphereVolume(1,nx);
A=((8/cn)*(nx+4)*2*sqrt(pi)^nx)^(1/(nx+4));
hOpt=A*N^(-1/(nx+4));

H=hOpt*SR*eye(nx);

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 value = lrline ( xu, yu, xv1, yv1, xv2, yv2, dv )

%*****************************************************************************80
%
%% LRLINE determines if a point is left of, right or, or on a directed line.
%
%  Discussion:
%
%    The directed line is parallel to, and at a signed distance DV from
%    a directed base line from (XV1,YV1) to (XV2,YV2).
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    Original FORTRAN77 version by Barry Joe.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Barry Joe,
%    GEOMPACK - a software package for the generation of meshes
%    using geometric algorithms,
%    Advances in Engineering Software,
%    Volume 13, pages 325-331, 1991.
%
%  Parameters:
%
%    Input, real XU, YU, the coordinates of the point whose
%    position relative to the directed line is to be determined.
%
%    Input, real XV1, YV1, XV2, YV2, the coordinates of two points
%    that determine the directed base line.
%
%    Input, real DV, the signed distance of the directed line
%    from the directed base line through the points (XV1,YV1) and (XV2,YV2).
%    DV is positive for a line to the left of the base line.
%
%    Output, integer VALUE, the result:
%    +1, the point is to the right of the directed line;
%     0, the point is on the directed line;
%    -1, the point is to the left of the directed line.
%
  tol = 100.0 * r8_epsilon ( );

  dx = xv2 - xv1;
  dy = yv2 - yv1;
  dxu = xu - xv1;
  dyu = yu - yv1;

  tolabs = tol * max ( abs ( dx ), ...
                 max ( abs ( dy ), ...
                 max ( abs ( dxu ), ...
                 max ( abs ( dyu ), abs ( dv ) ) ) ) );

  t = dy * dxu - dx * dyu + dv * sqrt ( dx * dx + dy * dy );

  if ( tolabs < t )
    value = 1;
  elseif ( -tolabs <= t )
    value = 0;
  else
    value = -1;
  end

  return
end


function qr = quatrot(w);
% QUATROT - returns the quaternion representing the rotation given by
%           the 3D vector w (rotation of ||w|| around the direction given by w)
%
%   qr = quatrot(w);
%
%  ON - 3/99
%

th = norm(w);

qr = [cos(th/2) sin(th/2)*w(:)'/th];


% sgwt_demo1 : SGWT for swiss roll data set
%
% This demo builds the SGWT for the swiss roll synthetic data set. It
% computes a set of scales adapted to the computed upper bound on the
% spectrum of the graph Laplacian, and displays the scaling function and
% the scaled wavelet kernels, as well as the corresponding frame bounds. It
% then computes the wavelets centered on a single vertex, and displays
% them. This essentally reproduces figure 3 from
% Hammond,Vangergheynst, Gribonval 2010.

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

% Create swiss roll point cloud
function sgwt_demo1
close all
fprintf('Welcome to SGWT demo #1\n');

npoints=500;
fprintf('Creating Swiss Roll point cloud with %g points\n',npoints);
dataparams=struct('n',npoints,'dataset',-1','noise',0,'state',0);
r=create_synthetic_dataset(dataparams);
x=rescale_center(r.x);

fprintf('Computing edge weights and graph Laplacian\n');
% Compute Weighted graph adjacency matrix, and graph Laplacian
d=distanz(x);
s=.1;
A=exp(-d.^2/(2*s^2));
L=full(sgwt_laplacian(A));

fprintf('Measuring largest eigenvalue, lmax = ');

%% Design filters for transform
Nscales=4;
lmax=sgwt_rough_lmax(L);
fprintf('%g\n',lmax);

fprintf('Designing transform in spectral domain\n');

designtype='abspline3';
%designtype='mexican_hat';
%designtype='meyer';
%designtype='simple_tf';

[g,t]=sgwt_filter_design(lmax,Nscales,'designtype',designtype);

arange=[0 lmax];
%% Display filter design in spectral domain
figure
sgwt_view_design(g,t,arange);
ylim([0 3])
set(gcf,'position',[0 780,600,300])
%% Chebyshev polynomial approximation
m=50; % order of polynomial approximation
fprintf('Computing Chebyshev polynomials of order %g for fast transform \n',m);
for k=1:numel(g)
  c{k}=sgwt_cheby_coeff(g{k},m,m+1,arange);
end

%% compute transform of delta at one vertex
jcenter=32; % vertex to center wavelets to be shown
fprintf('Computing forward transform of delta at vertex %g\n',jcenter);
N=size(L,1);
d=sgwt_delta(N,jcenter);
% forward transform, using chebyshev approximation
wpall=sgwt_cheby_op(d,L,c,arange);

fprintf('Displaying wavelets\n');
if (exist('OCTAVE_VERSION','builtin')~=0)
    % settings for octave
    msize=5;
    plotchar='s';
else
    % settings for native matlab
    msize=100;
    plotchar='.';
end

cp=[-1.4,-16.9,3.4]; % camera position
%% Visualize result

% show original point
ws=300;
figure;
xp=0; yp=ws+100;
set(gcf,'position',[xp,yp,ws-10,ws+10]);
scatter3(x(1,:),x(2,:),x(3,:),msize,d,plotchar);
set(gcf,'Colormap',[.5 .5 .5;1 0 0]);
clean_axes(cp);
title(sprintf('Vertex %g',jcenter));

% show wavelets
for n=1:Nscales+1
    wp=wpall{n};
    figure
    xp=mod(n,3)*(ws+10);
    yp=(1-floor((n)/3))*(ws+100);
    set(gcf,'position',[xp,yp,ws-10,ws+10]);
    scatter3(x(1,:),x(2,:),x(3,:),msize,wp,plotchar);
    colormap jet
    caxis([-1 1]*max(abs(wp)));
    clean_axes(cp);

    hcb=colorbar('location','north');
    cxt=get(hcb,'Xtick');
    cxt=[cxt(1),0,cxt(end)];
    set(hcb,'Xtick',cxt);
    cpos=get(hcb,'Position');
    cpos(4)=.02; % make colorbar thinner
    set(hcb,'Position',cpos);
    set(hcb,'Position',[.25 .91 .6 .02]);

    if n==1
      title('Scaling function');
    else
      title(sprintf('Wavelet at scale j=%g, t_j = %0.2f',n-1,t((n-1))));

    end
end

function clean_axes(cp)
xlim([-1 1]);ylim([-1 1]);zlim([-1 1]);
set(gca,'Xtick',[-1 0 1]);
set(gca,'Ytick',[-1 0 1]);
set(gca,'Ztick',[-1 0 1]);
axis square
set(gca,'CameraPosition',cp);

% rescale_center
% center input data at origin, then rescale so that all coordinates
% are between -1 and 1
%
% x should be dxN
function r=rescale_center(x)
N=size(x,2);
d=size(x,1);
x=x-repmat(mean(x,2),[1,N]);
c=max(abs(x(:)));
r=x/c;


%  Figure 6.58      Feedback Control of Dynamic Systems, 5e
%                   Franklin, Powell, Emami
%

clear all
close all

num=9;
den=conv([1 0.5],[1 1]);
den=conv(den,[1 2]);
w=logspace(-1,1,500);
[mag,phas]=bode(num,den,w);
[OLGM,OLPM,OLWcg,OLWcp]=margin(mag,phas,w)

%Lead compensator, first guess
numl=[1 1];
denl=0.333*[1 3];
numc=conv(num,numl);
denc=conv(den,denl);
[magc,phasc]=bode(numc,denc,w);
[D1GM,D1PM,D1Wcg,D1Wcp]=margin(magc,phasc,w)
dencl=denc+[0 0 0 numc];
t=0:.1:20;
y=step(numc,dencl,t);
%Design Iteration, next guess
numl=[1 1.5];
denl=0.1*[1 15];
numcc=conv(num,numl);
dencc=conv(den,denl);
[magcc,phascc]=bode(numcc,dencc,w);
[D2GM,D2PM,D2Wcg,D2Wcp]=margin(magcc,phascc,w)
subplot(2,1,1)
loglog(w,mag,'-',w,magc,'--',w,magcc,'-.',w,ones(500,1),'-');
grid;
%xlabel('w (rad/sec)');
ylabel('Magnitude');
title('Fig. 6.58 Bode Plot for lead-compensation design (a) magnitude');
subplot(2,1,2)
semilogx(w,phas,'-',w,phasc,'--',w,phascc,'-.',w,-180*ones(500,1));
grid;
xlabel('\omega (rad/sec)');
ylabel('Phase (deg)');
title('Fig. 6.58 (b) phase');


function [U, L, mu, mse] = pca(X, m)
% Principal component analysis
% Input:
%   X: d x n data matrix
%   m: target dimension
% Output:
%   U: d x m Projection matrix
%   L: m x 1 Eigen values
%   mu: d x 1 mean
%   mse: mean square error
% Written by Mo Chen (sth4nth@gmail.com).
n = size(X,2);
mu = mean(X,2);
Xo = bsxfun(@minus,X,mu);
S = Xo*Xo'/n;                   % 12.3
[U,L] = eig(S);                         % 12.5
[L,idx] = sort(diag(L),'descend');
mse = sum(L)-sum(L(1:m));
U = U(:,idx(1:m));
L = L(1:m);


function d = vgg_H_sampson_distance_sqr(H,X1,X2)

% d = vgg_H_sampson_distance_sqr(H,X1,X2)
%
% Returns an approximation of the squared geometric distance from the
% 4d joint-space point [X1;X2] to the H manifold. See Torr CVIU 97.

if (size(X1) ~= size(X2))
  error('Point sets not same size!');
end

p1 = X1 ./ repmat(X1(3,:),3,1);
p2 = X2 ./ repmat(X2(3,:),3,1);

alg = vgg_H_algebraic_distance(H,p1,p2);

N = size(X1,2);

h = reshape(H',9,1);

G1 = [ H(1,1) - p2(1,:) * H(3,1) ; ...
  H(1,2) - p2(1,:) * H(3,2) ; ...
  -p1(1,:) * H(3,1) - p1(2,:) * H(3,2) - H(3,3) ; ...
  zeros(1,N) ];

G2 = [ H(2,1) - p2(2,:) * H(3,1) ; ...
  H(2,2) - p2(2,:) * H(3,2) ; ...
  zeros(1,N) ; ...
  -p1(1,:) * H(3,1) - p1(2,:) * H(3,2) - H(3,3) ];

magG1 = sqrt(sum(G1 .* G1));
magG2 = sqrt(sum(G2 .* G2));
magG1G2 = sum(G1 .*  G2);

alpha = acos( magG1G2 ./ (magG1 .* magG2) );

D1 = alg(1,:) ./ magG1;
D2 = alg(2,:) ./ magG2;

d = (D1.*D1 + D2.*D2 - 2 * D1 .* D2 .* cos(alpha)) ./ sin(alpha);


function ps = normpdf2( xs, m, C )
% Normal prob. density function (pdf) with arbitrary covariance matrix.
%
% Evaluate the multi-variate density with mean vector m and covariance
% matrix C for the input vector xs.  Assumes that the N datapoints are d
% dimensional.  Then m is dx1 or 1xd, C is dxd, and xs is dxN or NxD where
% N is the number of samples to be evaluated.
%
% USAGE
%  ps = normpdf2( xs, m, C )
%
% INPUTS
%  xs  - points to evaluated (Nxd or dxN)
%  m   - mean vector (dx1 or 1xd)
%  C   - Covariance matrix (dxd)
%
% OUTPUTS
%  ps  - probability density at each x (Nx1)
%
% EXAMPLE
%  ps = normpdf2( randn(10,2), [0 0], eye(2) )
%
% See also NORMPDF
%
% Piotr's Image&Video Toolbox      Version 2.30
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

% get dimensions of data
d=length(m);
if( size(xs,1)~=d ); xs=xs'; end
N=size(xs,2);

if( d==1 ) % fast special case
  ps = 1/sqrt(2*pi*C) * exp(-(xs-m).*(xs-m)/(2*C))';

elseif( rcond(C)<eps ) % if matrix is badly conditioned
  warning('normpdf2: Covariance matrix close to singular.'); %#ok<WNTAG>
  ps = zeros(N,1);

else % get probabilities
  xs = (xs-m(:)*ones(1,N))';
  denom = (2*pi)^(d/2)*sqrt(abs(det(C)));
  mahal = sum( (xs/C).*xs, 2 );
  numer = exp(-0.5*mahal);
  ps = numer/denom;
end


% Optimal doping profile optimization
% Boyd, Kim, Vandenberghe, and Hassibi, "A tutorial on geometric programming"
% Joshi, Boyd, and Dutton, "Optimal doping profiles via geometric programming"
% Written for CVX by Almir Mutapcic 02/08/06
% (a figure is generated)
%
% Determines the optimal doping profile that minimizes base transit
% time in a (homojunction) bipolar junction transistor.
% This problem can be posed as a GP:
%
%   minimize   tau_B
%       s.t.   Nmin <= v <= Nmax
%              y_(i+1) + v_i^const1 <= y_i
%              w_(i+1) + v_i^const2 <= w_i, etc...
%
% where variables are v_i, y_i, and w_i.

% discretization size
M = 50;
% M = 1000; % takes a few minutes to process constraints

% problem constants
g1 = 0.42;
g2 = 0.69;
Nmax = 5*10^18;
Nmin = 5*10^16;
Nref = 10^17;
Dn0 = 20.72;
ni0 = 1.4*(10^10);
WB = 10^(-5);
C =  WB^2/((M^2)*(Nref^g1)*Dn0);

% exponent powers
pwi = g2 -1;
pwj = 1+g1-g2;

% optimization variables
cvx_begin gp
  variables v(M) y(M) w(M)

  % objective function is the base transmit time
  tau_B = C*w(1);

  minimize( tau_B )
  subject to
    % problem constraints
    v >= Nmin;
    v <= Nmax;

    for i = 1:M-1
      if( mod(i,100) == 0 ), fprintf(1,'progress counter: %d\n',i), end;
      y(i+1) + v(i)^pwj <= y(i);
      w(i+1) + y(i)*v(i)^pwi <= w(i);
    end

    y(M) == v(M)^pwj;
    w(M) == y(M)*v(M)^pwi;
cvx_end

% plot the basic optimal doping profile
figure, clf
nbw = 0:1/M:1-1/M;
semilogy(nbw,v,'LineWidth',2);
axis([0 1 1e16 1e19]);
xlabel('base');
ylabel('doping');
text(0,Nmin,'Nmin ', 'HorizontalAlignment','right');
text(0,Nmax,'Nmax ', 'HorizontalAlignment','right');
disp('Optimal doping profile is plotted.')


%% Bivariate Kernel Density Estimation Demonstration
% Several examples show how to use the gkdeb2 function.

%% Distribution with unbounded support
% Distribution with four peaks.
x = [randn(100,1), (randn(100,1)-10)*2;
      randn(100,1)+10, randn(100,1);
      randn(100,1)+10, (randn(100,1)-10)*2;
      randn(100,2)];
gkde2(x);

%% Distribution with upper and lower bounds: uniform distribution
clear
x=rand(10000,2);
% PDF with bounded support
p.xylim=[0 0 1 1];
gkde2(x,p);
% Compare with unbounded PDF estimate
figure;
gkde2(x);

%% Distribution with lower bound only: exponential distribution
clear
x=-log(rand(1000,2));
% PDF with bounded support
p.xylim=[0 0 Inf Inf];
gkde2(x,p);
% Compare with unbounded PDF estimate
figure
gkde2(x);

%% Distribution with lower bound only: log-normal distribution
clear
x=exp(randn(1000,2));
% PDF with bounded support
p.xylim=[0 0 Inf Inf];
gkde2(x,p);
% Compare with unbounded PDF estimate
figure
gkde2(x);

%% Distribution with lower bound only: chi-square distribution
clear
x=randn(1000,2).^2;
% PDF with bounded support
p.xylim=[0 0 Inf Inf];
p.alpha=0.95;
gkde2(x,p);
% Compare with unbounded PDF estimate
figure
p1.alpha=0.95;
gkde2(x,p1);

%%  Distribution with lower bound only: Rayleigh distribution
clear
x=sqrt(randn(2,1000).^2 + randn(2,1000).^2);
% PDF with bounded support
p.xylim=[0 0 Inf Inf];
p.alpha=0.95;
gkde2(x,p);
% Compare with unbounded PDF estimate
figure
p1.alpha=0.95;
gkde2(x,p1);


function [dx, dxGrad] = dynamics(x,u,p)
% [dx, dxGrad] = dynamics(x,u,p)
%
% Computes the dynamics (and gradients) for the simple pendulum
%

q = x(1,:);
dq = x(2,:);

    k = p.k;    c = p.c;
    ddq = -c*dq - k*sin(q) + u;
    dx = [dq;ddq];

if nargout == 2   % Analytic gradients
    nTime = length(u);

    dqGrad = zeros(1,4,nTime); %4 = [time + angle + rate + torque];
    dqGrad(1,3,:) = 1; %gradient dq wrt dq

    ddqGrad = zeros(1,4,nTime);  %4 = [time + angle + rate + torque];
    ddqGrad(1,2,:) = -k*cos(q);   %gradient ddq wrt q
    ddqGrad(1,3,:) = -c;  %gradient ddq wrt dq
    ddqGrad(1,4,:) = 1;  %gradient ddq wrt u

    dxGrad = cat(1, dqGrad, ddqGrad);

end

end


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