function g=TaylorLinearTapering(nBar,sidelobedB,xPoints,a)
%%TAYLORLINEARTAPERING The Taylor tapering is a set of amplitude weights
%          for a continuous linear (narrowband) aperture antenna that will
%          reduce the height of nBar of the close-in sidelobes at a cost of
%          widening the beam. Such a tapering can be discretized and
%          applied to the elements in a linear phased array (An array of
%          antenna elements can be viewed as a discrete approximation to a
%          continuous aperture). This function will provide the tapering
%          values at a set of discrete points given by xPoints (the origin
%          is taken to be the center of the aperture). The radius of the
%          aperture can either be provided or is taken as value of the
%          farthest point provided.
%
%INPUTS: nBar The number of terms to use in the expansion. High values can
%             produce undesirable results.
%  sidelobedB The number of decibels of the ratio of the close-in sidelobe
%             voltages to the main lobe voltage. This must be a negative
%             number. A typical value is -30.
%    xyPoints An NX1 or 1XN set of N points at which the tapering values
%             should be evaluated. The center of the aperture is taken to
%             be the origin.
%           a The radius of the aperture. Tapering weights for points in
%             xPoints outside of the aperture are taken to be zero. If
%             this parameter is omitted or an empty matrix is passed, then
%             the radius is taken to be the distance of the farthest point
%             from the origin in xPoints.
%
%OUTPUTS: g The NX1 set of discretized Taylor tapering values evaluated at
%           the points given in xPoints. All Taylor tapering values are
%           positive and real. The coefficients are not normalized.
%
%This function implements the algorithm in [1].
%
%EXAMPLE 1:
%Here, we evaluate the tapering values for 30dB down on a large array of
%points to see what the tapering looks like.
% nBar=4;
% sidelobedB=-30;
% numPoints=100;
% %Generate points symmetric about the origin. This makes the aperture size
% %1.
% k=0:(numPoints-1);
% xPoints=(k-(1/2)*numPoints+1/2)/numPoints;
% g=TaylorLinearTapering(nBar,sidelobedB,xPoints);
%
% figure(1)
% clf
% plot(xPoints,g)
% h1=xlabel('x');
% h2=ylabel('y');
% title('Taylor Tapering Weight')
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%EXAMPLE 2:
%Here, we consider the array response when using tapering values for 30dB
%sidelobes on a linear array with lambda/2 spacing between elements.
% nBar=4;
% sidelobedB=-30;
% numPoints=30;
% %Generate points symmetric about the origin.
% k=0:(numPoints-1);
% xPoints=(k-(1/2)*numPoints+1/2)/2;
% g=TaylorLinearTapering(nBar,sidelobedB,xPoints);
%
% %Tapering matrix
% T=diag(g);
%
% %Now, display the response with the tapering
% [Rsp,U]=standardUVBeamPattern(T,xPoints,'NormPowGain');
%
% figure(2)
% clf
% plot(U,10*log10(Rsp),'-b','LineWidth',2);
% axis([-1, 1, -40 1])
% h1=xlabel('u');
% h2=ylabel('Amplitude Response (decibels)');
% title('Taylor Weighted Array Response')
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%REFERENCES:
%[1] T. T. Taylor, "Design of line-source antennas for narrow beamwidth and
%    low side lobes," IRE Transactions on Antennas and Propagation, vol. 3,
%    no. 1, pp. 16-28, Jan. 1955.
%
%August 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%After Equation 35 in [1], it is noted that cosh(pi*A) is the side-lobe
%ratio. Thus, we get the following expression for A in terms of the
%sidelobe level in decibels:
eta=10^(sidelobedB/(-20));
A=acosh(eta)/pi;

%The square of Sigma in Equation 41 in [1].
sigma2=nBar^2/(A^2+(nBar-1/2)^2);

%The suggestion for C after Equation 48 in [1].
C=cosh(pi*A);

%Fm holds values of F in Equation 48 for z being an integer>=1.
Fm=zeros(nBar-1,1);
for m=1:(nBar-1)
%Equation 48 contains singularities when z=m is an integer. To evaluate it
%when z is an integer, we first simplify Q in Equation 47 to eliminate the
%singularity.

    %Equation 47 in [1], taking the limit of z to an integer to eliminate
    %the singularity.
    np=[1:(m-1),(m+1):(nBar-1)];
    Qm=(-1)^(m+1)/(2*prod(1-(m./np).^2));

    n=1:(nBar-1);
    Fm(m)=C*Qm*prod(1-m^2./(sigma2*(A^2+(n-1/2).^2)));
end
F0=C;%The case where z=0.

numPoints=length(xPoints);

if(nargin<4||isempty(a))
    %The maximum distance from the origin to a point is taken to be the
    %radius of the aperture.
    a=sqrt(max(sum(xPoints.^2,1)));
end

%The loop below implements Equation 63 in [1].
g=zeros(numPoints,1);
g(:)=F0/(2*pi);
for curPoint=1:numPoints
    rho=norm(xPoints(curPoint));

    if(rho<=a)
        %The normalized radius at this point.
        p=pi*rho/a;

        m=(1:(nBar-1))';
        g(curPoint)=g(curPoint)+(1/pi)*sum(Fm.*cos(m*p));
    end
end
end

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


function a = upshift ( n )

%*****************************************************************************80
%
%% UPSHIFT returns the UPSHIFT matrix.
%
%  Formula:
%
%    if ( J-I == 1 mod ( n ) )
%      A(I,J) = 1
%    else
%      A(I,J) = 0
%
%  Example:
%
%    N = 4
%
%    0 1 0 0
%    0 0 1 0
%    0 0 0 1
%    1 0 0 0
%
%  Rectangular properties:
%
%    A is integral: int ( A ) = A.
%
%    A is a zero/one matrix.
%
%  Square Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is nonsingular.
%
%    A is a permutation matrix.
%
%    If N is even, det ( A ) = -1.
%    If N is odd,  det ( A ) = +1.
%
%    A is unimodular.
%
%    A is persymmetric: A(I,J) = A(N+1-J,N+1-I).
%
%    A is a Hankel matrix: constant along anti-diagonals.
%
%    A is an N-th root of the identity matrix.
%
%    The inverse of A is the downshift matrix.
%
%    A circulant matrix C, whose first row is (c1, c2, ..., cn), can be
%    written as a polynomial in A:
%
%      C = c1 * I + c2 * A + c3 * A**2 + ... + cn * A**n-1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of rows and columns
%    of the matrix.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

  for i = 1 : n
    for j = 1 : n
      if ( i4_modp ( j - i, n ) == 1 )
        a(i,j) = 1.0;
      else
        a(i,j) = 0.0;
      end
    end
  end

  return
end


function [mantissa,exponent,signBit]=decomposeFloat(x,decodeExp,addLeading1)
%%DECOMPOSEFLOAT Given a floating point number, extract the sign but, the
%          mantissa and the exponent as three separate integer quantities.
%          Unlike the function [F,E]=log2(x), this provies the raw bits of
%          the mantissa rather than another float as in the F returned by
%          log2. The floating point value is assumed to be in IEEE 754
%          format, which is documented in [1].
%
%INPUTS: x The real, scalar floating point value to decompose. This can be
%          of class 'single' or 'double'.
% decodeExp The raw exponent of the floating point number is biased by 1023
%          for a double and by 127 for a single. The bits are shifted (from
%          the original double) so that the first bit in the return value
%          exponent is the least significant bit in the exponent. If this
%          is true, then the bias is removed. The default if this parameter
%          is omitted or an empty matrix is passed is true. Note that when
%          decoded, the exponent for 1 is 0, but for 0 it is actually -1023
%          for a double and is -127 for a single.
% addLeading1 For mantissas of normalized numbers, if this is true (the
%          default), then the leading 1 that is implied but not expressly
%          stored in the floating point register will be added. No 1 will
%          be added for subnormal numbers, where it is not implied that
%          there is a leading 1. Note that "leading" means that it is added
%          past the last bit in the mantissa.
%
%OUTPUTS: mantissa The mantissa of the float as a uint64 if x is a double
%                  or uint32 if x is a single. If addLeading1=true, then
%                  there are 53 significant bits for double and 24
%                  significant bits for a single. Otherwise, there are
%                  respectively 52 and 23 significant bits for a double or
%                  for a single.
%         exponent The exponent value. If decodeExp is false, then this is
%                  a uint64 if x is a double or a uint32 if x is a single.
%                  If decodeExp is true, then this is respectively an int64
%                  or an int32 for a double or for a single.
%          signBit This is 1 if the sign bit in x is 1 (negative) and 0 if
%                  the sign bit in x is zero. This is a uint64 if x is a
%                  double or a uint32 if x is a single.
%
%The IEEE 754 standard for floating point arithmetic in [1] formats a
%double as a 64-bit floating point data type as
%[mantissa (52 bits)] [exponent (11 bits)] [sign (1 bit)]
%where bit numbering starts at 0 in the mantissa and goes through 63 with
%the sign bit. For a 32-bit floating point single, the bit ordering is
%[mantissa (23 bits)] [exponent (8 bits)] [sign (1 bit)]
%If exponent is all ones and the mantissa is zero, then the value Inf is
%represented with the sign given by the sign bit. If the exponent is all
%ones and the mantissa is any nonzero value, then a NaN is given.
%
%To interpret the mantissa, consider that there is an implied binary point
%after the highest bit and if exponent is nonzero, then an implied 1. If
%exponent is zero, then it is implied that a 0 leads the binary point.
%Thus, the mantissa represents a fraction >=0 and < 0.5. If one reverses
%the order of the bits in the mantissa (because we wrtie numbers in big-
%endian format), then the number represented by the float is of the form
%1.mantissa*2^(exponent-bias) for a nonzero exponent and
%0.mantissa*2^(-bias) for a zero exponent. The bias is 1023 for a double
%and is 127 for a single.
%
%EXAMPLE:
% [mantissa,exponent,signBit]=decomposeFloat(4568.321)
%One gets mantissa=5022922058913284, exponent=12, signBit=0
%
%EXAMPLE:
%When dealing with integers, the mantissa with the leading 1 added
%multiplied by a power of two (shifted) is the integer value. Consider
% [mantissa,exponent,signBit]=decomposeFloat(11)
% %One gets mantissa=6192449487634432, exponent=3, signBit=0
% %Now, shift until the first nonzero bit is at the start.
% mantissaShifted=bitshift(mantissa,-findPosOfMin1Bit(mantissa)+1)
%One will see that the shifted mantissa is the orignal value, 11. The
%actual amount one has to shift the mantissa also depends on the exponent.
%
%REFERENCES:
%[1] IEEE Standard for Floating Point Arithmetic, Institute for Electrical
%    and Electronics Engineers Std. IEEE Std 754-2008, 29 Aug. 2008.
%
%January 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2||isempty(decodeExp))
    decodeExp=true;
end

if(nargin<3||isempty(addLeading1))
    addLeading1=true;
end

if(~isreal(x)||~isscalar(x))
   error('x must be a real, scalar, floating point value.')
end

if(isa(x,'double'))
    N=typecast(x,'uint64');

    %Get the sign bit.
    theMask=getBitMask(63,'uint64');
    signBit=bitshift(bitand(N,theMask),-63);

    %Select the bits that make up the exponent.
    expMask=getBitMask([52,62],'uint64');
    exponent=bitshift(bitand(N,expMask),-52);

    %Select the bits that make up the mantissa.
    theMask=getBitMask([0,51],'uint64');
    mantissa=bitand(N,theMask);
    if(addLeading1&&exponent~=0&&exponent~=expMask)
        %If a leading 1 is implied by the floating point number, then add
        %it. No leading 1 is added if theExp is the value indicating an INf
        %or a NaN.

        mantissa=bitor(mantissa,bitshift(uint64(1),52));
    end

    if(decodeExp)
        %Get rid of the bias. Note that two exceptions are that +/-0 maps
        %to -1023 instead of 0 and +/-Inf and NaN map to 1024.
        exponent=int64(exponent)-1023;
    end
elseif(isa(x,'single'))
    N=typecast(x,'uint32');

    %Get the sign bit.
    theMask=getBitMask(31,'uint32');
    signBit=bitshift(bitand(N,theMask),-31);

    %Select the bits that make up the exponent.
    expMask=getBitMask([23,30],'uint32');
    exponent=bitshift(bitand(N,expMask),-23);

    %Select the bits that make up the mantissa.
    theMask=getBitMask([0,22],'uint32');
    mantissa=bitand(N,theMask);
    if(addLeading1&&exponent~=0&&exponent~=expMask)
        %If a leading 1 is implied by the floating point number, then add
        %it. No leading 1 is added if theExp is the value indicating an INf
        %or a NaN.

        mantissa=bitor(mantissa,bitshift(uint32(1),23));
    end

    if(decodeExp)
        %Get rid of the bias. Note that two exceptions are that +/-0 maps
        %to -127 instead of 0 and +/-Inf and NaN map to 127.
        exponent=int32(exponent)-127;
    end
else
    error('x must be a single or double floating point value.')
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 [ resultg, resultk, error_est ] = sum_sub_gk ( func, a, b, nsub, ...
  ng, wg, nk, xk, wk )

%*****************************************************************************80
%
%% SUM_SUB_GK carries out a composite Gauss-Kronrod rule.
%
%  Discussion:
%
%    The integral:
%
%      integral ( a <= x <= b ) f(x) dx
%
%    The quadrature rule:
%
%      H = ( B - A ) / NSUB
%      XMID(J) = A + 0.5 * H * ( 2 * J - 1 )
%
%      Sum ( 1 <= J <= NSUB )
%        Sum ( 1 <= I <= NK )
%          WK(I) * F ( XMID(J) + 0.5 * H * XK(I) )
%
%    The Gauss-Legendre weights should be computed by LEGCOM or LEGSET.
%    The Kronrod abscissas and weights should be computed by KRONSET.
%
%    The orders of the Gauss-Legendre and Kronrod rules must satisfy
%    NK = 2 * NG + 1.
%
%    The Kronrod rule uses the abscissas of the Gauss-Legendre rule,
%    plus more points, resulting in an efficient and higher order estimate.
%
%    The difference between the Gauss-Legendre and Kronrod estimates
%    is taken as an estimate of the error in the approximation to the
%    integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, external FUNC, the name of the function which
%    evaluates the integrand.  The function must have the form
%      function func ( x ).
%
%    Input, real A, B, the lower and upper limits of integration.
%
%    Input, integer NSUB, the number of equal subintervals into
%    which the finite interval (A,B) is to be subdivided for
%    higher accuracy.  NSUB must be at least 1.
%
%    Input, integer NG, the order of the Gauss-Legendre rule.
%    NG must be at least 1.
%
%    Input, real WG(NG), the weights of the
%    Gauss-Legendre rule.
%
%    Input, integer NK, the order of the Kronrod rule.
%    NK must be at least 1.
%
%    Input, real XK(NK), the abscissas of the
%    Kronrod rule.
%
%    Input, real WK(NK), the weights of the
%    Kronrod rule.
%
%    Output, real RESULTG, the approximate value of the
%    integral based on the Gauss-Legendre rule.
%
%    Output, real RESULTK, the approximate value of the
%    integral based on the Kronrod rule.
%
%    Output, real ERROR_EST, an estimate of the approximation
%    error.  This is computed by taking the sum of the absolute values of
%    the differences between the Gauss-Legendre and Kronrod rules
%    over each subinterval.  This is usually a good estimate of
%    the error in the value RESULTG.  The error in the Kronrod
%    estimate RESULTK is usually much smaller.
%
  resultg = 0.0;
  resultk = 0.0;
  error_est = 0.0;

  if ( a == b )
    return
  end

  if ( nk ~= 2 * ng + 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'SUM_SUB_GK - Fatal error!\n' );
    fprintf ( 1, '  NK must equal 2 * NG + 1.\n' );
    fprintf ( 1, '  The input value was NG = %d\n', ng );
    fprintf ( 1, '  The input value was NK = %d\n', nk );
    error (  'SUM_SUB_GK - Fatal error!' );
  end

  h = ( b - a ) / nsub;

  for j = 1 : nsub

    xmid = a + 0.5 * h * ( 2 * j - 1 );

    partg = 0.0;
    partk = 0.0;

    for i = 1 : nk

      xval = xmid + 0.5 * h * xk(i);
      fk = func ( xval );
      partk = partk + 0.5 * h * wk(i) * fk;

      if ( mod ( i, 2 ) == 0 )
        partg = partg + 0.5 * h * wg(i/2) * fk;
      end

    end

    resultg = resultg + partg;
    resultk = resultk + partk;
    error_est = error_est + abs ( partk - partg );

  end

  return
end


function node_xyz = sphere_grid_q9_node_xyz ( nelemx, nelemy )

%*****************************************************************************80
%
%% SPHERE_GRID_Q9_NODE_XYZ produces node coordinates for a Q9 sphere grid.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NELEMX, NELEMY, the number of elements along the
%    X and Y directions.
%
%    Output, real NODE_XYZ(3,4*NELEMX*NELEMY-2*NELEMX+2),
%    the node coordinates.
%
  node = 0;

  node = node + 1;
  node_xyz(1,node) =  0.0;
  node_xyz(2,node) =  0.0;
  node_xyz(3,node) = -1.0;

  for j = 2 * nelemy : -1 : 2

    phi = ( j - 1 ) * pi / ( 2 * nelemy );

    for i = 1 : 2 * nelemx

      theta = ( i - 1 ) * 2.0 * pi / ( 2 * nelemx );

      node = node + 1;
      node_xyz(1,node) = cos ( theta ) * sin ( phi );
      node_xyz(2,node) = sin ( theta ) * sin ( phi );
      node_xyz(3,node) =                 cos ( phi );

    end
  end

  node = node + 1;
  node_xyz(1,node) =  0.0;
  node_xyz(2,node) =  0.0;
  node_xyz(3,node) =  1.0;

  return
end


function [ region_image ] = average_feature_region(im, region_size)
% compute cell wise averages, where a cell is a region_size*region_sized
% region in the image. Input can be uint8t, single or double matrices
% of arbitrary dimension

region_area = region_size.^2;

if isa(im,'double') || isa(im,'single') || isa(im,'gpuArray')
    maxval = 1.0;
elseif isa(im,'unit8')
    maxval = 255;
end

% compute the integral image
iImage = integralVecImage(im);

% region indices
i1 = (region_size:region_size:size(im,1)) + 1;
i2 = (region_size:region_size:size(im,2)) + 1;

% sum over region, divided by number of elements, and normalize to [0,1]
% range if integer image
region_image = (iImage(i1,i2,:,:) - iImage(i1,i2-region_size,:,:) - iImage(i1-region_size,i2,:,:) + iImage(i1-region_size,i2-region_size,:,:)) ./ (region_area * maxval);

end


function p = predictOneVsAll(all_theta, X)
%PREDICT Predict the label for a trained one-vs-all classifier. The labels
%are in the range 1..K, where K = size(all_theta, 1).
%  p = PREDICTONEVSALL(all_theta, X) will return a vector of predictions
%  for each example in the matrix X. Note that X contains the examples in
%  rows. all_theta is a matrix where the i-th row is a trained logistic
%  regression theta vector for the i-th class. You should set p to a vector
%  of values from 1..K (e.g., p = [1; 3; 1; 2] predicts classes 1, 3, 1, 2
%  for 4 examples)

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

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

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

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

z = X * all_theta';

h = sigmoid(z);

[pval p] = max(h, [], 2);

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

end


function gnuplot_taylor_test ( )

%*****************************************************************************80
%
%% GNUPLOT_TAYLOR_TEST generates a field on a regular grid and plots it.
%
%  Location:
%
%    http://people.sc.fsu.edu/~jburkardt/m_src/navier_stokes_2d_exact/gnuplot_taylor_test.m
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 January 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'GNUPLOT_TAYLOR_TEST:\n' );
  fprintf ( 1, '  Taylor Vortex Flow:\n' );
  fprintf ( 1, '  Generate a velocity field on a regular grid.\n' );
  fprintf ( 1, '  Store in GNUPLOT data and command files.\n' );

  x_lo = 0.5;
  x_hi = 2.5;
  x_num = 21;

  y_lo = 0.5;
  y_hi = 2.5;
  y_num = 21;

  [ x, y ] = grid_2d ( x_num, x_lo, x_hi, y_num, y_lo, y_hi );

  nu = 1.0;
  rho = 1.0;
  n = x_num * y_num;
  t = 0.0;

  [ u, v ] = uvp_taylor ( nu, rho, n, x, y, t );

  header = 'taylor';
  s = 0.10;
  ns2de_gnuplot ( header, n, x, y, u, v, s );

  return
end


function [A, b, x, ProbInfo] = PRdiffusion(varargin)
% PRdiffusion Generates data for use in an inverse diffusion problems
%
% [A, b, x, ProbInfo] = PRdiffusion
% [A, b, x, ProbInfo] = PRdiffusion(n)
% [A, b, x, ProbInfo] = PRdiffusion(n, options)
%
% This function generates a 2D inverse diffusion problem on a uniform
% finite-element mesh with 2*(n-1)^2 triangular elements; think of the
% domain as an n-by-n pixel grid with two triangular elements in each pixel.
%
% The data represents a function u(t) on the grid at time t = Tfinal.
% The goal of the inverse problem is to compute the function u(t) at
% time t = 0 which, when diffused, produces the data.
%
% The forward problem is a very simple diffusion problem
%    du/dt = u_xx + u_yy,   0 < t < Tfinal
% with homogenous Neumann boundary conditions.  It is solved by means of
% the Crank-Nicolson-Galerkin finite-element method.  The inverse problem
% is to compute the initial condition, the function u(0) at time t = 0,
% from the solution u(t) at time t = Tfinal.
%
% The functions u(0) and u(Tfinal) are represented by the vecors x and b,
% resp., which hold the values at the corners of the finite elements.
% Both vectors have a total of n^2 elements.
%
% The severity of the problem increases with Tfinal and does not depend on
% Tsteps.
%
% Input:
%  n       - The grid has n-1 pixels in each direction, and n must be an
%            integer.  Default: n = 128.  There are 2*(n-1)^2 finite
%            elements, and the number of unknowns is n^2.
%  options - Parameters that define the problem
%              Tfinal : diffusion time; default Tfinal = 0.01.
%              Tsteps : number of time steps; default Tsteps = 100.
%
% Output:
%  A -  Function handle for the forward and adjoint problem.
%  b -  Vector that represents the solution u(t) at t = Tfinal.
%  x -  Vector that represents the initial condition u(t) at t = 0.
%  ProbInfo -  Structure containing some information about problem
%                problemType : type of test problem generated
%                              (in this case: 'diffusion')
%                xType       : solution type (in this case 'fem')
%                bType       : data type (in this case 'fem')
%                elmtab      : table of FEM elements
%                elmX        : X-coordinates of element grid
%                elmY        : Y-coordinates of element grid
%
% See also: PRblur, PRinvinterp2, PRnmr, PRseismic, PRspherical, PRtomo,
% PRnoise, PRshowb, PRshowx

% Silvia Gazzola, University of Bath
% Per Christian Hansen, Technical University of Denmark
% James G. Nagy, Emory University
% April, 2018.

% Based on original code by Allan P. Engsig-Karup, DTU Compute.

% This file is part of the IR Tools package and is distributed under the
% 3-Clause BSD Licence. A separate license file should be provided as part
% of the package.

% Set default values for options.
defaultopt = struct('Tfinal', 0.01, 'Tsteps', 100);

% If input is 'defaults,' return the default options in A.
if nargin == 1 && nargout <= 1 && strcmp(varargin,'defaults')
    A = defaultopt;
    return;
end

% Check for acceptable number of optional input arguments.
switch length(varargin)
    case 0
        n = []; options = [];
    case 1
        if isa(varargin{1}, 'double')
            n = varargin{1}; options = [];
        else
            n = []; options = varargin{1};
        end
    case 2
        if isa(varargin{1}, 'double')
            n = varargin{1}; options = varargin{2};
        else
            n = varargin{2}; options = varargin{1};
        end
    otherwise
        error('Too many input parameters')
end

if isempty(options)
    options = defaultopt;
end

options = PRset(defaultopt, options);
Tfinal = PRget(options, 'Tfinal', [], 'fast');
Tsteps = PRget(options, 'Tsteps', [], 'fast');

if isempty(n), n = 128; end

% Create rectangular mesh consisting of uniformly distributed triangles.
[elmX,elmY] = meshgrid(linspace(0,1,n));
elmX = elmX(:);
elmY = elmY(:);

% Element table for uniformly distributed triangles in a rectangular domain.
elmtab = zeros(2*(n-1)^2,3);
count = 0;
for j = 1:n-1
    for i = 1:n-1
        elmtab(count+(1:2),:) = [i   i+1+n i+n;
                                 i+1 i+1+n i     ] + (j-1)*n;
        count = count+2;
    end
end

% Initial condition.
x = 0.7*exp( -((elmX-0.4)/0.12).^2 - ((elmY-0.5)/0.15).^2) + ...
        exp( -((elmX-0.7)/0.1 ).^2 - ((elmY-0.4)/0.08).^2);

% Create the matrices.
dt = Tfinal/Tsteps;
[AA,CC] = assembly(elmX,elmY,elmtab);
S = CC - 0.5*dt*AA;
R = CC + 0.5*dt*AA;

% A is a function handle to the function that carries out the forward
% operation, i.e., interpolates from the regular grid to the randon points,
% or the corresponding adjoint operation (representing A').
A = @(xx,tflag) OPdiffusion(xx,R,S,Tsteps,tflag);

% The right-hand side (the data) ...
b = A(x,'notransp');

ProbInfo.problemType = 'diffusion';
ProbInfo.bType = 'fem';
ProbInfo.xType = 'fem';
ProbInfo.elmtab = elmtab;
ProbInfo.elmX = elmX;
ProbInfo.elmY = elmY;
ProbInfo.R = R;                  %PCH
ProbInfo.S = S;

% SUBFUNCTIONS -----------------------------------------------------------

function [A,C] = assembly(x,y,elmtab)
% Generate linear system coefficient matrix and right hand side vector.
% Symmetry is not exploited.

P = size(elmtab,1);
iL = zeros(3*3*P,1);
jL = iL;
AL = iL;
CL = iL;
count = 0;
for p = 1:P
    [delta,abc] = basfun(p,x,y,elmtab);
    for r = 1:3
        i = elmtab(p,r);
        for s = 1:3   % Does not exploit symmetry.
            j = elmtab(p,s);
            Ars = 1/(4*abs(delta))*(abc(r,2)*abc(s,2) + abc(r,3)*abc(s,3));
            if r == s
                Crs = abs(delta)/6;
            else
                Crs = abs(delta)/12;
            end
            count = count + 1;
            iL(count) = i;
            jL(count) = j;
            AL(count) = Ars;
            CL(count) = Crs;
        end
    end
end
iL = iL(1:count);
jL = jL(1:count);
AL = AL(1:count);
A = sparse(iL,jL,AL);
C = sparse(iL,jL,CL);

function [delta,abc] = basfun(p,x,y,elmtab)
% For a given element compute the geometric properties of the element.

xc = x(elmtab(p,:));
yc = y(elmtab(p,:));
delta = 0.5*( xc(2)*yc(3) - yc(2)*xc(3) - (xc(1)*yc(3) - ...
              yc(1)*xc(3)) + xc(1)*yc(2) - yc(1)*xc(2)      );

% Vectorized output.
j   = [2 3 1]';
k   = [3 1 2]';
at  = xc(j).*yc(k) - xc(k).*yc(j);
bt  = yc(j) - yc(k);
ct  = xc(k) - xc(j);
abc = [at bt ct];


 function ni = trl_curvature(yi, bi, ri, li, ctype)
%function ni = trl_curvature(yi, bi, ri, li, ctype)
%|
%| Compute surrogate parabola curvatures for Poisson transmission model
%| ctype:
%|	oc	erdogan's optimal curvatures
%|	pc	precomputed curvatures, ala trpl3
%|	nc	newton curvatures
%|
%| fix: align with C version of trpl2,3
%| The minimum returned curvature will be zero.
%| It is the user's responsibility to impose additional bounds
%| if desired for certain algorithms.
%|
%| Copyright 2002-1-28, Jeff Fessler, University of Michigan

if nargin == 1 && streq(yi, 'test'), trl_curvature_test, return, end
if nargin < 4, ir_usage, end

[h dh] = trl_h_dh;

if ~isvar('ctype') || isempty(ctype)
	ctype = 'oc'
end

% Compute optimal surrogate parabola curvatures
% for Poisson transmission model based on Erdogan's formula.
switch ctype
case 'oc'

	% compute curvature at l=0
	ni_max = zeros(size(yi));
	if numel(bi) == 1 % scalar bi (must be positive!)
		ni_max = bi .* (1 - yi .* ri ./ (bi + ri).^2);
	else
		i0 = bi > 0;
		if numel(ri) == 1
			rii = 1;
		else
			rii = ri(i0);
		end
		ni_max(i0) = bi(i0) .* (1 - yi(i0) .* rii ./ (bi(i0) + rii).^2);
	end
	ni_max = max(ni_max, 0);
	ni = ni_max;

	if 0
		il0 = li <= 0;
	else % trick in C program due to numerical precision issues
		il0 = li < 0.1;
	end

	tmp = h(yi,bi,ri,li) - h(yi,bi,ri,0) - li .* dh(yi,bi,ri,li);
	i = ~il0;
	ni(i) = 2 ./ li(i).^2 .* max(tmp(i),0);

	if any(ni > ni_max)
	%	plot([ni_max(:) ni(:) ni(:)>ni_max(:)])
		warning 'large ni'
	end

% Precomputed approximating parabola curvatures
% for Poisson transmission model.
% The minimum returned curvature will be zero.
% This is compatible with trpl/trp_init_der02_sino() in aspire.
case 'pc'

	% ni = (yi-ri)^2 / yi, if yi > ri >= 0 and bi > 0
	ii = (yi > ri) & (ri >= 0) & (bi > 0); % good rays
	ni = zeros(size(yi));
	ni(ii) = (yi(ii) - ri(ii)).^2 ./ yi(ii);

% newton curvatures (current 2nd derivative)
case 'nc'
	bel = bi .* exp(-li);
	yb = bel + ri;
	ni = (1 - ri.*yi./yb.^2) .* bel;

otherwise
	fail 'bug'
end

% trl_h_dh()
% transmission Poisson likelihood function
function [h, dh] = trl_h_dh
h = @(y,b,r,l) y .* log(b.*exp(-l)+r) - (b.*exp(-l)+r);
dh = @(y,b,r,l) (1 - y ./ (b.*exp(-l)+r)) .* b.*exp(-l);

% trl_curvature_test()
% demonstrate an example surrogate parabola!
function trl_curvature_test
[h dh] = trl_h_dh;
if 0
	l = linspace(0,2,101)';
	n = trl_curvature(2+0*l, 3, 3, l, 'oc');
	plot(l, n, '-o'), xlabel l, ylabel n
else
%	y = 4; b = 3; r = 1; ln = 3.8;
%	y = 2; b = 3; r = 3; ln = 0.05;
	y = 2; b = 3; r = 1; ln = 1;
	n.oc = trl_curvature(y, b, r, ln, 'oc');
	n.pc = trl_curvature(y, b, r, ln, 'pc');
	l = linspace(-0.2,5,101)';
	hn = h(y,b,r,ln);
	dhn = dh(y, b, r, ln);%
	hl = h(y,b,r,l);
	q.oc = hn + dhn * (l-ln) - 0.5 * n.oc * (l-ln).^2;
	q.pc = hn + dhn * (l-ln) - 0.5 * n.pc * (l-ln).^2;
	if im
		clf, plot(l, hl, '-', l, q.oc, '--', l, q.pc, '-.', ln, hn, 'o')
		grid
		axis([minmax(l)' minmax(hl)'])
		legend('h(l)',	sprintf('q_o(l) n_i=%g', n.oc), ...
				sprintf('q_p(l) n_i=%g', n.pc))
	end
end


function value = ellipse_circumference_2d ( r1, r2 )

%*****************************************************************************80
%
%% ELLIPSE_CIRCUMFERENCE_2D returns the circumference of an ellipse in 2D.
%
%  Discussion:
%
%    There is no closed formula for the circumference of an ellipse.
%
%    Defining the eccentricity by
%
%      E = sqrt ( 1 - ( r2 / r1 )**2 )
%
%    where R1 and R2 are the major and minor axes, then
%
%      circumference
%        = 4 * R1 * E(K,2*PI)
%        = R1 * Integral ( 0 <= T <= 2*PI ) sqrt ( 1 - E**2 * sin**2 ( T ) ) dT
%
%    This integral can be approximated by the Gauss-Kummer formula.
%
%  Integration region:
%
%    Points (X,Y) such that
%
%      ( ( X - XC ) / R1 )**2 + ( ( Y - YC ) / R2 )**2 <= 1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 November 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    John Harris and Horst Stocker,
%    Handbook of Mathematics and Computational Science,
%    Springer, 1998.
%
%  Parameters:
%
%    Input, real R1, R2, the major and minor semi-axes.
%
%    Output, real VALUE, the circumference of the ellipse.
%
  if ( r1 == r2 ) then
    value = 2.0 * pi * r1;
    return
  end
%
%  Compute the eccentricity of the ellipse.
%
  e = sqrt ( 1.0 - ( min ( r1, r2 ) / max ( r1, r2 ) )^2 );

  value = 1.0;
  term = value;
  i = 0;

  while ( 1 )

    i = i + 1;
    term = term * ( 2 * i - 3 ) * ( 2 * i - 1 ) * e * e / ( 2 * 2 * i * i );

    if ( abs ( term ) <= eps * ( abs ( value ) + 1.0 ) )
      break
    end

    value = value + term;

  end

  value = 2.0 * pi * max ( r1, r2 ) * value;

  return
end


function G=gaussFilter(segma,kSize)
% Creates a 1-D Gaussian kernel of a standard deviation 'segma' and a size
% of 'kSize'.
%
% In theory, the Gaussian distribution is non-zero everywhere. In practice,
% it's effectively zero at places further away from about three standard
% deviations. Hence the reason why the kernel is suggested to be truncated
% at that point.
%
% The 2D Gaussian filter is a complete circular symmetric operator. It can be
% seperated into x and y components. The 2D convolution can be performed by
% first convolving with 1D Gaussian in the x direction and the same in the
% y direction.
%
% Author: Mohd Kharbat at Cranfield Defence and Security
% mkharbat(at)ieee(dot)org , http://mohd.kharbat.com
% Published under a Creative Commons Attribution-Non-Commercial-Share Alike
% 3.0 Unported Licence http://creativecommons.org/licenses/by-nc-sa/3.0/
%
% October 2008

if nargin<1
    segma=1;
end
if nargin<2
    kSize=2*(segma*3);
end

x=-(kSize/2):(1+1/kSize):(kSize/2);
G=(1/(sqrt(2*pi)*segma)) * exp (-(x.^2)/(2*segma^2));


classdef spaces
% Utility functions to work with vector spaces

    methods(Static)

        function result  = insersection_space(A, B)
            % Let A and B represent vector spaces
            % The function returns basis for their intersection
            if size(A, 1) ~= size(B, 1)
                error('The ambient space must be same.');
            end

            % Orthogonalize the two bases
            A = orth(A);  % A is n x a
            B = orth(B);  % B is n x b
            % Count the rank of each of them
            % After orthogonalization number of columns may have reduced
            rank_a = size(A, 2);
            rank_b = size(B, 2);
            % Combine them
            C = [A B]; % C is n x (ra + rb)
            % Compute the null space of the whole thing
            D = null(C); % C * D = 0. D is (ra + rb) x  m
            % m is the nullity of C
            % Pick up the first rank_a rows from D
            D2 = D(1:rank_a, :); % ra * m
            % Multiply with A
            result = A * D2 ; % n * m.
            % We get the basis we were looking for
        end

        function result = orth_complement(A, B)
            % Find orthogonal complement of A in B.
            if size(A, 1) ~= size(B, 1)
                error('The ambient space must be same.');
            end
            % Orthogonalize A to make sure that it is full rank.
            A  = orth(A);
            rank_a = size(A,2);
            C = [A B];
            [Q, R] = qr(C, 0);
            % Leave the first rank_a columns from A
            result = Q(:, rank_a+ 1:end);
        end

        function result = principal_angles_orth_cos(A, B)
            % assumes that A and B are orthonormal bases
            % Compute the matrix of inner products of bases of A and B.
            M = A' * B;
            % Compute the SVD of M. The singular values are the cosine of principal angles
            result = svd(M);
            % make sure that result is bounded by 1.
            result = min(1, result);
        end

        function result = principal_angles_cos(A, B)
            % Finds the principal angles between the subspaces spanned by A and B
            % References
            % - http://in.mathworks.com/matlabcentral/newsreader/view_thread/284282
            if size(A, 1) ~= size(B, 1)
                error('The ambient space must be same.');
            end
            A = orth(A);
            B = orth(B);
            result = spx.la.spaces.principal_angles_orth_cos(A, B);
        end

        function result = principal_angles_radian(A, B)
            % Returns the principal angles in radians
            s = spx.la.spaces.principal_angles_cos(A, B);
            % Return the angles as cos inverse of singular values
            % ensure that cos-theta values are <= 1. Otherwise complex numbers may appear.
            result = acos(min(1, s));
        end

        function result = principal_angles_degree(A, B)
            % Returns the principal angles in degrees
            radians = spx.la.spaces.principal_angles_radian(A, B);
            % Return the angles as cos inverse of singular values
            result = rad2deg(radians);
        end

        function result = smallest_angle_cos(A, B)
            % Returns the smallest angle between two subspaces as cos(theta)
            s = spx.la.spaces.principal_angles_cos(A, B);
            result = s(1);
        end

        function result = smallest_angle_orth_cos(A, B)
            % Returns the smallest angle between two subspaces as cos(theta)
            % assumes A and B are orthonormal bases
            s = spx.la.spaces.principal_angles_orth_cos(A, B);
            result = s(1);
        end

        function result = smallest_angle_rad(A, B)
            % Returns the smallest angle between two subspaces in radians
            cos_theta = spx.la.spaces.smallest_angle_cos(A, B);
            result = acos(cos_theta);
        end

        function result = smallest_angle_deg(A, B)
            % Returns the smallest angle between two subspaces in degree
            theta = spx.la.spaces.smallest_angle_rad(A, B);
            result = rad2deg(theta);
        end

        function result = smallest_angles_cos(subspaces, d)
            % subspaces is either a cell array of bases or a concatenated matrix.
            % d is the dimension of each subspace [needed only if all bases are concatenated]
            if iscell(subspaces)
                bases = subspaces;
                % number of subspaces
                s = numel(subspaces);
                % the ambient dimension
                m = size(bases{1}, 1);
            else
                if nargin < 2
                    error('Dimension of each subspace must be specified.');
                end
                [m, n] = size(subspaces);
                if mod(n, d) ~= 0
                    error('n must be multiple of d');
                end
                % number of subspaces
                s = n /d;
                % create the cell array for bases
                bases = cell(s, 1);
                for i=0:s-1
                    %i-th subspace basis
                    si = subspaces(:, i*d + (1:d));
                    bases{i+1} = si;
                end
            end
            % Orthogonalize all subspaces
            for i=1:s
                bases{i} = orth(bases{i});
            end
            % The smallest angles result matrix
            result = eye(s);
            for i=1:s
                si = bases{i};
                for j=i+1:s
                    % j-th subspace
                    sj = bases{j};
                    result(i, j) = spx.la.spaces.smallest_angle_orth_cos(si, sj);
                    result(j, i) = result(i, j);
                end
            end
        end

        function result = smallest_angles_rad(subspaces, d)
            if nargin < 2
                % subspace dimensions are unspecified
                d = -1;
            end
            result = spx.la.spaces.smallest_angles_cos(subspaces, d);
            result = acos(result);
        end

        function result = smallest_angles_deg(subspaces, d)
            if nargin < 2
                % subspace dimensions are unspecified
                d = -1;
            end
            result = spx.la.spaces.smallest_angles_rad(subspaces, d);
            result = rad2deg(result);
        end

        function result = subspace_distance(A, B)
            % The distance between two subspaces based on Grassmannian
            % References
            % - http://math.stackexchange.com/questions/198111/distance-between-real-finite-dimensional-linear-subspaces
            if size(A, 1) ~= size(B, 1)
                error('The ambient space must be same.');
            end
            A = orth(A);
            B = orth(B);
            if size(A, 2) ~= size(B, 2)
                error('The two subspaces must be of same dimensions');
            end
            % Compute the projection matrices for the two spaces
            PA = A*A';
            PB = B*B';
            D = PA  - PB;
            % We return the operator norm of D as the distance between the two subspaces.
            result = norm(D);
        end

        function result = is_in_range_orth(v, U)
            % Returns if v is in the range of U where U is a unitary matrix
            nv = norm(v);
            if nv == 0
                % zero vector is always in the column space of U
                result = true;
                return;
            end
            % Compute the projection of v into the space spanned by U.
            pv = U (U' * v);
            % Compute the difference [projection to the orthogonal complement of U]
            d = v - pv;
            % Compute it's norm
            nd = norm(d);
            % Verify that the norm of difference is indeed very small
            result = nd <= 1e-6 * nv;
        end

        function result = is_in_range(v, A)
            % Returns if v is in the range of an arbitrary matrix A
            result = is_in_range_orth(v, orth(A));
        end

        function result = find_basis(A)
            % Returns a (not necessarily orthogonal) basis of A from columns of A
            [R, pivot_cols] = rref(A);
            [m, n] = size(A);
            i = 1;
            %pivot_cols = false(n, 1);
            %for j=1:n
            %    if R(i, j) == 1
            %        % Add the column containing the leading one
            %        pivot_cols(j) = true;
            %        % Move on to find the 1 in next row
            %        i = i + 1;
            %    end
            %end
            % Return a basis
            result = A (:, pivot_cols);
        end

        function [E, R] = elim(A)
            % References
            % - http://web.mit.edu/18.06/www/Course-Info/Mfiles/elim.m
            % Factorize: E R  = A
            % where E is a product of elementary matrices and
            % R is the row reduced echelon form
            [m, n] = size(A);
            I = eye(m);
            RE = rref([A I]);
            R = RE(:, 1:n);
            E = RE(:, (n+1):m+n);
        end

        function N = null_basis(A)
            % Returns a null basis for A
            % References
            % - http://web.mit.edu/18.06/www/Course-Info/Mfiles/nulbasis.m
            [m, n] = size(A);
            [R, pivot_cols] = rref(A, sqrt(eps));
            r = length(pivot_cols);
            % The columns of A which are not part of pivots
            freecol = 1:n;
            freecol(pivot_cols) = [];
            % Create space for storing the null basis
            N = zeros(n, n-r);
            N(freecol, : ) = eye(n-r);
            N(pivot_cols,  : ) = -R(1:r, freecol);
        end

        function [col_space, null_space, row_space, left_null_space] = four_bases(A)
            % Returns bases for the four spaces associated with the matrix A
            % These are not necessarily orthonormal bases
            [m, n] = size(A);
            [R, pivot_cols] = rref(A, sqrt(eps));
            rank_a = length(pivot_cols);
            % The first rank_a rows of the echelon matrix form the row space
            row_space = R(1:rank_a, :)';
            % The columns of A indexed by the pivot columns form the column space
            col_space = A(:, pivot_cols);

            % Computation of the null space
            % The columns of A which are not part of pivots
            freecol = 1:n;
            freecol(pivot_cols) = [];
            % Allocate memory for the null space basis
            null_space = zeros(n, n-r);
            null_space(freecol, : ) = eye(n-r);
            null_space(pivot_cols,  : ) = -R(1:r, freecol);

            left_null_space = E((r+1):m, :)';
        end

        function [col_space, null_space, row_space, left_null_space] = four_orth_bases(A)
            % Prepares the four bases using SVD
            [U, S, V] = svd(A);
            % Finding the rank of A
            s = diag(S);
            tol = max(size(A))*eps(max(s));
            r = sum(s > tol);
            col_space = U(:, 1:r);
            null_space = U(:, r+1:m);
            row_space = V(:, 1:r);
            left_null_space = V(:, r+1:n);
        end

        function Y = k_dim_to_n_dim(X, n, indices)
            % Maps the data in K dimensions to N-dimensions.
            [k, d] = size(X);
            if nargin < 2
                error('Target dimension must be specified');
            end
            if n < k
                error('n must be larger than k');
            end
            if nargin < 3
                indices = 1:k;
            end
            if ~isvector(indices)
                error('indices must be a vector.');
            end
            if numel(indices) > k
                error('Number of indices must be k');
            end
            if length(unique(indices))<length(indices)
                error('There must be exactly k unique entries in indices');
            end
            if max(indices) > n || min(indices) < 1
                error('Indices cannot point outside 1:n ');
            end
            Y = zeros(n, d);
            Y(indices, :) = X;
        end

        function [A, B, C] = three_spaces_at_angle(N, theta)
            if ~mod(N, 3) == 0
                error('N must be divisible by 3');
            end
            % First create two random orthonormal vectors
            X = orth(randn(N, 3));
            % Then tilt the second one w.r.t. first
            a1 = X(:, 1);
            a2 = X(:, 2);
            a3 = X(:, 3);
            p = cos(theta);
            % first vector for second space
            b1 = sqrt(1 - p^2) * a2 + p * a1;
            % first vector for third space
            c1_1 = p;
            c1_2 = p * (1 - p) / sqrt(1 - p^2);
            c1_3 = sqrt(1 - c1_1^2 - c1_2^2);
            c1 = c1_1 * a1 + c1_2 * a2 + c1_3 * a3;
            X = [a1 b1 c1];
            % Find the orthogonal complement of X
            [U S V] = svd(X);
            Y = U(:, 4:end);
            [~, n] = size(Y);
            % Distribute vectors from Y into A and B
            A = [a1 Y(:, 1:n/3)];
            B = [b1 Y(:, n/3 + (1:n/3))];
            C = [c1 Y(:, 2*n/3 + (1:n/3))];
        end

        function [A, B, C] = three_disjoint_spaces_at_angle(N, theta)
            X = eye(4);
            R1 = [cos(theta) -sin(theta); sin(theta) cos(theta)];
            a1 = [1 ; 0];
            a2 = R1*a1;
            a3 = R1*a2;
            theta2 = deg2rad(59);
            R2 = [cos(theta2) -sin(theta2); sin(theta2) cos(theta2)];
            b1 = [1 ; 0];
            b2 = R2*b1;
            b3 = R2*b2;
            z = zeros(2, 1);
            A = [a1 z; z b1];
            B = [a2 z; z b2];
            C = [a3 z; z b3];
            A =kron(A , eye(N / 2));
            B =kron(B , eye(N / 2));
            C =kron(C , eye(N / 2));
        end

        function describe_three_spaces(A, B, C)
            % Compute principal angles between the subspaces
            fprintf('Ranks: [A]: %d, [B]: %d, [A]: %d\n', ...
                rank(A), rank(B), rank(C));
            fprintf('Cols: [A]: %d, [B]: %d, [A]: %d\n', ...
                size(A, 2), size(B, 2), size(C, 2));
            fprintf('Ranks: [A B]: %d, [B C]: %d, [A C]: %d, \n', ...
                rank([A B]), rank([B C]), rank([A C]));
            D = [A B C];
            fprintf('Rank [A B C]: %d\n', rank(D));
            fprintf('Angle between A and B: %.4f deg\n', spx.la.spaces.smallest_angle_deg(A, B));
            fprintf('Angle between B and C: %.4f deg\n', spx.la.spaces.smallest_angle_deg(B, C));
            fprintf('Angle between A and C: %.4f deg\n', spx.la.spaces.smallest_angle_deg(A, C));
            fprintf('Column wise norms: \n');
            fprintf(' %.2f', spx.norm.norms_l2_cw(A));
            fprintf('\n');
            fprintf(' %.2f', spx.norm.norms_l2_cw(B));
            fprintf('\n');
            fprintf(' %.2f', spx.norm.norms_l2_cw(C));
            fprintf('\n');
        end

        function [A, B, C] = abc_spaces_junk_1(N, theta)
            if ~mod(N, 2) == 0
                error('N must be divisible by 2');
            end
            d = N / 2;
            % First create three random orthonormal vectors
            X = orth(randn(N, 2));
            % Then tilt the second one w.r.t. first
            a1 = X(:, 1);
            a2 = X(:, 2);
            p = cos(theta);
            % first vector for second space
            b1 = sqrt(1 - p^2) * a2 + p * a1;
            X = [a1 b1];
            % Find the orthogonal complement of X
            [U S V] = svd(X);
            Y = U(:, 3:end);
            [~, n] = size(Y);
            % Distribute vectors from Y into A and B
            A = [a1 Y(:, 1:n/2)];
            B = [b1 Y(:, n/2 + 1:end)];

            % choose a vector a3 which is orthogonal to A and b1
            X = [A B(:, 1:d-1)];
            [U S V] = svd(X);
            a3 = U(:, size(X, 2) + 1);
            % first vector for third space
            c1_1 = p;
            c1_2 = p * (1 - p) / sqrt(1 - p^2);
            c1_3 = sqrt(1 - c1_1^2 - c1_2^2);
            c1 = c1_1 * a1 + c1_2 * a2 + c1_3 * a3;

            X = [A c1];
            % Find the orthogonal complement of X
            [U S V] = svd(X);
            Y = U(:, size(X, 2)+1:end);
            C = [c1 Y];
        end

        function result = have_same_column_spans(A, B)
            % Checks if the column spans of two matrices are same.
            r1 = rank(A);
            r2 = rank(B);
            if r1 ~= r2
                result = false;
                return;
            end
            r3 = rank([A B]);
            if r3 ~= r1
                result = false;
                return;
            end
            result = true;
        end

    function result =  bases(X, counts)
        % bases for individual subspaces
        K = length(counts);
        % bases cell array
        result = cell(1, K);
        [start_indices, end_indices] = spx.cluster.start_end_indices(counts);
        for k=1:K
            ss = start_indices(k);
            ee = end_indices(k);
            XX = X(:, ss:ee);
            basis = orth(XX);
            result{k} = basis;
        end
    end

    end

end


addpath(genpath('/dartfs-hpc/rc/home/m/f0042vm/software/fdaM'))

% create a basis set

dt = 0.0288;
order = 3;
l = 25;
degree = 8;

basis = create_bspline_basis([0,l/dt], degree+4, order);
bf = full(eval_basis((1:l/dt),basis));
bf = bf(:,3:end-2);

obf = spm_orth(bf); % orthogonalize bf

figure(1);
subplot(3,1,1);
cla
h1 = plot(bf,'r');
title('Spline Basis Set');
subplot(3,1,2);
h2 = plot(obf,'b');
title('SPM orthogonalized splines');

% compute inverse orthogonal transform

iO = (obf'*obf)\obf'*bf;
iO(iO < 0) = 0;

% generate a random walk;

rand_walk = sum(triu(repmat(randn(length(bf),1),1,length(bf))));

figure(1);
subplot(3,1,3);
cla
h1=plot(rand_walk,'bla');
hold on;

% fit both basis fnuctions to the random walk

B = (bf'*bf)\bf'*rand_walk';
orth_B = (obf'*obf)\obf'*rand_walk';

h2=plot(obf*orth_B,'*b');
h3=plot(bf*B,'r');
h4=plot(bf.*repmat(B',size(bf,1),1),'g')

legend([h1(1),h2(1),h3(1),h4(1)],'Random Walk','spm spline model','spline model','weighted splines','location','southeast');
title('Spline model can be obtained with either basis set');

% so now we have the following
% splineModel = bf*B
% splineModel = obf*orth_B
% obf*iO = bf
% so we can rearrange
% obf*iO*b = obf*orth_B
% iO*b = orth_B
% b = inv(iO)*orth_B

i0 = (bf'*obf)'\obf'*obf;
iO(iO<0) = 0;

sum(inv(iO)*orth_B)
sum(B)


function [ y, m, d, f ] = jed_to_ymdf_republican ( jed )

%*****************************************************************************80
%
%% JED_TO_YMDF_REPUBLICAN converts a JED to a Republican YMDF date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Richards,
%    Algorithm F,
%    Mapping Time, The Calendar and Its History,
%    Oxford, 1999, pages 324-325.
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, integer Y, M, D, real F,
%    the YMDF date.
%

%
%  Determine the computational date (Y'/M'/D').
%
  j = floor ( jed + 0.5 );
  f = ( jed + 0.5 ) - j;

  g =floor ( ( 4 * j + 578797 ) / 146097 );
  g = floor ( ( 3 * g ) / 4 ) - 51;
  j_prime = j + 111 + g;

  y_prime =     floor ( ( 4 * j_prime + 3 ) / 1461 );
  t_prime = floor ( mod ( 4 * j_prime + 3, 1461 ) / 4 );
  m_prime = floor ( t_prime / 30 );
  d_prime =   mod ( t_prime, 30 );
%
%  Convert the computational date to a calendar date.
%
  d = d_prime + 1;
  m = mod ( m_prime, 13 ) + 1;
  y = y_prime - 6504 + floor ( ( 13 - m ) / 13 );

  return
end


function J = computeCostMulti(X, y, theta)
% J = COMPUTECOSTMULTI(X, y, theta) computes the cost of using theta as the
% parameter for linear regression to fit the data points in X and y

m = length(y); % number of training examples

J = (1/(2*m)) * (X * theta - y)' * (X * theta - y); % Vectorized

end


function [mask] = polygon_filter(x, y, XI, YI, in_or_out)
    % POLYGON_FILTER used Analytic Geometry to select points inside or outside polygon
    %
    % [mask] = POLYGON_FILTER(x, y, XI, YI, in_or_out)
    %
    % input params:
    %    x, y : polygon vertices, with x(1)==x(end) and y(1)==y(end)
    %           x & y must be vectors of same size, and include
    %           more than 3 points (len(polyX) > 3)
    %
    %    XI, YI : x and y values for points to be tested
    %
    %    in_or_out : either 'inside' or 'outside'
    %               'inside' : returns a mask that is true for points inside polygon
    %               'outside': returns mask that is true for points outside polygon
    %
    %               default is 'inside'
    %
    %    I don't know about edge cases.
    %
    % see also inpolygon, inpoly

    assert(length(XI) == length(YI), 'test-points should have equal numbers of x and y' );
    assert(length(x) == length(y), 'number of polygon x should equal polygon y');
    assert(numel(x) > 3,'not enough points to be a polygon');

    m = length(x)-1;      %  number of coordinates of polygon
    l = zeros(size(XI));
    l2 = l;            %  Algorithm to select points inside a closed
    %  polygon based on Analytic Geometry    R.Z. 4/94
    for i = 1:m

        l= ((y(i)-YI < 0) & (y(i+1)-YI >= 0)) & ...
            (XI-x(i)-(YI-y(i))*(x(i+1)-x(i))/(y(i+1)-y(i)) < 0) | ...
            ((y(i)-YI >= 0) & (y(i+1)-YI < 0)) & ...
            (XI-x(i)-(YI-y(i))*(x(i+1)-x(i))/(y(i+1)-y(i)) < 0);

        if i ~= 1
            l2(l) = 1 - l2(l);
        else
            l2 = l;
        end         % if i

    end

    if ~exist('in_or_out','var')
        in_or_out = 'inside';
    end

    switch(in_or_out)
        case 'inside'
            mask = l2;
        case 'outside'
            mask = ~l2;
        otherwise
            error("unrecognized in_or_out option. either 'inside' or 'outside'");
    end
end


% IM = mkRamp(SIZE, DIRECTION, SLOPE, INTERCEPT, ORIGIN)
%
% Compute a matrix of dimension SIZE (a [Y X] 2-vector, or a scalar)
% containing samples of a ramp function, with given gradient DIRECTION
% (radians, CW from X-axis, default = 0), SLOPE (per pixel, default =
% 1), and a value of INTERCEPT (default = 0) at the ORIGIN (default =
% (size+1)/2, [1 1] = upper left).  All but the first argument are
% optional.

% Eero Simoncelli, 6/96. 2/97: adjusted coordinate system.

function [res] = mkRamp(sz, dir, slope, intercept, origin)

sz = sz(:);
if (size(sz,1) == 1)
  sz = [sz,sz];
end

% -----------------------------------------------------------------
% OPTIONAL args:

if (exist('dir') ~= 1)
  dir = 0;
end

if (exist('slope') ~= 1)
  slope = 1;
end

if (exist('intercept') ~= 1)
  intercept = 0;
end

if (exist('origin') ~= 1)
  origin = (sz+1)/2;
end

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

xinc = slope*cos(dir);
yinc = slope*sin(dir);

[xramp,yramp] = meshgrid( xinc*([1:sz(2)]-origin(2)), ...
    yinc*([1:sz(1)]-origin(1)) );

res = intercept + xramp + yramp;


function result = gaussint(P,a,b,ngp)
% Integration using Gauss Quadratures
% by Manuel Diaz 2013.03.20

% compute gauss locations and weights
[w,psi] = gauss1d(ngp);

% compute the change the integration range to -1 to 1
x = (b+a)/2 + (b-a)/2*psi;

% perform quadrature
result  = (b-a)/2*sum(w.*P(x));


function [orientim, G_xx, G_yy, G_xy, cos_2_theta, sin_2_theta, denom] = orient(or_im, g_sigma, b_sigma, o_smooth)

    % Calculate image gradients.
    hsize = fix(6*g_sigma);
    if ~mod(hsize,2); hsize = hsize+1; end
    f = fspecial('gaussian', hsize, g_sigma);
    [f_x,f_y] = gradient(f);

    G_x = filter2(f_x, or_im);
    G_y = filter2(f_y, or_im);

    G_xx = G_x.^2;
    G_xy = G_x.*G_y;
    G_yy = G_y.^2;

    % to smooth the covariance data

    hsize = fix(6*b_sigma);
    if ~mod(hsize,2); hsize = hsize+1; end
    f = fspecial('gaussian', hsize, b_sigma);

    G_xx = filter2(f, G_xx);
    G_xy = 2*filter2(f, G_xy);
    G_yy = filter2(f, G_yy);

    denom = sqrt(G_xy.^2 + (G_xx - G_yy).^2) + eps;
    sin_2_theta = G_xy./denom;            % Sin of angle
    cos_2_theta = (G_xx-G_yy)./denom;     % Cos of angle

    %Smooth
        hsize = fix(6*o_smooth);
        if ~mod(hsize,2); hsize = hsize+1; end
        f = fspecial('gaussian', hsize, o_smooth);
        cos_2_theta = filter2(f, cos_2_theta);
        sin_2_theta = filter2(f, sin_2_theta);

    a = pi/2;
    orientim = a + atan2(sin_2_theta,cos_2_theta)/2;


rng default;
% Signal space
N = 256;
% Number of measurements
M = 64;
% Sparsity level
K = 10;
% Construct the signal generator.
gen  = spx.data.synthetic.SparseSignalGenerator(N, K);
% Generate bi-uniform signals
x = gen.biUniform(1, 2);
% Sensing matrix
Phi = spx.dict.simple.gaussian_dict(M, N);
% Measurement vectors
y = Phi.apply(x);
% OMP MMV solver instance
result = spx.pursuit.single.omp_chol(double(Phi), y, K, 1e-6);
% Solution vector
z = result.z;

stats = spx.commons.sparse.recovery_performance(Phi, K, y, x, z);
spx.commons.sparse.print_recovery_performance(stats);

mf = spx.graphics.Figures();
mf.new_figure('OMP solution');
subplot(411);
stem(x, '.');
title('Sparse vector');
subplot(412);
stem(z, '.');
title('Recovered sparse vector');
subplot(413);
stem(abs(x - z), '.');
title('Recovery error');
subplot(414);
stem(y, '.');
title('Measurement vector');


function [C,R] = incircle(x,y)
% incircle: compute the maximal in-circle of the polygonal convex hull of a set of points in the plane
%
% [C,R] = incircle(x,y)
%    Called with a pair of vectors of the same length,
%    incircle computes the convex hull in 2-dimensions,
%    then finds the maximal radius in-circle that lies
%    entirely within the polygon of the convex hull.
%
% [C,R] = incircle(xy)
%    Called with a single nx2 array, incircle treats
%    this as a list of points in 2 dimensions. Each row
%    of xy is treated as a single point. The convex hull
%    is computed and the maximal in-circle then computed
%    for the convex hull.
%
% [C,R] = incircle(xy,edges)
%    Called with two arguments, the first of which is an
%    nx2 array of data points, and the second a list of
%    edges of the convex hull as would be generated by
%    convhull (or convhulln), the maximal in-circle is
%    generated for the hull as provided. No test is made
%    to assure the hull is truly convex.
%
% All input forms return a row vector of length 2 (C)
% which defines the center of the in-circle, and the
% radius (R) of the in-circle.
%
% Example:
%
% [C,R] = incircle(rand(1000,1),rand(1000,1))
%
% C =
%      0.50191      0.49999
%
% R =
%      0.49788
%
% Example:
%
% x = randn(100,1) + 1;
% y = randn(100,1) - 2.5;
% H = convhull(x,y);
% [C,R] = incircle([x,y],H)
%
% C =
%      1.0212      -2.3458
%
% R =
%      2.1329
%
% t = linspace(0,2*pi,200);
% xc = R*cos(t) + C(1);
% yc = R*sin(t) + C(2);
% plot(x(H),y(H),'-r',x,y,'ko',xc,yc,'-b')
% axis equal
% xlabel X
% ylabel Y
% title 'Convex hull, with polygon in-circle'
% grid on
%
%
% See also: minboundcicle, convhull
%
% Author: John D'Errico
% e-mail: woodchips@rochester.rr.com
% Release: 1.0
% Release date: 6/14/09

if (nargin < 1) || (nargin > 2)
  error('INCIRCLE:improperarguments', ...
    'incircle requires exactly 1 or 2 arguments')
elseif (nargin == 2) && isvector(x) && isvector(y) && (numel(x) == numel(y))
  % a pair of vectors
  xy = [x(:),y(:)];
  % compute the hull. I prefer convhulln.
  edges = convhulln(xy);
elseif (nargin == 1) && (size(x,2) == 2)
  % a single list of points as rows of x
  xy = x;
  edges = convhulln(xy);
elseif (nargin == 2) && (size(x,2) == 2) && (size(y,2) == 2)
  % y must be a list of edges from convhulln
  xy = x;
  edges = y;
elseif (nargin == 2) && (size(x,2) == 2) && isvector(y) && (y(1) == y(end))
  % y must be a list of edges from convhull
  xy = x;
  I = y(:);
  % in case the first point was not wrapped in the polygon
  if I(1) ~= I(end)
    I = [I;I(1)];
  end
  edges = [I(1:(end-1)),I(2:end)];
else
  % none of the forms I allow seem to fit.
  % give up and throw an error.
  error('INCIRCLE:invaliddata', ...
    'x and y do not seem to fit into any of the allowed forms for incircle input')
end
ne = size(edges,1);

% the end points of each edge are...
A = xy(edges(:,1),:);
B = xy(edges(:,2),:);

% the normal vector to each edge
N = (B - A)*[0 1;-1 0];

% normalize to unit length
L = sqrt(sum(N.^2,2));
N = N./[L,L];

% a central point inside the hull itself
C0 = mean(A,1);

% ensure the normals point inwards. While
% I can use the signed area for a hull as
% generated by convhull (suggestion by Bruno)
% this test is also efficient, and it deals
% with the case of a hull provided from some
% unknown and less trusted source.
k = sum(N.*bsxfun(@minus,C0,A),2) < 0;
N(k,:) = -N(k,:);

% formulate the linear programming problem.
% given a point C inside the hull, the distance
% from C to the edge that contains A(i,:) is
% given by (dot(N(i,:),C - A(i,:))). If this
% number is negative for any edge of the hull,
% then C is outside of the hull.
%
% Now think of it as a set of slack variables,
% one for each edge of the hull. Given the
% unknown point C that defines the center of
% the in-circle,
%
%  dot(N(i,:),C-A(i,:)) - S(i) == 0
%
% Thus the vector S is of length ne, where ne is
% the number of edges in the convex hull. Every
% element of S must be positive.
%
% Create one more slack variable, a scalar R.
% R is the minimum value that S attains for a
% given point C.
%
%   R >= 0
%   S(i) >= R
%
% The objective for our linear programming problem
% is simple. It is just -R. When we find the
% solution to the LP problem that satisfies the
% equality constraints above between C and S, the
% bound constraint on T, and the inequality
% constraints between S and R, the solution yields
% the maximal radius in-circle that fits inside
% the convex hull polygon.
%
% The unknowns for the LP are a list of ne+3
% variables. The first two variables represent
% the center coordinates of the circle. X(3) = R
% is the circle radius. The remainder of the
% variables are the slack variabls S(i).

% equality constraints defined by the dot products
% with the normal vectors.
Aeq = [N,zeros(ne,1),-eye(ne)];
beq = sum(N.*A,2);

% lower bounds only for the slack variables
LB = [-inf; -inf; 0; zeros(ne,1)];
% there are no upper bounds
UB = [];

% inequalities defined by the slack variable
% constraints
A = [zeros(ne,2),ones(ne,1),-eye(ne)];
b = zeros(ne,1);

% the objective is just -R
f = zeros(ne+3,1);
f(3) = -1;

% just turn off the output message
options = optimset('linprog');
options.Display = 'off';

% linprog does all of the hard work.
result = linprog(f,A,b,Aeq,beq,LB,UB,[],options);

% unpack the circle parameters
C = result(1:2)';
R = result(3);


function bitPos=findPosOfMin1Bit(n)
%%FINDPOSOFMIN1BIT Given n, which is of an integer data type, determine the
%           position of the least significant bit that is a 1.
%
%INPUTS: n An integer or a matrix of integers. These must be an integer
%          data type (i.e. not a double).
%
%OUTPUTS: bitPos The position of the first 1 in the binary representation
%                of each of the integers in n. Counting starts at 1. A
%                value of 0 means that there is no 1 in the binary
%                representation.
%
%The algorithm just keeps shifting the number (dividing by 2) until it
%the first digit is no longer 0, counting the number of shifts needed.
%
%EXAMPLE:
% n=findPosOfMin1Bit(int32([0,4,1213,2^23]))
%
%The function returns n=[0, 3, 1, 24]. Binary representations of
%the numbers (the least significant bit is to the left) are
%0    0
%4    001
%1213 10111101001
%2^23 000000000000000000000001
%
%January 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(isfloat(n)||~isreal(n))
    error('The values must be real and be an integer data type.')
end

if(ischar(n))
    n=uint8(n);
end

bitPos=ones(size(n));
numEls=numel(n);

for curEl=1:numEls
    if(n(curEl)~=0)
        while(bitand(n(curEl),1)==0)
            bitPos(curEl)=bitPos(curEl)+1;
            n(curEl)=bitshift(n(curEl),-1);
        end
    else
        bitPos(curEl)=0;
    end
end
end

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


function x_num = box_behnken_size ( dim_num )

%*****************************************************************************80
%
%% BOX_BEHNKEN_SIZE returns the size of a Box-Behnken design.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    George Box, Donald Behnken,
%    Some new three level designs for the study of quantitative variables,
%    Technometrics,
%    Volume 2, pages 455-475, 1960.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Output, integer X_NUM, the number of elements of the design.
%    X_NUM will be equal to DIM_NUM * 2**(DIM_NUM-1) + 1.
%
  if ( 1 <= dim_num )
    x_num = 1 + dim_num * 2^( dim_num - 1 );
  else
    x_num = -1;
  end

  return
end


function [ xp ] = DoAction( force, x )
%MountainCarDoAction: executes the action (a) into the mountain car
%environment
% a: is the force to be applied to the car
% x: is the vector containning the position and speed of the car
% xp: is the vector containing the new position and velocity of the car

position = x(1);
speed    = x(2);

% bounds for position
bpleft=-1.5;
bpright=0.5;

% bounds for speed
bsleft=-0.07;
bsright=0.07;

speedt1= speed + (0.001*force) + (-0.0025 * cos( 3.0*position) );
%speedt1= speedt1 * 0.999; % thermodynamic law, for a more real system with friction.

if(speedt1<bsleft)
    speedt1=bsleft;
end
if(speedt1>bsright)
    speedt1=bsright;
end

post1 = position + speedt1;

if(post1<=bpleft)
    post1=bpleft;
    speedt1=0.0;
end

if(post1>=bpright)
    post1=bpright;
    speedt1=0.0;
end
xp=[];
xp(1) = post1;
xp(2) = speedt1;


function fx = ln_cordic ( x, n )

%*****************************************************************************80
%
%% LN_CORDIC evaluates the natural logarithm function using the CORDIC method.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Frederick Ruckdeschel,
%    BASIC Scientific Subroutines,
%    Volume II,
%    McGraw-Hill, 1980,
%    ISBN: 0-07-054202-3,
%    LC: QA76.95.R82.
%
%  Parameters:
%
%    Input, real X, the argument.
%
%    Input, integer N, the number of steps to take.
%
%    Output, real FX, the logarithm of X.
%
%  Local Parameters:
%
%    Local, real A(1:25) = exp ( (1/2)^(1:25) );
%
  a_length = 25;

  a = [ ...
    1.648721270700128, ...
    1.284025416687742, ...
    1.133148453066826, ...
    1.064494458917859, ...
    1.031743407499103, ...
    1.015747708586686, ...
    1.007843097206488, ...
    1.003913889338348, ...
    1.001955033591003, ...
    1.000977039492417, ...
    1.000488400478694, ...
    1.000244170429748, ...
    1.000122077763384, ...
    1.000061037018933, ...
    1.000030518043791, ...
    1.0000152589054785, ...
    1.0000076294236351, ...
    1.0000038147045416, ...
    1.0000019073504518, ...
    1.0000009536747712, ...
    1.0000004768372719, ...
    1.0000002384186075, ...
    1.0000001192092967, ...
    1.0000000596046466, ...
    1.0000000298023228 ];
  e = 2.718281828459045;

  if ( x <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LN_CORDIC - Fatal error!\n' );
    fprintf ( 1, '  Input argument X <= 0.0\n' );
    error ( 'LN_CORDIC - Fatal error!' );
  end

  k = 0;

  while ( e <= x )
    k = k + 1;
    x = x / e;
  end

  while ( x < 1.0 )
    k = k - 1;
    x = x * e;
  end
%
%  Determine the weights.
%
  for i = 1 : n

    w(i) = 0.0;

    if ( i <= a_length )
      ai = a(i);
    else
      ai = 1.0 + ( ai - 1.0 ) / 2.0;
    end

    if ( ai < x )
      w(i) = 1.0;
      x = x / ai;
    end

  end

  x = x - 1.0;
  x = x ...
    * ( 1.0 - ( x / 2.0 ) ...
    * ( 1.0 + ( x / 3.0 ) ...
    * ( 1.0 -   x / 4.0 )));
%
%  Assemble.
%
  poweroftwo = 0.5;
  for i = 1 : n
    x = x + w(i) * poweroftwo;
    poweroftwo = poweroftwo / 2.0;
  end

  fx = k + x;

  return
end


function f = p02_f ( m, n, x )

%*****************************************************************************80
%
%% P02_F evaluates the objective function for problem 02.
%
%  Discussion:
%
%    This function is also known as the weighted sphere model.
%
%    The function is continuous, convex, and unimodal.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Marcin Molga, Czeslaw Smutnicki,
%    Test functions for optimization needs.
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of arguments.
%
%    Input, real X(M,N), the arguments.
%
%    Output, real F(N), the function evaluated at the arguments.
%
  f = zeros ( n, 1 );

  y = r8vec_indicator ( m );

  for j = 1 : n
    f(j) = sum ( y(1:m) .* x(1:m,j).^2 );
  end

  return
end


function [ a, more ] = tree_rb_lex_next ( n, a, more )

%*****************************************************************************80
%
%% TREE_RB_LEX_NEXT generates rooted binary trees in lexicographic order.
%
%  Discussion:
%
%    The information definining the tree of N nodes is stored in a vector
%    of 0's and 1's, in preorder traversal form.  Essentially, the
%    shape of the tree is traced out with a pencil that starts at the root,
%    and stops at the very last null leaf.  The first time that a (non-null)
%    node is encountered, a 1 is added to the vector, and the left
%    descendant of the node is visited next.  When the path returns from
%    the first descendant, the second descendant is visited.  When then path
%    returns again, the path passes back up from the node to its parent.
%    A null leaf is encountered only once, and causes a zero to be added to
%    the vector, and the path goes back up to the parent node.
%
%    The lexicographic order is used to order the vectors of 1's and 0's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 June 2013
%
%  Reference:
%
%    Frank Ruskey,
%    Combinatorial Generation,
%    To appear.
%
%  Parameters:
%
%    Input, integer N, the number of nodes in the rooted binary
%    tree.  N should be odd.
%
%    Input/output, integer A(N), the preorder traversal form for
%    the previous/next rooted binary tree.
%
%    Output, logical MORE, is TRUE if the next rooted binary tree was
%    returned on this call, or FALSE if there are no more rooted binary
%    trees, and the output of the previous call was the last one.
%
  if ( ~ more )
    a(1:2:n-2) = 1;
    a(2:2:n-1) = 0;
    a(n) = 0;
    more = 1;
    return
  end
%
%  Find the last 1 in A.
%
  k = n;
  while ( a(k) == 0 )
    k = k - 1;
  end
  q = n - k - 1;
%
%  Find the last 0 preceding the last 1 in A.
%  If there is none, then we are done, because 11...1100..00
%  is the final element.
%
  while ( 1 )

    if ( k == 1 )
      more = 0;
      return
    end

    if ( a(k) == 0 )
      break
    end

    k = k - 1;

  end

  p = n - k - q - 1;
  a(k) = 1;
  a(k+1:n-2*p+1) = 0;
  a(n-2*p+2:2:n-2) = 1;
  a(n-2*p+3:2:n-1) = 0;
  a(n) = 0;

  return
end


%DECOMPOSEESSENTIALMAT  Decompose an essential matrix to possible rotations and translation
%
%     S = cv.decomposeEssentialMat(E)
%
% ## Input
% * __E__ The input essential matrix, 3x3.
%
% ## Output
% * __S__ Decomposed `E`. A scalar struct with the following fields:
%   * __R1__ One possible rotation matrix, 3x3.
%   * __R2__ Another possible rotation matrix, 3x3.
%   * __t__ One possible translation, 3x1.
%
% This function decompose an essential matrix `E` using SVD decomposition
% [HartleyZ00]. Generally 4 possible poses exists for a given `E`. They are
% `[R1,t]`, `[R1,-t]`, `[R2,t]`, `[R2,-t]`. By decomposing `E`, you can only
% get the direction of the translation, so the function returns unit `t`.
%
% ## References
% [HartleyZ00]:
% > Richard Hartley and Andrew Zisserman. "Multiple view geometry in computer
% > vision". Cambridge university press, 2003.
%
% See also: cv.findEssentialMat, cv.SVD
%


% test for low rank approximation of an image

name = 'lena';
n = 128;
M = load_image(name);
M = crop(M,n);

[U,S,V] = svd(M);

%% display reconstruction
m_list = [5 10 50 100];
for i = 1:length(m_list)
    m = m_list(i);
    s = diag(S);
    s(m+1:end) = 0;
    M1 = U*diag(s)*V';
    subplot(2,2,i);
    imagesc(M1); axis image; axis off;
    title([num2str(m) ' eigv']);
end
colormap gray(256);

return;

% test for pseudo inverse
n = 300; m = 4*n;
D = rand(n,m);
tic;
B = D' * (D*D')^(-1);
t = toc;
tic;
B1 = pinv(D);
t1 = toc;
e = norm(B-B1, 'fro')/norm(B, 'fro');
disp(['speed-up=' num2str((t1-t)/t*100) '%, err=' num2str(e*100)]);


function [U_exact] = exact_translating_sphere(sphere_translational_velocity,sphere_radius,mesh_eval)
%+========================================================================+
%|                                                                        |
%|           This function uses the GYPSILAB toolbox for Matlab           |
%|                                                                        |
%| COPYRIGHT :                                                            |
%| PROPERTY  :                                                            |
%| LICENCE   :                                                            |
%| CONTACT   :                                                            |
%| WEBSITE   : www.cmap.polytechnique.fr/~aussal/gypsilab                 |
%|                                                                        |
%| Please acknowledge the gypsilab toolbox in programs or publications in |
%| which you use it.                                                      |
%|________________________________________________________________________|
%|   '&`   |                                                              |
%|    #    |   FILE       : exact_translating_sphere.m                    |
%|    #    |   VERSION    : 0.10                                          |
%|   _#_   |   AUTHOR(S)  : Luca Berti                                    |
%|  ( # )  |   CREATION   : 25.12.2018                                    |
%|  / 0 \  |   LAST MODIF :                                               |
%| ( === ) |   SYNOPSIS   :                                               |
%|  `---'  |                                                              |
%+========================================================================+
% COMPUTE THE EXACT VELOCITY FIELD DETERMINED BY A TRANSLATING SPHERE IN
% AN INFINITE FLUID ALONG THE Z AXIS
% Reference: Happel-Brenner, "Low Reynolds number hydrodynamics"
% (pag. 119 and formulas 4-17.17 and 4-17.18) transformed into Cartesian
% coordinates (p.507 A-15.29 for the transformation)

% Input -> mesh_eval: mesh containing the evaluation points for the exact
%                     solution
%          sphere_translational_velocity -> translational velocity of the
%                                           vertically moving sphere
%                                           [0,0,W]
% Output -> U_exact:  3xN_eval vector containing the values of the exact
%                     solution at the evaluation point, expressed IN CARTESIAN
%                     COORDINATES

W = sphere_translational_velocity(3);
% Exact solutions taken from the reference - SPHERICAL COORDINATES
u_r = @(x,y,z) -W.*cos(acos(z./sqrt(x.^2+y.^2+z.^2))).*(sphere_radius^3./(2*sqrt(x.^2+y.^2+z.^2).^3) -3*sphere_radius./(2*sqrt(x.^2+y.^2+z.^2)));
u_theta = @(x,y,z) -W.*sin(acos(z./sqrt(x.^2+y.^2+z.^2))).*(sphere_radius^3./(4*sqrt(x.^2+y.^2+z.^2).^3)+3*sphere_radius./(4*sqrt(x.^2+y.^2+z.^2)));
u_phi =@(x,y,z) 0;

X = mesh_eval.vtx;
N_eval = size(X,1);

% Evaluation vector - SPHERICAL COORDINATES
U_exact = zeros(N_eval*3,1);
U_exact(1:N_eval,1) = feval(u_r,X(:,1),X(:,2),X(:,3));
U_exact(N_eval+1:2*N_eval,1) = feval(u_theta,X(:,1),X(:,2),X(:,3));
U_exact(2*N_eval+1:end,1) = feval(u_phi,X(:,1),X(:,2),X(:,3));

% Expression of the evaluation points in spherical coordinates, to extract
% (r,theta,phi) needed to transform the exact velocities from spherical to
% Cartesian coordinates
Y = X;
[X(:,3),X(:,2),X(:,1)] = cart2sph(Y(:,1),Y(:,2),Y(:,3));
% Latitude is needed instead of colatitude (as computed by Matlab)
X(:,2) = pi/2-X(:,2);

temporary = zeros(N_eval*3,1);
% Transformation of the exact velocity vector field from spherical to
% Cartesian coordinates - CARTESIAN COORDINATES
temporary(1:N_eval,1) = U_exact(1:N_eval,1).*sin(X(:,2)).*cos(X(:,3)) + ...
                          U_exact(N_eval+1:N_eval*2,1).*cos(X(:,2)).*cos(X(:,3))- ...
                          U_exact(1+2*N_eval:end,1).*sin(X(:,3));

temporary(1+N_eval:2*N_eval,1) = U_exact(1:N_eval,1).*sin(X(:,2)).*sin(X(:,3)) + ...
                          U_exact(N_eval+1:N_eval*2,1).*cos(X(:,2)).*sin(X(:,3)) + ...
                          U_exact(1+2*N_eval:end,1).*cos(X(:,3));

temporary(1+2*N_eval:end,1) = U_exact(1:N_eval,1).*cos(X(:,2)) - ...
                          U_exact(N_eval+1:N_eval*2,1).*sin(X(:,2));
U_exact = temporary;

end


function X_zero=assignPerimeterPositions(radius,mesh);
% Define a set of perimeter points on the circle.
%
%   X_zero=assignPerimeterPositions(perimeterDists,mesh);
%
% orderMeshPerimeterPointsAll is the routine that gets the perimeter points
% into the proper order for the mapping here.   The mapping here simply
% puts these points on a circle.  In principle, we could put the points at
% these angles but adjust for distance.  In that case, however, we might
% not have a convex set.  So, we use a circle.
%
% The most anterior point in the sub mesh should map to the top of the
% circle. The most posterior point should be on the left or right.
%
% Stanford.

numPerimPoints=length(mesh.orderedUniquePerimeterPoints);

% Find the maximum y value in the perimeter
[maxHeight,maxHIndex]=max(mesh.uniqueVertices(mesh.orderedUniquePerimeterPoints,2));

angles=linspace(0,2*pi,numPerimPoints)';
angles=shift(angles(:),[-maxHIndex,0]);

X_zero=zeros(numPerimPoints,2);

% Perimeter must be convex for Tutte's algorithm  to work properly -
X_zero(:,1)=radius.*cos(angles);
X_zero(:,2)=radius.*sin(angles);

return;


function sF = calcDensity(v,varargin)
% calculate a density function out of (weighted) unit vectors
%
% Syntax
%
%   sF = calcDensity(v)
%   sF = calcDensity(v,'weights',w)
%   sF = calcDensity(v,'halfwidth',delta)
%   sF = calcDensity(v,'kernel',psi)
%    f = calcDensity(v,S2G)
%
% Input
%  v   - sampling points for density estimation @vector3d
%  S2G - @vector3d
%  w   - weights, default is all one
%  delta - halfwidth of the kernel, default is 10 degree
%  psi - @S2Kernel function, default is S2 de la Vallee Poussin
%
% Output
%  sF  - @S2Fun
%   f  - function values
%
% Options
%  halfwidth - halfwidth of a kernel
%  kernel    - specify a S2Kernel
%  weights   - vector of weights, with same length as v
%

% determine kernel function
hw = get_option(varargin,'halfwidth',10*degree);
psi = get_option(varargin,'kernel',S2DeLaValleePoussinKernel('halfwidth',hw));

% ignore nans
v = subSet(v,~isnan(v));

sF = 4*pi * S2FunHarmonic.quadrature(v,ones(size(v)),varargin{:});

% normalize
if ~check_option(varargin,'noNormalization')
  sF = sqrt(4*pi) * sF ./ sF.fhat(1);
end

% convolute with kernel function
sF = conv(sF,psi);

% if required compute function values
if nargin > 1 && isa(varargin{1},'vector3d')
  sF = sF.eval(varargin{1});
end

end


function value = p18_f ( dim_num, point_num, x )

%*****************************************************************************80
%
%% P18_F evaluates the integrand for problem 18.
%
%  Discussion:
%
%    This is the characteristic function of the interior of the
%    N sphere of radius R and center Z, to be integrated within the
%    unit hypercube [0,1]^N.  If the user picks a combination of R
%    and Z that causes the volume of the sphere to lie at least
%    partially outside the unit hypercube, the formula for the
%    exact integral will no longer be correct.
%
%  Dimension:
%
%    DIM_NUM is arbitrary.
%
%  Region:
%
%    0 <= X(1:DIM_NUM) <= 1
%
%  Integral Parameters:
%
%    R defaults to 0.50.
%    You can change R by calling P18_R8.
%
%    Z(1:DIM_NUM) defaults to (0.5,0.5,...0.5).
%    You can change Z by calling P18_R8VEC.
%
%  Integrand:
%
%    f(x) = 1 if X(1:DIM_NUM) is less than R from Z(1:DIM_NUM),
%           0 otherwise.
%
%  Exact Integral:
%
%    The volume of the DIM_NUM sphere of radius R.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the argument.
%
%    Input, integer POINT_NUM, the number of points.
%
%    Input, real X(DIM_NUM,POINT_NUM), the evaluation points.
%
%    Output, real VALUE(POINT_NUM), the integrand values.
%
  z = [];
  z = p18_r8vec ( 'G', 'Z', dim_num, z );

  r = 0.0;
  r = p18_r8 ( 'G', 'R', r );

  value(1:point_num) = 0.0;

  for point = 1 : point_num

    d = sqrt ( sum ( ( x(1:dim_num,point) - z(1:dim_num)' ).^2 ) );

    if ( d <= r )
      value(point) = 1.0;
    else
      value(point) = 0.0;
    end

  end

  p18_i4 ( 'I', '#', point_num );

  return
end


function itree = pruefer_to_tree_2 ( nnode, iarray )

%*****************************************************************************80
%
%% PRUEFER_TO_TREE_2 produces the edge list of a tree from its Pruefer code.
%
%  Discussion:
%
%    One can thus exhibit all trees on N nodes, produce
%    one at random, find the M-th one on the list, etc, by
%    manipulating the Pruefer codes.
%
%    For every labeled tree on N nodes, there is a unique N-2 tuple
%    of integers A1 through AN-2, with each A between 1 and N.  There
%    are N^(N-2) such sequences, and each one is associated with exactly
%    one tree.
%
%    This routine apparently assumes that the Pruefer code is
%    generated by taking the LOWEST labeled terminal node each time.
%    This is not consistent with PRUEFER_TO_TREE and TREE_TO_PRUEFER.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 June 2013
%
%  Author:
%
%    Original FORTRAN77 version by Albert Nijenhuis, Herbert Wilf.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Albert Nijenhuis. Herbert Wilf,
%    Combinatorial Algorithms,
%    Academic Press, 1978, second edition,
%    ISBN 0-12-519260-6.
%
%  Parameters:
%
%    Input, integer NNODE, number of nodes in desired tree.
%
%    Input, integer IARRAY(NNODE).  IARRAY(I), I = 1, NNODE-2
%    is the Pruefer code for the tree.
%
%    Output, integer ITREE(NNODE); the I-th edge of the tree
%    joins nodes I and ITREE(I).
%
  itree(1:nnode) = 0;

  for i = nnode-2 : -1 : 1

    l = iarray(i);

    if ( itree(l) == 0 )
      iarray(i) = - l;
      itree(l) = - 1;
    end

  end

  iarray(nnode-1) = nnode;
%
%  Find next index K so that ITREE(K) is 0.
%
  k = 1;
  j = 0;

  while ( itree(k) ~= 0 )
    k = k + 1;
  end

  kp = k;

  while ( 1 )

    j = j + 1;
    ir = abs ( iarray(j) );
    itree(kp) = ir;

    if ( j == nnode - 1 )
      break
    end

    if ( 0 < iarray(j) )
      while ( itree(k) ~= 0 )
        k = k + 1;
      end
      kp = k;
      continue
    end

    if ( k < ir )
      itree(ir) = 0;
      while ( itree(k) ~= 0 )
        k = k + 1;
      end
      kp = k;
      continue
    end

    kp = ir;

  end
%
%  Restore the signs of IARRAY.
%
  iarray(1:nnode-2) = abs ( iarray(1:nnode-2) );

  return
end


function [lmval,indd]=lmax(xx,filt)
%LMAX 	[lmval, indd]=lmax(xx,filt). Find local maxima in vector XX,where
%	LMVAL is the output vector with maxima values, INDD  is the
%	corresponding indexes, FILT is the number of passes of the small
%	running average filter in order to get rid of small peaks.  Default
%	value FILT =0 (no filtering). FILT in the range from 1 to 3 is
%	usially sufficient to remove most of a small peaks
%	For example:
%	xx=0:0.01:35; y=sin(xx) + cos(xx ./3);
%	plot(xx,y); grid; hold on;
%	[b,a]=lmax(y,2)
%	 plot(xx(a),y(a),'r+')
%	see also LMIN, MAX, MIN

%**************************************************|
% 	Serge Koptenko, Guigne International Ltd., |
%	phone (709)895-3819, fax (709)895-3822     |
%--------------06/03/97----------------------------|

x=xx;
len_x = length(x);
	fltr=[1 1 1]/3;
  if nargin <2, filt=0;
	else
x1=x(1); x2=x(len_x);
	for jj=1:filt,
	c=conv(fltr,x);
	x=c(2:len_x+1);
	x(1)=x1;
        x(len_x)=x2;
	end
  end
lmval=[]; indd=[];
i=2;		% start at second data point in time series
    while i < len_x-1,
	if x(i) > x(i-1)
	   if x(i) > x(i+1)	% definite max
lmval =[lmval x(i)];
indd = [ indd i];
	   elseif x(i)==x(i+1)&x(i)==x(i+2)	% 'long' flat spot
%lmval =[lmval x(i)];  	%1   comment these two lines for strict case
%indd = [ indd i];	%2 when only  definite max included
i = i + 2;  		% skip 2 points
	   elseif x(i)==x(i+1)	% 'short' flat spot
%lmval =[lmval x(i)];	%1   comment these two lines for strict case
%indd = [ indd i];	%2 when only  definite max included
i = i + 1;		% skip one point
	   end
	end
	i = i + 1;
    end
if filt>0 & ~isempty(indd),
	if (indd(1)<= 3)|(indd(length(indd))+2>length(xx)),
	   rng=1;	%check if index too close to the edge
	else rng=2;
	end
	  for ii=1:length(indd), 	% Find the real maximum value
	    [val(ii) iind(ii)] = max(xx(indd(ii) -rng:indd(ii) +rng));
	    iind(ii)=indd(ii) + iind(ii)  -rng-1;
	  end
  indd=iind; lmval=val;
else
end


function idx = findClosestCentroids(X, centroids)
%FINDCLOSESTCENTROIDS computes the centroid memberships for every example
%   idx = FINDCLOSESTCENTROIDS (X, centroids) returns the closest centroids
%   in idx for a dataset X where each row is a single example. idx = m x 1
%   vector of centroid assignments (i.e. each entry in range [1..K])
%

% Set K
K = size(centroids, 1);

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

% ====================== YOUR CODE HERE ======================
% Instructions: Go over every example, find its closest centroid, and store
%               the index inside idx at the appropriate location.
%               Concretely, idx(i) should contain the index of the centroid
%               closest to example i. Hence, it should be a value in the
%               range 1..K
%
% Note: You can use a for-loop over the examples to compute this.
%
for i = 1:size(X,1)
	min = Inf;
	for j = 1:K
		diff = sum((X(i,:) - centroids(j,:)).^2);
		if min > diff
			min = diff;
			idx(i) = j;
		end
	end
end

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

end


function [upsilonaa, upsilonap] = lfmaaComputeUpsilonMatrix(gamma, sigma2, t1, t2, mode)

% LFMAACOMPUTEUPSILONMATRIX Upsilon matrix acce. accel. with t1, t2 limits
% FORMAT
% DESC computes a portion of the LFM kernel.
% ARG gamma : Gamma value for system.
% ARG sigma2 : length scale of latent process.
% ARG t1 : first time input (number of time points x 1).
% ARG t2 : second time input (number of time points x 1).
% ARG mode : operation mode, according to the derivative (mode 0,
% derivative wrt t1, mode 1 derivative wrt t2)
% RETURN upsilon : result of this subcomponent of the kernel for the given values.
%
% COPYRIGHT : Mauricio Alvarez, 2010

% KERN

sigma = sqrt(sigma2);
gridt1 = repmat(t1, 1, length(t2));
gridt2 = repmat(t2', length(t1), 1);
timeGrid = gridt1 - gridt2;

if mode==0
    if nargout > 1
        upsilonap = lfmapComputeUpsilonMatrix(gamma, sigma2, t1, t2,1);
        upsilonaa = gamma^2*upsilonap + (2/(sqrt(pi)*sigma))*exp(-(timeGrid.^2)./sigma2).* ...
            ((gamma + 2*timeGrid/sigma2).*(2/sigma2 - (2*timeGrid/sigma2).^2) + 8*timeGrid/sigma^4);
    else
        upsilonaa = gamma^2*lfmapComputeUpsilonMatrix(gamma, sigma2, t1, t2,1) ...
            + (2/(sqrt(pi)*sigma))*exp(-(timeGrid.^2)./sigma2).* ...
            ((gamma + 2*timeGrid/sigma2).*(2/sigma2 - (2*timeGrid/sigma2).^2) + 8*timeGrid/sigma^4);
    end
else
    if nargout > 1
        upsilonap = lfmapComputeUpsilonMatrix(gamma, sigma2, t1, t2, 0);
        upsilonaa = gamma^2*upsilonap + (2/(sqrt(pi)*sigma))*exp(-(timeGrid.^2)./sigma2).* ...
            ((gamma + 2*timeGrid/sigma2).*(2/sigma2 - (2*timeGrid/sigma2).^2) + 8*timeGrid/sigma^4) ...
            + (2*gamma^2/(sqrt(pi)*sigma))*exp(-gamma*t1)*((gamma - 2*t2/sigma2).*exp(-(t2.^2)/sigma2)).';

    else
        upsilonaa = gamma^2*lfmapComputeUpsilonMatrix(gamma, sigma2, t1, t2, 0) ...
            + (2/(sqrt(pi)*sigma))*exp(-(timeGrid.^2)./sigma2).* ...
            ((gamma + 2*timeGrid/sigma2).*(2/sigma2 - (2*timeGrid/sigma2).^2) + 8*timeGrid/sigma^4) ...
            + (2*gamma^2/(sqrt(pi)*sigma))*exp(-gamma*t1)*((gamma - 2*t2/sigma2).*exp(-(t2.^2)/sigma2)).';
    end
end


clear all; close all;
I=imread('cameraman.tif');
I=im2double(I);
J=fftshift(fft2(I));
[x, y]=meshgrid(-128:127, -128:127);
z=sqrt(x.^2+y.^2);
D1=10;  D2=30;
n=6;
H1=1./(1+(z/D1).^(2*n));
H2=1./(1+(z/D2).^(2*n));
K1=J.*H1;
K2=J.*H2;
L1=ifft2(ifftshift(K1));
L2=ifft2(ifftshift(K2));
figure;
subplot(131);
imshow(I);
subplot(132);
imshow(real(L1));
subplot(133);
imshow(real(L2))


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

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

  x = burr_cdf_inv ( cdf, a, b, c, d );

  return
end


function [lambda_vec, error_train, error_val] = ...
    validationCurve(X, y, Xval, yval)
%VALIDATIONCURVE Generate the train and validation errors needed to
%plot a validation curve that we can use to select lambda
%   [lambda_vec, error_train, error_val] = ...
%       VALIDATIONCURVE(X, y, Xval, yval) returns the train
%       and validation errors (in error_train, error_val)
%       for different values of lambda. You are given the training set (X,
%       y) and validation set (Xval, yval).
%

% Selected values of lambda (you should not change this)
lambda_vec = [0 0.001 0.003 0.01 0.03 0.1 0.3 1 3 10]';

% You need to return these variables correctly.
error_train = zeros(length(lambda_vec), 1);
error_val = zeros(length(lambda_vec), 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Fill in this function to return training errors in
%               error_train and the validation errors in error_val. The
%               vector lambda_vec contains the different lambda parameters
%               to use for each calculation of the errors, i.e,
%               error_train(i), and error_val(i) should give
%               you the errors obtained after training with
%               lambda = lambda_vec(i)
%
% Note: You can loop over lambda_vec with the following:
%
%       for i = 1:length(lambda_vec)
%           lambda = lambda_vec(i);
%           % Compute train / val errors when training linear
%           % regression with regularization parameter lambda
%           % You should store the result in error_train(i)
%           % and error_val(i)
%           ....
%
%       end
%
%

for i = 1:length(lambda_vec)
    lambda = lambda_vec(i);

    theta = trainLinearReg(X, y, lambda);

    error_train(i) = linearRegCostFunction(X, y, theta, 0);
    error_val(i) = linearRegCostFunction(Xval, yval, theta, 0);
end

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

end

github-repos/MATLAB/Borye-machine-learning-coursera-1/machine-learning-coursera-1-033fdc2e6da393eeb1179a09aafe92362021effb/Week 6 Assignments/Regularized Linear Regression and Bias,Variance/mlclass-ex5-005/mlclass-ex5/validationCurve.m


function yi=akimai(x,y,xi)
%
% Usage: yi=akimai(x,y,xi)
%
%        Given vectors x and y (of the same length)
%        and the array xi at which to interpolate,
%        fits piecewise cubic polynomials and returns
%        the interpolated values yi at xi.
%
% Ref. : Hiroshi Akima, Journal of the ACM, Vol. 17, No. 4, October 1970,
%        pages 589-602.
%
% Programmer: N. Shamsundar, University of Houston, 6/2002
%   Correction to lines 32-33, 9/2004,  motivated by Gilford Ward,
%     to make routine work correctly for linear data.
%
% Notes: Use only for precise data, as the fitted curve passes through the
%        given points exactly. This routine is useful for plotting a pleasingly
%        smooth curve through a few given points for purposes of plotting.
%
x=x(:); y=y(:); xi=xi(:); n=length(x);
if n~=length(y), error('input x and y arrays must be of same length'), end
dx=diff(x); if any(dx <= 0) error('input x-array must be in strictly ascending order'), end
if any(xi<x(1)) | any(xi > x(n))
  warning('All interpolation points xi must lie between x(1) and x(n)')
end
m=diff(y)./dx;
mm=2*m(1)-m(2);     mmm=2*mm-m(1);     % augment at left
mp=2*m(n-1)-m(n-2); mpp=2*mp-m(n-1);   % augment at right
m1=[mmm; mm; m; mp; mpp];              % slopes
dm=abs(diff(m1)); f1=dm(3:n+2); f2=dm(1:n); f12=f1+f2;
id=find(f12 > 1e-8*max(f12)); b=m1(2:n+1);
b(id)=(f1(id).*m1(id+1)+f2(id).*m1(id+2))./f12(id);
c=(3*m-2*b(1:n-1)-b(2:n))./dx;
d=(b(1:n-1)+b(2:n)-2*m)./dx.^2;

% Loop replaced by vector ops following tip from johannes.korsawe@volkswagen.de
% 1/19/2006
%
[ncnt,bin]=histc(xi,x);
bin=min(bin,n-1);
bb=bin(1:length(xi));
wj=xi-x(bb);
yi=((wj.*d(bb) +c(bb)).*wj+b(bb)).*wj+y(bb);