function KM = computeKernelMatrix(P1, P2, kType, kParam)
%COMPUTEKERNELMATRIX computes the kernel matrix between two sets of patterns
%
%   KM = computeKernelMatrix(P1, P2, kType, kParam) computes kernel matrix
%   KM between sets of patterns P1 and P2. kType is the type of the kernel
%   function (Gauss, Linear, Quickrbf, Poly, or Sigmoid). KPARAM is the
%   kernel parameter, for instance the width of the Gaussian kernel.
%
% Function inputs:
%   patterns1, patterns2   - Two matrixes of patterns (train and test, or train and train)
%   kernelType             - Kernel function choice. Can be  Gauss, Linear, Quickrbf, Poly, or Sigmoid.
%   kernelMatrix           - The kernel matrix
%
%   This file is part of ORCA: https://github.com/ayrna/orca
%   Original authors: Pedro Antonio Gutiérrez, María Pérez Ortiz, Javier Sánchez Monedero
%   Citation: If you use this code, please cite the associated paper http://www.uco.es/grupos/ayrna/orreview
%   Copyright:
%       This software is released under the The GNU General Public License v3.0 licence
%       available at http://www.gnu.org/licenses/gpl-3.0.html
%
Nf1             = size(P1, 2);
Nf2             = size(P2, 2);
KM   = zeros(Nf1, Nf2);

switch upper(kType)
    case {'GAUSS','GAUSSIAN','RBF'}

        for i = 1:Nf2
            KM(:,i)  = exp(-kParam*sum((P1-P2(:,i)*ones(1,Nf1)).^2)');

        end

    case {'QUICKRBF'}
        d = pdistalt(P1,P2,'euclidean');
        KM = exp(-kParam*d.^2);

    case {'POLYNOMIAL', 'POLY', 'LINEAR'}
        if strcmpi(kType, 'LINEAR')
            kParam = 1;
            bias = 0;
        else
            bias = 1;
        end
        KM = ((P1' * P2 + bias)/size(P1,1)).^kParam;

    case 'SIGMOID'

        if (length(kParam) ~= 2)
            error('This kernel needs two parameters to operate!')
        end

        KM   = zeros(Nf1, Nf2);
        for i = 1:Nf2
            KM(:,i)  = tanh(P1'*P2(:,i)*kParam(1)+kParam(2));
        end

    otherwise
        error('Unknown kernel. Can be Gauss, Linear, Quickrbf, Poly, or Sigmoid.')

end


function X = lyap(A, B, C)
%LYAP  Solve continuous-time Lyapunov equations.
%
%   X = LYAP(A,C) solves the special form of the Lyapunov matrix
%   equation:
%
%           A*X + X*A' = -C
%
%   X = LYAP(A,B,C) solves the general form of the Lyapunov matrix
%   equation (also called Sylvester equation):
%
%           A*X + X*B = -C
%
%   See also  DLYAP.

%	S.N. Bangert 1-10-86
%	Copyright (c) 1986-98 by The MathWorks, Inc.
%	$Revision: 1.4 $  $Date: 1997/12/01 22:11:32 $
%	Last revised JNL 3-24-88, AFP 9-3-95

ni = nargin;

if ni==2,
   C = B;
   B = A';
end

[ma,na] = size(A);
[mb,nb] = size(B);
[mc,nc] = size(C);

% A and B must be square and C must have the rows of A and columns of B
if (ma ~= na) | (mb ~= nb) | (mc ~= ma) | (nc ~= mb)
   error('Dimensions do not agree.')
elseif ma==0,
   X = [];
   return
end

% Perform schur decomposition on A (and convert to complex form)
[ua,ta] = schur(A);
[ua,ta] = rsf2csf(ua,ta);
if ni==2,
   % Schur decomposition of A' can be calculated from that of A.
   j = ma:-1:1;
   ub = ua(:,j);
   tb = ta(j,j)';
else
   % Perform schur decomposition on B (and convert to complex form)
   [ub,tb] = schur(B);
   [ub,tb] = rsf2csf(ub,tb);
end

% Check all combinations of ta(i,i)+tb(j,j) for zero
p1 = diag(ta).'; % Use .' instead of ' in case A and B are not real
p1 = p1(ones(mb,1),:);
p2 = diag(tb);
p2 = p2(:,ones(ma,1));
sum = abs(p1) + abs(p2);
if any(any(sum == 0)) | any(any(abs(p1 + p2) < 1000*eps*sum))
   error('Solution does not exist or is not unique.');
end

% Transform C
ucu = -ua'*C*ub;

% Solve for first column of transformed solution
y = zeros(ma,mb);
ema = eye(ma);
y(:,1) = (ta+ema*tb(1,1))\ucu(:,1);

% Solve for remaining columns of transformed solution
for k=2:mb,
   km1 = 1:(k-1);
   y(:,k) = (ta+ema*tb(k,k))\(ucu(:,k)-y(:,km1)*tb(km1,k));
end

% Find untransformed solution
X = ua*y*ub';

% Ignore complex part if real inputs (better be small)
if isreal(A) & isreal(B) & isreal(C),
   X = real(X);
end

% Force X to be symmetric if ni==2 and C is symmetric
if (ni==2) & isequal(C,C'),
   X = (X+X')/2;
end

% end lyap


function DeriveDynamicsDP(P)

%FUNCTION:
%   This function is used to derive the analytic equations of motion for a
%   forced double pendulum. This also does the kimenatics and energy
%   calculations.

%State Naming Conventions:
% th = absolute angle of the first link measured wrt the positive horizontal axis (i)
% phi = absolute angle of the second link measured wrt the positive horizontal axis (i)
% Dth = first time derivative of th
% Dphi = first time derivative of phi

%NOTE: It might be faster to use the jacobian command to find the symbolic
%coeffieints of the mass matrix and then invert the system, rather than
%symbolically inverting the matrix.
%

% Define the angles and derivatives
    th = sym('th');
    Dth = sym('Dth');
    DDth = sym('DDth');

    phi = sym('phi');
    Dphi = sym('Dphi');
    DDphi = sym('DDphi');

% Define the scalar parameters
    g = sym('g');   %gravity
    L = sym('L');    %Lenght of each link
    m1 = sym('m1');    %mass of the link
    m2 = sym('m2');    %mass of the link

% Known Vectors
    F1_x = sym('F1_x');
    F1_y = sym('F1_y');
    F1 = [F1_x;F1_y];   %External force at CoM of first link

    F2_x = sym('F2_x');
    F2_y = sym('F2_y');
    F2 = [F2_x;F2_y];   %External force at CoM of 2nd link

    M1 = sym('M1');   %Input torque on link on
    M2 = sym('M2');   %Input torque between links 1 and 2

% UNIT VECTORS:
    i = [1;0];
    j = [0;1];

    a1 = cos(th)*i + sin(th)*j;   %The direction along the first link
    b1 = -sin(th)*i + cos(th)*j;
    Da1 = Dth*b1;
    Db1 = -Dth*a1;
    DDa1 = DDth*b1 + Dth*Db1;
    DDb1 = -DDth*a1 -Dth*Da1;

    a2 = cos(phi)*i + sin(phi)*j;   %The direction along the second link
    b2 = -sin(phi)*i + cos(phi)*j;
    Da2 = Dphi*b2;
    Db2 = -Dphi*a2;
    DDa2 = DDphi*b2 + Dphi*Db2;
    DDb2 = -DDphi*a2 -Dphi*Da2;

%Weights
    W1 = -m1*g*j;   %weight of the first link
    W2 = -m2*g*j;   %weight of the second link

%Kinematic vectors
    r_P1_O = L*a1;    %Position of the point mass 1
    v_P1_O = L*Da1;
    a_P1_O = L*DDa1;

    r_P2_O = L*a1 + L*a2;    %Position of point mass 2
    v_P2_O = L*Da1 + L*Da2;
    a_P2_O = L*DDa1 + L*DDa2;

    r_P2_P1 = L*a2;   %Relative position of the tip with respect to the mid joint

%Momentum balance for both links about the origin
    %       = Moment from weight 1 +  moment from weight 2 + Control torque 1
    Sum_M_O = Cross(r_P1_O,F1+W1) + Cross(r_P2_O,F2+W2) + M1;
    %        = translation mass 1  + translation mass 2
    Sum_DH_O = Cross(r_P1_O,m1*a_P1_O) + Cross(r_P2_O,m2*a_P2_O);

%Momentum balance for second link about central pivot
    %         moment from weight 2  +  control moment
    Sum_M_P1 = Cross(r_P2_P1,F2+W2) + M2;
    %         translation mass 2 +
    Sum_DH_P1 = Cross(r_P2_P1,m2*a_P2_O);

%Simplify
    AMB_1 = simplify(Sum_M_O - Sum_DH_O);
    AMB_2 = simplify(Sum_M_P1 - Sum_DH_P1);

% Solve the system of equations:
    Soln = solve( AMB_1, ...    %AMB for system
           AMB_2, ...    %AMB for second link
            DDth,...                      %acceleration of first joint
            DDphi  );                    %acceleration of second joint

    Soln.DDth = simplify(Soln.DDth);   %Simplify the result
    Soln.DDphi = simplify(Soln.DDphi);   %Simplify the result

%Write the results to a file  --  these are scripts!
if P.misc.CppFlag
    WriteDynamicsFile_Cpp    %Call a script that write the dynamics to a file
else
    WriteDynamicsFile_Matlab;   %Call a script that write the dynamics to a file
end
WriteKinematicsFile_Matlab;   %Call a script that writes the equations for kinetics

end


function [xi,w]=firstOrderTriangleCubPoints()
%%FIRSTORDERTRIANGLECUBPOINTS Obtain first-order cubature points for
%   integration over a triangle in 2D. The points and weights are for the
%   triangle with vertices (1,0), (0,1), (0,0), but can be transformed to
%   any triangle using transformSimplexTriPoints.
%
%INPUTS: None
%
%OUTPUTS: xi A 2XnumCubPoints set of points for the standard triangle.
%          w A 1XnumCubPoints set of cubature weights. This sums to the
%            volume of the triangle (1/2).
%
%This function implements the points given in [1] (3 points).
%
%EXAMPLE:
%Given the vertices of the simplex, we compare a first-order moment
%computed using these cubature points to one computed using
%monomialIntSimplex. The results are the same within typical finite
%precision limits.
% [xi,w]=firstOrderTriangleCubPoints();
% alpha=[1;0];
% theMoment=findMomentFromSamp(alpha,xi,w)
% intVal=monomialIntSimplex(alpha)
%
%REFERENCES:
%[1] F. D. Witherden and P. E. Vincent, "On the identification of symmetric
%    quadrature rules for finite element methods," Computer and Mathematics
%    with Applications, vol. 69, no. 10, pp. 1232-1241, May 2015.
%
%October 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

M=[-0.33333333333333333333333333333333333333, -0.33333333333333333333333333333333333333, 2];
w=M(:,3);
xi=M(:,1:2)';
%Transform the points to the standard triangle.
v1=[-1,-1, 1;
    -1, 1,-1];
v2=[1,0,0;
    0,1,0];
[A,d]=affineTransBetweenTriangles(v1,v2);
xi=bsxfun(@plus,A*xi,d);
w=w/4;
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.


%% Structured grid
% This is a sample code showing how to use ConstructProjector3D().
% This example is going to setup a transformation matrix based on forth
% order polynomials in 3D.
% Pay attention that no data is needed to construct the interpolator. Only
% the coordinates of the points on source and destination grid.
clear;clc;
%% Initializing Part I
disp('- Initializing')
xMin=0;
xMax=2*pi;
yMin=0;
yMax=2*pi;
zMin=0;
zMax=2*pi;

nx=20;
ny=20;
nz=20;

dx=(xMax-xMin)/(nx-1);
dy=(yMax-yMin)/(ny-1);
dz=(zMax-zMin)/(nz-1);

nPoly=2; % We gonna fit a fourth order polynomial,
         % i.e. sum_{n,m,t=0}^{n,m,t=nPoly} x^n*y^m*z^t
nInterp=27:37;

%% Turning off the warnings
% Depending on the parameter that you choose the matrices might be nearly
% singular. In this example, despite being nearly singular, they are not
% affecting the final interpolation. Therefore, I set the warning to off.
% But generally do not turn it off and if you got this warning check if it
% is going to affect your results or not.
% disp('- Turning the warnings off')
% warning('OFF','MATLAB:nearlySingularMatrix');

%% Generating the Source Grid
disp('- Generating the source grid.')
[xn,yn,zn]=meshgrid(linspace(xMin,xMax,nx),linspace(yMin,yMax,ny),linspace(zMin,zMax,nz));

%% Finding the cell centers
disp('- Generating the destination grid')
xc=xn(1:ny-1,1:nx-1,1:nz-1)+dx/2;
yc=yn(1:ny-1,1:nx-1,1:nz-1)+dy/2;
zc=zn(1:ny-1,1:nx-1,1:nz-1)+dz/2;

% figure
% plot3(xn(:),yn(:),zn(:),'k.','MarkerSize',20);
% hold on
% plot3(xc(:),yc(:),zc(:),'b.','MarkerSize',20);
% axis tight;
% axis square;
% title('Source Grid, black dots, & the destination grid, blue dots.', ...
%       'FontName','Arial','FontSize',12,'FontWeight','Bold');

%% Generarting some Data
disp('- Generating some data and interpolating')
F1=@(x,y,z) (sqrt(x.^2+y.^2+z.^2));
Vn=F1(xn,yn,zn);
Vc_Analytic=F1(xc,yc,zc);

%% Generating the interpolant
disp('- Generating the interpolant and testing nInterp')
RMSE=zeros(size(nInterp));
for i=1:numel(nInterp)
  disp(['-- nInterp= ' num2str(nInterp(i))])
  P=ConstructProjector3D(xn(:),yn(:),zn(:),xc(:),yc(:),zc(:),nPoly,nInterp(i));
  % Interpolating
  Vc_interp=P*Vn(:);

  % Calculating the RMSE
  RMSE(i)=sqrt(mean( (Vc_interp-Vc_Analytic(:)).^2 ));
  disp(['   RMSE= ' num2str(RMSE(i))])
end
%% plotting

figure
plot(nInterp,RMSE,'b.-')
xlabel('nInterp');
ylabel('RMSE');
axis tight

disp('All done!')


function value = torus_volume_3d ( r1, r2 )

%*****************************************************************************80
%
%% TORUS_VOLUME_3D returns the volume of a torus in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that:
%
%      ( SQRT ( X**2 + Y**2 ) - R1 )**2 + Z**2 = R2**2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, the two radii that define the torus.
%
%    Output, real TORUS_VOLUME_3D, the volume of the torus.
%
  value = 2.0 * pi * pi * r1 * r2 * r2;

  return
end


function theta = circle3dPosition(point, circle)
%CIRCLE3DPOSITION Return the angular position of a point on a 3D circle
%
%   POS = circle3dPosition(POINT, CIRCLE)
%   Returns angular position of point on the circle, in degrees, between 0
%   and 360.
%   with POINT: [xp yp zp]
%   and CIRCLE: [X0 Y0 Z0 R THETA PHI] or [X0 Y0 Z0 R THETA PHI PSI]
%   (THETA being the colatitude, and PHI the azimut)
%
%   See also:
%   circles3d, circle3dOrigin, circle3dPoint
%
%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 21/02/2005
%

%   HISTORY
%   27/06/2007: change 3D angle convention
%   2011-06-21 use degrees for angles

% get center and radius
xc = circle(:,1);
yc = circle(:,2);
zc = circle(:,3);

% get angle of normal
theta   = circle(:,5);
phi     = circle(:,6);

% find origin of the circle
ori     = circle3dOrigin(circle);

% normal vector of the supporting plane (cartesian coords)
vn      = sph2cart2d([theta phi]);

% create plane containing the circle
plane   = createPlane([xc yc zc], vn);

% find position of point on the circle plane
pp0     = planePosition(ori,    plane);
pp      = planePosition(point,  plane);

% compute angles in the planes
theta0  = mod(atan2(pp0(:,2), pp0(:,1)) + 2*pi, 2*pi);
theta   = mod(atan2(pp(:,2), pp(:,1)) + 2*pi - theta0, 2*pi);

% convert to degrees
theta = theta * 180 / pi;


function [varargout] = dcblock(varargin);
%
% DCBLOCK   determines the filter coefficient a for the dc blocking/high-
%           pass filter y(t) = x(t) - x(t-1) + a*y(t-1).
%
%           [a] = dcblock(Fc) returns the filter coefficient a for
%           normalized cut-on frequency Fc.
%
%           [a] = dcblock(fc,fs)returns the filter coefficient a for cut-on
%           frequency fc, and sampling frequency fs, when both are given in
%           Hz.
%
%           [aQ] = dcblock(fc,fs,B) returns the quantized filter
%           coefficient aQ when the quantization level B is given.
%
%           dcblock(...) plots the frequency and phase response of the
%           filter.
%
%           Note that if two parameters are passed to the function without
%           an output argument, the plot routine always interprets the
%           first as fc and the second as fs.
%
% SYNTAX    [a] = dcblock(Fc);
%           [a] = dcblock(fc,fs);
%           [aQ] = dcblock(fc,fs,B);
%           [Fc,fc] = dcblock(a,fs);
%           dcblock(Fc)
%           dcblock(fc,fs)
%           dcblock(fc,fs,B)
%
% INPUT     Fc      Normalized frequency cut-on of the filter.
%                   Fc = fc[Hz]/(fs[Hz]/2); fs/2 is the Nyquist frequency.
%                   Note that 0 < Fc < 1/3;
%
%           fc      filter cut-on frequency in Hz (or other reciprocal
%                   units of frequency e.g. 1/metre).
%
%           fs      sampling frequency in Hz (or other reciprocal
%                   units of frequency e.g. 1/metre).
%
%           B       quantization level for fixed point processing e.g. B is
%                   16 for 16-bit operation.
%
% OUTPUT    a       filter coefficient; 0 < a < 1 for floating point
%                   operation.
%
%           aQ      quantized filter coefficient a; 0 < aQ < 2^(B-1) - 1.
%                   The quantization level is set by B which is assumed to
%                   be signed integer.
%
% EXAMPLES  (1) Calculate the filter coefficient a when the normalized
%               frequency is 1E-5:
%
%           >> format long                      % set display format
%           >> a = dcblock(1E-5)                % Fc = 0.00001
%           >> a = 0.99994558749947             % filter coefficient
%
%           (2) Calculate the normalized and true cut-on frequency when the
%               coefficient a is 0.9987 and the sampling frequency is 1MHz:
%
%           >> [Fc,fc] = dcblock(0.9987,1E6)    % a = 0.9987; fs = 1MHz
%           >> Fc = 2.3906E-004                 % this output is normalized
%           >> fc = 119.5323                    % this output is in Hz
%
%           Note the difference in inputs between [Fc,fc] = dcblock(a,fs),
%           the function call [a] = dcblock(fc,fs), and its plot facility
%           dcblock(fc,fs). You can plot the filter response using
%
%           >> dcblock(119.5323,1E6)            % fc = 119.5323; fs = 1E6
%
%           (3) Carry out filtering operation using the dc blocking filter
%               with cut-on frequency of 70Hz and sampling rate of 10kHz.
%
%           t = -0.1:1/10000:0.1-1/10000;       % set up time base
%           s = sin(2*pi*2.5*t+pi/6)+0.01*randn(size(t))+1.25;
%           x = gauspuls(t,250,0.6) + s;        % noisy Gaussian test pulse
%           p = dcblock(70,10000);              % get filter coefficient
%           b = [1 -1];                         % set up differentiator
%           a = [1 -p];                         % set up integrator
%           y = filter(b,a,x);                  % filter test data
%           plot(t,x,t,y)                       % plot results to screen
%           legend('Original','DC Filtered','location','northwest');
%
%           The forward pass of the filter creates a distortion in the
%           Gaussian pulse. This distortion can be removed by using the
%           filtfilt form of the filter. If you now try
%
%           y2 = filtfilt(b,a,x);               % filter test data
%           plot(t,x,t,y,t,y2)                  % plot results to screen
%           legend('Original','DC Filtered','Undistorted','location','northwest');
%
%           you will notice that the symmetry of the Gaussian pulse has
%           been restored.
%
% See also FILTER, FILTFILT, SPTOOL, FDATOOL.

% Author:   J M De Freitas
%           QinetiQ Ltd, Winfrith Technology Centre
%           Winfrith, Dorchester DT2 8XJ, UK.
%
% Email     jdefreitas@qinetiq.com
%
% Revision  1.0
%
% Date      11 October 2006.
%

% Perform checks on input and output
Lin = nargin;
Lout = nargout;
if Lin > 3
    error('dcblock error: Too many input arguments.');
end
if Lin < 1
    errror('dcblock error: No input argument used.');
end
if Lout > 2
    error('dcblock error: Too many output arguments.');
end

% Calculate a when Fc is given and plot response if required
if Lin == 1
    Fc = varargin{1};
    if (Fc < 0)|(Fc > 1/3)
        error('dcblock error: Normalized cut-on frequency must be between 0 and 1/3.');
    end
    a = coef(Fc);
    if Lout == 1
        varargout{1} = a;
    elseif Lout == 0
        PlotResp(1,a);
    end
end

% Calculate a when fc and fs are given and plot response if required
% or Fc and fc when a and fs are given
if Lin == 2
    if (Lout == 1)|(Lout == 0)
        fc = varargin{1};
        fs = varargin{2};
        Fc = 2*fc/fs;
        if (Fc < 0)|(Fc > 1/3)
            error('dcblock error: Cut-on frequency must be between 0 and fs/6.');
        end
        a = coef(Fc);
        if Lout == 1
            varargout{1} = a;
        else
            PlotResp(fs/2,a);
        end
    elseif Lout == 2
        a = varargin{1};
        fs = varargin{2};
        if (a < 0)|(a > 1)
            error('dcblock error: Filter coefficient a must be between 0 and 1.');
        end
        Fc = atan(sqrt(3)*(1-a^2)/(1+4*a+a^2))/pi;
        varargout{1} = Fc;
        varargout{2} = Fc*fs/2;
    end
end

% Calculate a when B, fc and fs are given and plot if required
if Lin == 3
    fc = varargin{1};
    fs = varargin{2};
    B = floor(varargin{3});
    Fc = 2*fc/fs;
    if (Fc < 0)|(Fc > 1/3)
        error('dcblock error: Cut-on frequency fc must be between 0 and fs/6.');
        return
    end
    if (B <= 2)|(B > 300)
        error('dcblock error: Quantization level B must be between 2 and 300.');
        return
    end
    a = coef(Fc);
    if Lout == 1
        varargout{1} = floor(a*(2^(B-1)-1));
    elseif Lout == 0
        aQ = floor(a*(2^(B-1)-1))/(2^(B-1)-1);
        PlotResp(fs/2,aQ);
    end
end

function a = coef(Fc);
% get up coefficient
    a = (sqrt(3) - 2*sin(pi*Fc))/(sin(pi*Fc) + sqrt(3)*cos(pi*Fc));

function PlotResp(Fn,a);
% Plot frequency and phase response
    f = 0.000001:0.000001:1-0.000001;
    h = (1+a)*sin(pi*f/2)./sqrt(1+a^2-2*a*cos(pi*f));
    phi = atan((1-a)*(sin(pi*f)./(1-cos(pi*f)))/(1+a));
    indigo = [.48 .06 .89];
    subplot(2,1,1);
        loglog(Fn*f,h,'LineWidth',1.5,'Color',indigo);
        title('\bf Frequency Response: IIR DC Blocking Filter','Color','k');
        if Fn == 1
            xlabel('Normalized Frequency');
        else
            xlabel('Frequency (Hz)');
        end
        ylabel('Magnitude ');
        minY = min(get(gca,'YTick'));
        minX = min(get(gca,'XTick'));
        maxX = max(get(gca,'XTick'));
        if minY >= 0.1
            TickY = [0.1 1];
        else
            for j = 1:abs(log10(minY))+1 TickY(j) = 10^(log10(minY)+j-1); end
        end
        for j = 1:(log10(maxX)-log10(minX))+1 TickX(j) = 10^(log10(minX)+j-1); end
        ylim([TickY(1) 1.1]);
        set(gca,'XGrid','on','YGrid','on','XMinorGrid','on',...
        'YMinorGrid','on','GridLineStyle','-',...
        'MinorGridLineStyle','-','Xtick',TickX,'Ytick',TickY,...
        'Color',[0.835 0.918 0.918]);
    subplot(2,1,2);
        loglog(Fn*f,phi*180/pi,'LineWidth',1.5,'Color',indigo);
        title('\bf Phase Response: IIR DC Blocking Filter','Color','k');
        if Fn == 1
            xlabel('Normalized Frequency');
        else
            xlabel('Frequency (Hz)');
        end
        ylabel('Phase (degree) ');
        ylim([0.1 100]);
        minX = min(get(gca,'XTick'));
        maxX = max(get(gca,'XTick'));
        for j = 1:(log10(maxX)-log10(minX))+1
            TickX2(j) = minX*10^(j-1) ;
        end
        set(gca,'XGrid','on','YGrid','on','XMinorGrid','on',...
        'YMinorGrid','on','GridLineStyle','-',...
        'MinorGridLineStyle','-','Xtick',TickX2,'YTick',[0.1 1 10 100],...
        'Color',[0.835 0.918 0.918]);


%  Script file: calc_roots2.m
%
%  Purpose:
%    This program solves for the roots of a quadratic equation
%    of the form a*x**2 + b*x + c = 0.  It calculates the answers
%    regardless of the type of roots that the equation possesses.
%
%  Record of revisions:
%      Date       Programmer          Description of change
%      ====       ==========          =====================
%    02/24/07    S. J. Chapman        Original code
%
% Define variables:
%   a            -- Coefficient of x^2 term of equation
%   b            -- Coefficient of x term of equation
%   c            -- Constant term of equation
%   discriminant -- Discriminant of the equation
%   x1           -- First solution of equation
%   x2           -- Second solution of equation

% Prompt the user for the coefficients of the equation
disp ('This program solves for the roots of a quadratic ');
disp ('equation of the form A*X^2 + B*X + C = 0. ');
a = input ('Enter the coefficient A: ');
b = input ('Enter the coefficient B: ');
c = input ('Enter the coefficient C: ');

% Calculate discriminant
discriminant = b^2 - 4 * a * c;

% Solve for the roots
x1 = ( -b + sqrt(discriminant) ) / ( 2 * a );
x2 = ( -b - sqrt(discriminant) ) / ( 2 * a );

% Display results
disp ('The roots of this equation are:');
fprintf ('x1 = (%f) +i (%f)\n', real(x1), imag(x1));
fprintf ('x2 = (%f) +i (%f)\n', real(x2), imag(x2));


function f=dctresample(f,L,dim)
%DCTRESAMPLE   Resample signal using Fourier interpolation
%   Usage:  h=dctresample(f,L);
%           h=dctresample(f,L,dim);
%
%   `dctresample(f,L)` returns a discrete cosine interpolation of the signal *f*
%   to length *L*. If the function is applied to a matrix, it will apply
%   to each column.
%
%   `dctresample(f,L,dim)` does the same along dimension *dim*.
%
%   If the input signal is not a periodic signal (or close to), this method
%   will give much better results than |fftresample| at the endpoints, as
%   this method assumes than the signal is even a the endpoints.
%
%   The algorithm uses a DCT type iii.
%
%   See also:  fftresample, middlepad, dctiii

%   AUTHOR: Peter L. Søndergaard

% ------- Checking of input --------------------
complainif_argnonotinrange(nargin,2,3,mfilename);

if nargin<3
  dim=[];
end;

[f,L,Ls,W,dim,permutedsize,order]=assert_sigreshape_pre(f,L,dim,'DCTRESAMPLE');

wasreal=isreal(f);

% The 'dim=1' below have been added to avoid dct and middlepad being
% smart about choosing the dimension.
f=dctiii(postpad(dctii(f,[],1),L))*sqrt(L/Ls);

f=assert_sigreshape_post(f,dim,permutedsize,order);

if wasreal
  f=real(f);
end;


function f1 = p07_f1 ( x )

%*****************************************************************************80
%
%% P07_F1 evaluates the first derivative for problem 7.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 February 2002
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the value of the variable.
%
%    Output, real F1, the first derivative of the
%    objective function.
%
  f1 = ( 1.0 - 2.0 * x * x + cos ( x ) ...
         - 2.0 * x * sin ( x ) ) * exp ( - x * x );

  return
end


function inside = sphere_imp_contains_point_3d ( r, center, p )

%*****************************************************************************80
%
%% SPHERE_IMP_CONTAINS_POINT_3D: point in implicit sphere in 3D?
%
%  Discussion:
%
%    An implicit sphere in 3D satisfies the equation:
%
%      sum ( ( P(1:DIM_NUM) - CENTER(1:DIM_NUM) )**2 ) = R**2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real CENTER(3), the center of the sphere.
%
%    Input, real P(3), the point to be checked.
%
%    Output, logical INSIDE, is TRUE if the point is inside the sphere.
%
  dim_num = 3;

  if ( sum ( ( p(1:dim_num) - center(1:dim_num) ).^2 ) <= r * r )
    inside = 1;
  else
    inside = 0;
  end

  return
end


function er4OC
%EG4OC    Example 4 of optimal control tutorial.
%    This example is from the following reference:
%    S.N.Avvakumov and Yu.N.Kiselev, "Boundary value problem for ordinary
%    differential equations with applications to optimal control".
%    Example 5 on page 8

global mu;
mu = 0.5;
solinit = bvpinit(linspace(0,1,10),[2;2;0;-1],4);

sol = bvp4c(@ode,@bc,solinit);

figure(1)
lines = {'k-.','r--','b-'};
ut = sol.y(4,:)./sqrt(mu*sol.y(3,:).^2+sol.y(4,:).^2);
t = sol.parameters*sol.x;
plot(t,ut,lines{1});
% axis([-0.1 1.1 0 1.7]);
title('Smoothed control');
xlabel('t');
ylabel('u');
drawnow; hold on;

figure(2)
plot(sol.y(1,:),sol.y(2,:),lines{1});
% axis([-0.1 1.1 0 1.7]);
title('Admissible trajectories');
xlabel('x_1');
ylabel('x_2');
drawnow; hold on;

% the solution for one value of mu is used as guess for the next.
for i=2:3
  if i==2
      mu = 0.3;
  else
      mu = .1;
  end;
  % After creating function handles, the new value of mu
  % will be used in nested functions.
  sol = bvp4c(@ode,@bc,sol);
  figure(2)
  plot(sol.y(1,:),sol.y(2,:),lines{i});
  drawnow;

  figure(1)
  ut = sol.y(4,:)./sqrt(mu*sol.y(3,:).^2+sol.y(4,:).^2);
  t = sol.parameters*sol.x;
  plot(t,ut,lines{i});
  drawnow;

end
figure(1); legend('mu = 0.5', 'mu = 0.3', 'mu = 0.1', ...
                  'Location', 'NorthWest'); hold off;
figure(2); legend('mu = 0.5', 'mu = 0.3', 'mu = 0.1', ...
                  'Location', 'NorthWest'); hold off;

% print -djpeg90 -f1 -r300 eg4_trajectory.jpg;
% print -djpeg90 -f2 -r300 eg4_control.jpg

% --------------------------------------------------------------------------
function dydt = ode(t,y,T)
global mu;
term = sqrt(mu*y(3)^2+y(4)^2);
dydt = T*[ y(2) + mu*y(3)/term
           y(4)/term
           0
           -y(3)];

% --------------------------------------------------------------------------
% boundary conditions, with 4 states and 1 parameters, 5 conditions are
% needed: x1(0) =2, x2(0) = 2; x1(1) = 0; x2(1) = 0; x3(1)^2+x4(1)^2 = 1;
function res = bc(ya,yb,T)
res = [ya(1)-2
       ya(2)-2
       yb(1)
       yb(2)
       yb(3)^2+yb(4)^2-1];


function [v,unv] = statmoments(p,n)
%STATMOMENTS Computes statistical central moments of image histogram.
%   [W,UNV] = STATMOMENTS(P,N) computes up to the Nth statistical
%   central moment of a histogram whose components are in vector
%   P. The length of P must equal 256 or 65536.
%
%   The program outputs a vector V with V(1) = mean, V(2) = variance,
%   V(3) = 3rd moment, . . . V(N) = Nth central moment. The random
%   variable values are normalized to the range [0,1], so all
%   moments also are in this range.
%
%   The program also outputs a vector UNV containing the same moments
%   as V, but using un-normalized random variable values (e.g., 0 to
%   255 if length(P) = 2^8). For example, if length(P) = 256 and V(1)
%   = 0.5, then UNV(1) would have the value UNV(1) = 127.5 (half of
%   the [0,255] range).
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

Lp = length(p);
if (Lp ~= 256) && (Lp ~= 65536)
   error('P must be a 256- or 65536-element vector.');
end
G = Lp - 1;

% Make sure the histogram has unit area, and convert it to a
% column vector.
p = p/sum(p); p = p(:);

% Form a vector of all the possible values of the
% random variable.
z = 0:G;

% Now normalize the z's to the range [0,1].
z = z./G;

% The mean.
m = z*p;

% Center random variables about the mean.
z = z - m;

% Compute the central moments.
v = zeros(1,n);
v(1) = m;
for j = 2:n
   v(j) = (z.^j)*p;
end

if nargout > 1
   % Compute the uncentralized moments.
   unv = zeros(1,n);
   unv(1)=m.*G;
   for j = 2:n
      unv(j) = ((z*G).^j)*p;
   end
end


function s = legendre_integral ( p )

%*****************************************************************************80
%
%% LEGENDRE_INTEGRAL evaluates a monomial Legendre integral.
%
%  Discussion:
%
%    To test a Legendre quadrature rule, we use it to approximate the
%    integral of a monomial:
%
%      integral ( -1 <= x <= +1 ) x^p dx
%
%    This routine is given the value of the exponent, and returns the
%    exact value of the integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 May 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer P, the power.
%
%    Output, real S, the value of the exact integral.
%

%
%  Get the exact value of the integral.
%
  if ( mod ( p, 2 ) == 0 )

    s = 2.0 / ( p + 1 );

  else

    s = 0.0;

  end

  return
end


function value = torus_square_area_3d ( r1, r2 )

%*****************************************************************************80
%
%% TORUS_SQUARE_AREA_3D returns the area of a square torus in 3D.
%
%  Integration region:
%
%    Points (X,Y,Z) such that:
%
%      R1 - R2 <= SQRT ( X**2 + Y**2 ) <= R1 + R2,
%      -R2 <= Z <= R2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R1, R2, the two radii that define the torus.
%
%    Output, real TORUS_SQUARE_AREA_3D, the area of the torus.
%
  value = 16.0E+00 * pi * r1 * r2;

  return
end


function mean = genlogistic_mean ( a, b, c )

%*****************************************************************************80
%
%% GENLOGISTIC_MEAN returns the mean of the Generalized Logistic PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, C, the parameters of the PDF.
%    0.0 < B,
%    0.0 < C.
%
%    Output, real MEAN, the mean of the PDF.
%
  mean = a + b * ( euler_constant ( ) + digamma ( c ) );

  return
end


function [R,subgrad,data] = risk_svm(data,W)
% RISK_SVM evaluates SVM risk term given by L1-hinge loss.
%
% Synopsis:
%  [R,subgrad,data] = risk_svm(data)
%  [R,subgrad,data] = risk_svm(data,W)
%
% Description:
%  Let the risk term be defined as
%
%  R(W) = 1/m sum_{i=1}^m max(0, 1-data.y(i)*(W'*[data.X(:,i);data.X0]))
%
%  This function returns value R and subgradient SUBGRAD of the
%  risk R(W) at W.
%

if nargin < 2
    % evaluates the risk and the subgradient of at W = 0

    nExamples = size(data.X,2);
    R = 1;
    if data.X0 == 0
        subgrad = -data.X*data.y(:)/nExamples;
    else
        subgrad = [-data.X*data.y(:)/nExamples; ...
                   -data.X0*sum(data.y)/nExamples];
    end

else

    nExamples = size(data.X,2);

    if data.X0 == 0
        dfce = 1 - (W'*data.X).*reshape(data.y,1,nExamples);

        idx = find(dfce>0);
        R = sum(dfce(idx))/nExamples;

        subgrad = -data.X(:,idx)*reshape(data.y(idx),length(idx),1)/nExamples;
    else

        dfce = 1 - (W(1:end-1)'*data.X + W(end)*data.X0).*(data.y(:)');
        idx = find(dfce>0);

        R = sum(dfce(idx))/nExamples;
        subgrad = [-data.X(:,idx)*reshape(data.y(idx),length(idx),1)/nExamples; ...
                   -data.X0*sum(data.y(idx))/nExamples];
    end

end

return;
% EOF


% compute abscissas and weight factors for Gaussian-Hermite quadrature
%
% CALL:  [x,w] = gauher(N)
%
%  x = base points (abscissas)
%  w = weight factors
%  N = number of base points (abscissas) (integrates an up to (2N-1)th order
%      polynomial exactly)
%
%  p(x)=exp(-x^2/2)/sqrt(2*pi), a =-Inf, b = Inf
%
%  The Gaussian Quadrature integrates a (2n-1)th order
%  polynomial exactly and the integral is of the form
%           b                         N
%          Int ( p(x)* F(x) ) dx  =  Sum ( w_j* F( x_j ) )
%           a                        j=1
%
%      this procedure uses the coefficients a(j), b(j) of the
%      recurrence relation
%
%           b p (x) = (x - a ) p   (x) - b   p   (x)
%            j j            j   j-1       j-1 j-2
%
%      for the various classical (normalized) orthogonal polynomials,
%      and the zero-th moment
%
%           1 = integral w(x) dx
%
%      of the given polynomial's weight function w(x).  Since the
%      polynomials are orthonormalized, the tridiagonal matrix is
%      guaranteed to be symmetric.

function [x,w]=gauher(N)
    if N==20 % return precalculated values
        x=[ -7.619048541679757;-6.510590157013656;-5.578738805893203;
            -4.734581334046057;-3.943967350657318;-3.18901481655339 ;
            -2.458663611172367;-1.745247320814127;-1.042945348802751;
            -0.346964157081356; 0.346964157081356; 1.042945348802751;
             1.745247320814127; 2.458663611172367; 3.18901481655339 ;
             3.943967350657316; 4.734581334046057; 5.578738805893202;
             6.510590157013653; 7.619048541679757];
        w=[  0.000000000000126; 0.000000000248206; 0.000000061274903;
             0.00000440212109 ; 0.000128826279962; 0.00183010313108 ;
             0.013997837447101; 0.061506372063977; 0.161739333984   ;
             0.260793063449555; 0.260793063449555; 0.161739333984   ;
             0.061506372063977; 0.013997837447101; 0.00183010313108 ;
             0.000128826279962; 0.00000440212109 ; 0.000000061274903;
             0.000000000248206; 0.000000000000126 ];
    else
        b = sqrt( (1:N-1)/2 )';
        [V,D] = eig( diag(b,1) + diag(b,-1) );
        w = V(1,:)'.^2;
        x = sqrt(2)*diag(D);
    end


function cPoly=composePolys(a,b)
%%COMPOSEPOLYS Compose two polynomials given as power series. This means,
%              for polynomials A(x) and B(x) in a scalar x, evaluate the
%              composition C(x)=A(B(x)). C(x) itself is a polynomial. Thus,
%              the output of the function is the set of coefficients of C
%              (subject to finite precision limitations in the recursion).
%
%INPUTS: a Coefficients for a power series of the form
%          y(z)=a(end)+a(end-1)*z+a(end-2)*z^2+...
%          into which the power series in b is to be substituted. The
%          ordering of the coefficients is the same as in Matlab's polyval
%          function.
%        b Coefficients for the power series that is substitued into a.
%
%OUTPUTS: c Coefficients for the power series that represents the
%           substitution of the polynomial b into a.
%
%The substitution is performed by explicitly evaluating power of b (via
%repeated convolutions), multiplying the powers by the appropriate value in
%a and summing the results.
%
%February 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

orderA=length(a)-1;
orderB=length(b)-1;

%The order of the output.
prodOrder=orderA*orderB;

%Zero-pad b so that it is the same length as the length of the output. This
%simplifies assignments in the loop.
b=[zeros(prodOrder-orderB,1);b(:)];

%bProd will hold powers of b. Right now, it is just initialized to 1 (b^0).
bProd=[zeros(prodOrder,1);1];

%Initialize the output with the zeroth-order term.
cPoly=zeros(prodOrder+1,1);
cPoly=cPoly+a(end)*bProd;
for curPow=1:orderA
    %Get the polynomial for the next power of b. The convolution operation
    %is equivalent to polynomial multiplication. The extra leading terms
    %(which are all zeros) are just thrown out.
    bProd=conv(b,bProd);
    bProd=bProd((prodOrder+1):end);

    %Add in the next power term.
    cPoly=cPoly+a(end-curPow)*bProd;
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 result = ball_unit_f1_nd ( func, n )

%*****************************************************************************80
%
%% BALL_UNIT_F1_ND approximates an integral inside a unit ball in ND.
%
%  Integration region:
%
%    Points X(1:N) such that:
%
%      Sum ( X(1:N)**2 ) <= 1.
%
%  Discussion:
%
%    An (N+1)*2**N point 5-th degree formula is used, Stroud number SN:5-6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 November 2004
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Arthur H Stroud,
%    Approximate Calculation of Multiple Integrals,
%    Prentice Hall, 1971.
%
%  Parameters:
%
%    Input, external FUNC, the name of the user supplied
%    function which evaluates F at the N-vector X, of the form
%      function value = func ( n, x )
%
%    Input, integer N, the dimension of the space.
%
%    Output, real RESULT, the approximate integral of the function.
%
  u2 = ( 1.0E+00 - 2.0E+00 * sqrt ( 1.0E+00 / ( n + 4 ) ) ) / ( n + 2 );
  u = sqrt ( u2 );
  x(1:n) = - u;

  w = 1.0E+00 / ( ( n + 1 ) * 2^n );

  quad = 0.0E+00;
  ihi = 2^n;

  for i = 1 : ihi

    itemp = i - 1;

    for j = 1 : n

      if ( mod ( itemp, 2 ) == 1 )
        x(j) = - abs ( x(j) );
      else
        x(j) = abs ( x(j) );
      end

      itemp = floor ( itemp / 2 );

    end

    quad = quad + w * feval ( func, n, x );

  end

  temp = sqrt ( n + 4 );

  t = sqrt ( 2.0E+00 * ( n + 1 ) / ( n + 2 ) ) / ( n * temp );

  y = ( 1.0E+00 + 2.0E+00 / ( n * temp ) ) / ( n + 2 );
  v = sqrt ( y - t );
  u = sqrt ( y + ( n - 1 ) * t );

  khi = 2^n;

  for i = 1 : n

    x(1:n) = - v;

    x(i) = - u;

    for k = 1 : khi

      ktemp = k - 1;

      for j = 1 : n

        if ( mod ( ktemp, 2 ) == 1 )
          x(j) = - abs ( x(j) );
        else
          x(j) = abs ( x(j) );
        end

        ktemp = floor ( ktemp / 2 );

      end

      quad = quad + w * feval ( func, n, x );

    end

    x(i) = - v;

  end

  volume = ball_unit_volume_nd ( n );
  result = quad * volume;

  return
end


function [OUT, W] = CrossWeightAverage(DATA,WEIGHT)
% =======================================================================
% Compute the weighted average of DATA, computing the weights form the
% matrix WEIGHT. Note that if there are NaNs in DATA the weights are
% rescaled. WEIGHTS cannot contain NaN
% =======================================================================
% [average, weight] = CrossWeightAverage(DATA,WEIGHT)
% -----------------------------------------------------------------------
% INPUT
%	- DATA: panel of time series DATA(T,N) of T observation x N series
%       (NaN are accepted and weights rescaled)
%   - WEIGHT: time series of WEIGHTS (TxN). You can also provide a (1xN)
%       matrix in this case the code would automatically compute fixed
%       weights
% -----------------------------------------------------------------------
% OUTPUT
%	- average : weighted average vector (T x 1) [double]
%	- weight  : matrix of weights (T x N) [double]
% -----------------------------------------------------------------------
% EXAMPLE 1: foreign variables as in GVAR (example with fixed weights)
%   x = [1 NaN  3 ;
%         2   3  4 ;
%         3   4  5 ;
%         4   5  6];
%    w = [0  .4 .6];
%    [average, weight] = CrossWeightAverage(x,w)
% -----------------------------------------------------------------------
% EXAMPLE 2: weighted average (with time-varying weights)
%    x = [ 1 NaN   3 ;
%          2   3   4 ;
%          3   4   5 ;
%          4   5   6];
%    w = [.4  .2  .4 ;
%         .3  .4  .3 ;
%         .4  .3  .3 ;
%         .5  .3  .2];
%    [average, weight] = CrossWeightAverage(x,w)
% =======================================================================
% VAR Toolbox 3.0
% Ambrogio Cesa-Bianchi
% ambrogiocesabianchi@gmail.com
% March 2012. Updated November 2020
% -----------------------------------------------------------------------

%% Preliminaries
% Check inputs
[r1, c1] = size(DATA);
[r2, c2] = size(WEIGHT);
if r2==1 && c2==c1
    % Create a matrix of fixed weights
    aux = [];
    for ii=1:r1
        aux = [aux; WEIGHT];
    end
    WEIGHT = aux;
end

% Re-Check inputs
[r1, c1] = size(DATA);
[r2, c2] = size(WEIGHT);
if r1~=r2 || c1~=c2
    disp(' ')
    disp('The matrices of data and weights are not conformable.')
    return
end

%% Cross section weihgted average
[nobs, nvars] = size(DATA);
nans = isnan(DATA);
WEIGHT(nans) = NaN;

OUT(1:nobs,1) = NaN;
W(1:nobs,1:nvars) = NaN;

for ii=1:nobs
    aux_weight = WEIGHT(ii,:)./nansum(WEIGHT(ii,:));
    W(ii,:) = aux_weight;
    aux_weight(nans(ii,:)) = 0;
    DATA(ii,nans(ii,:)) = 0;
    if sum(nans(ii,:))==nvars
        OUT(ii,1) = NaN;
    else
        OUT(ii,1) = DATA(ii,:) * aux_weight';
    end
end


clear all, close all, clc

% Define domain
dx = 0.001;
L = pi;
x = (-1+dx:dx:1)*L;
n = length(x);   nquart = floor(n/4);

% Define hat function
f = 0*x;
f(nquart:2*nquart) = 4*(1:nquart+1)/n;
f(2*nquart+1:3*nquart) = 1-4*(0:nquart-1)/n;
plot(x,f,'-k','LineWidth',1.5), hold on

% Compute Fourier series
CC = jet(20);
A0 = sum(f.*ones(size(x)))*dx;
fFS = A0/2;
for k=1:20
    A(k) = sum(f.*cos(pi*k*x/L))*dx; % Inner product
    B(k) = sum(f.*sin(pi*k*x/L))*dx;
    fFS = fFS + A(k)*cos(k*pi*x/L) + B(k)*sin(k*pi*x/L);
    plot(x,fFS,'-','Color',CC(k,:),'LineWidth',1.2)
end

%% Plot amplitudes
figure
clear ERR
clear A
fFS = A0/2;
A(1) = A0/2;
ERR(1) = norm(f-fFS);
kmax = 100;
for k=1:kmax
    A(k+1) = sum(f.*cos(pi*k*x/L))*dx;
    B(k+1) = sum(f.*sin(pi*k*x/L))*dx;
%     plot(x,B(k)*sin(2*k*pi*x/L),'k-','LineWidth',1.2);
    fFS = fFS + A(k+1)*cos(k*pi*x/L) + B(k+1)*sin(k*pi*x/L);
    ERR(k+1) = norm(f-fFS)/norm(f);
end
thresh = median(ERR)*sqrt(kmax)*4/sqrt(3);
r = max(find(ERR>thresh));
r = 7;
subplot(2,1,1)
semilogy(0:1:kmax,A,'k','LineWidth',1.5)
hold on
semilogy(r,A(r+1),'bo','LineWidth',1.5)
xlim([0 kmax])
ylim([10^(-7) 1])
subplot(2,1,2)
semilogy(0:1:kmax,ERR,'k','LineWidth',1.5)
hold on
semilogy(r,ERR(r+1),'bo','LineWidth',1.5)


function isMonge=isMongeMatrix(A)
%%ISMONGEMATRIX Determine whether a matrix is a Monge matrix. An n1Xn2
%          matrix is a Monge matrix if A(i1,j1)+A(i2,j2)<=A(i1,j2)+A(i2,j1)
%          for all 1<=i1<i2<=n1 and 1<=j1<j2<=n2. Monge matrices have
%          special properties in some discrete optimization problems.
%
%INPUTS: A An n1Xn2 matrix.
%
%OUTPUTS: isMonge This is true if A is a Monge matrix and false otherwise.
%
%EXAMPLE:
% A=[35, 25, 42, 88;
%    84, 63, 75, 96;
%    51,  9,  4, 25;
%    93, 16,  6, 18];
% isMonge=isMongeMatrix(A)
%A is a Monge matrix so isMonge will be 1.
%
%February 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

n1=size(A,1);
n2=size(A,2);

isMonge=true;
for i2=2:n1
    for i1=1:(i2-1)
        for j2=2:n2
            for j1=1:(j2-1)
                if(A(i1,j1)+A(i2,j2)>A(i1,j2)+A(i2,j1))
                   isMonge=false;
                   return;
                end
            end
        end
    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 = bivand2 ( n, alpha, beta )

%*****************************************************************************80
%
%% BIVAND2 returns a bidimensional Vandermonde2 matrix.
%
%  Discussion:
%
%    N = 3, ALPHA = ( 1, 2, 3 ), BETA = ( 10, 20, 30 )
%
%    (x,y)   | (1,10) (2,10) (3,10) (1,20) (2,20) (3,20) (1,30) (2,30) (3,30)
%    --------+---------------------------------------------------------------
%    1       |     1      1      1      1      1      1      1      1      1
%    x       |     1      2      3      1      2      1      1      2      3
%    x^2     |     1      4      9      1      4      1      1      4      9
%       y    |    10     10     10     20     20     20     30     30     30
%    x  y    |    10     20     30     20     40     60     30     60     90
%    x^2y    |    10     40     90     20     80    180     30    120    270
%       y^2  |   100    100    100    400    400    400    900    900    900
%    x  y^2  |   100    200    300    400    800   1200    900   1800   2700
%    x^2y^2  |   100    400    900    400   1600   3600    900   3600   8100
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the data vectors.
%
%    Input, real ALPHA(N), BETA(N), the values that define A.
%
%    Output, real A(N^2,N^2), the matrix.
%
  nn = n * n;
  a = zeros ( nn, nn );

  i = 0
  for iy = 1 : n
    for ix = 1 : n
      i = i + 1;
      j = 0;
      for jy = 1 : n
        for jx = 1 : n
          j = j + 1;
          a(i,j) = alpha(jx) ^ ( ix - 1 ) * beta(jy) ^ ( iy - 1 );
        end
      end
    end
  end

  return
end


function x = u1_to_sphere_unit_2d ( u )

%*****************************************************************************80
%
%% U1_TO_SPHERE_UNIT_2D maps a point in the unit interval onto the unit sphere in 2D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real U, a point in the unit interval.
%
%    Output, real X(2), the corresponding point on the circle.
%
  angle = 2.0 * pi * u(1);

  x(1) = cos ( angle );
  x(2) = sin ( angle );

  return
end


function [J, grad] = costFunction(theta, X, y)
%COSTFUNCTION Compute cost and gradient for logistic regression
%   J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
%   parameter for logistic regression and the gradient of the cost
%   w.r.t. to the parameters.

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

% You need to return the following variables correctly
% J = 0;
% grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Note: grad should have the same dimensions as theta
%

temp1 = -1 * (y .* log(sigmoid(X * theta)));
temp2 = (1 - y) .* log(1 - sigmoid(X * theta));

J = sum(temp1 - temp2) / m;

grad = (X' * (sigmoid(X * theta) - y)) * (1/m);

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

end


function a = r8vec_even ( n, alo, ahi )

%*****************************************************************************80
%
%% R8VEC_EVEN returns N real values, evenly spaced between ALO and AHI.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 January 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of values.
%
%    Input, real ALO, AHI, the low and high values.
%
%    Output, real A(N), N evenly spaced values.
%    Normally, A(1) = ALO and A(N) = AHI.
%    However, if N = 1, then A(1) = 0.5*(ALO+AHI).
%
  if ( n == 1 )

    a(1) = 0.5 * ( alo + ahi );

  else

    a(1:n) = ( (n-1:-1:0) * alo + (0:n-1) * ahi ) / ( n - 1 );

  end

  return
end


function price = Price_Exchange_Option_Margrabe_2D( S0_1, S0_2, T, rho, sigma_1, sigma_2, q_1, q_2)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% About: calcuates Price of 2D Exchange option, (S_1(T) - S_2(T)), using Magrabe Formula Under 2D Diffusion
% Author: Justin Lars Kirkby
%
% -----------------
% Params
% -----------------
% S0_1    = initial asset price of first asset, e.g. S0_1 = 100
% S0_2    = initial asset price of second asset, e.g. S0_2 = 100
% T       = time to maturity in years (e.g. T=1)
% rho     = instantaneous correlation between S_1 and S_2
% sigma_1 = volatility of first asset (annualized), e.g. sigma = 0.2
% sigma_2 = volatility of second asset (annualized), e.g. sigma = 0.2
% q_1     = dividend yield of first asset, e.g. q_1 = 0.02
% q_2     = dividend yield of second asset, e.g. q_2 = 0.02
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

sig = sqrt(sigma_1^2 - 2*rho*sigma_1*sigma_2 + sigma_2^2);
d1 = (log(S0_1/S0_2) + 0.5*sig^2*T)/(sig*sqrt(T));
d2 = d1 - sig*sqrt(T);
price = exp(-q_1*T)*S0_1*normcdf(d1) - exp(-q_2*T)*S0_2*normcdf(d2);

end


function trans = createRotation(varargin)
%CREATEROTATION Create the 3*3 matrix of a rotation.
%
%   TRANS = createRotation(THETA);
%   Returns the rotation corresponding to angle THETA (in radians)
%   The returned matrix has the form :
%   [cos(theta) -sin(theta)  0]
%   [sin(theta)  cos(theta)  0]
%   [0           0           1]
%
%   TRANS = createRotation(POINT, THETA);
%   TRANS = createRotation(X0, Y0, THETA);
%   Also specifies origin of rotation. The result is similar as performing
%   translation(-X0, -Y0), rotation(THETA), and translation(X0, Y0).
%
%   Example
%     % apply a rotation on a polygon
%     poly = [0 0; 30 0;30 10;10 10;10 20;0 20];
%     trans = createRotation([10 20], pi/6);
%     polyT = transformPoint(poly, trans);
%     % display the original and the rotated polygons
%     figure; hold on; axis equal; axis([-10 40 -10 40]);
%     drawPolygon(poly, 'k');
%     drawPolygon(polyT, 'b');
%
%   See also:
%   transforms2d, transformPoint, createRotation90, createTranslation
%

%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 06/04/2004.
%

%   HISTORY
%   22/04/2009: rename as createRotation

% default values
cx = 0;
cy = 0;
theta = 0;

% get input values
if length(varargin)==1
    % only angle
    theta = varargin{1};
elseif length(varargin)==2
    % origin point (as array) and angle
    var = varargin{1};
    cx = var(1);
    cy = var(2);
    theta = varargin{2};
elseif length(varargin)==3
    % origin (x and y) and angle
    cx = varargin{1};
    cy = varargin{2};
    theta = varargin{3};
end

% compute coefs
cot = cos(theta);
sit = sin(theta);
tx =  cy*sit - cx*cot + cx;
ty = -cy*cot - cx*sit + cy;

% create transformation matrix
trans = [cot -sit tx; sit cot ty; 0 0 1];


function [ i, j ] = i4_to_pascal ( k )

%*****************************************************************************80
%
%% I4_TO_PASCAL converts a linear index to Pascal triangle coordinates.
%
%  Discussion:
%
%    We describe the grid points in Pascal's triangle in two ways:
%
%    As a linear index K:
%
%                     1
%                   2   3
%                 4   5   6
%               7   8   9   10
%
%    As elements (I,J) of Pascal's triangle:
%
%                     0,0
%                  1,0   0,1
%               2,0   1,1    0,2
%            3,0   2,1   1,2    0,3
%
%  Example:
%
%     K  I  J
%
%     1  0  0
%     2  1  0
%     3  0  1
%     4  2  0
%     5  1  1
%     6  0  2
%     7  3  0
%     8  2  1
%     9  1  2
%    10  0  3
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 April 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer K, the linear index of the (I,J) element.
%    1 <= K.
%
%    Output, integer I, J, the Pascal indices.
%
  if ( k <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_TO_PASCAL - Fatal error!\n' );
    fprintf ( 1, '  K must be positive.\n' );
    error ( 'I4_TO_PASCAL - Fatal error!' );
  end

  d = i4_to_pascal_degree ( k );

  j = k - ( d * ( d + 1 ) ) / 2 - 1;
  i = d - j;

  return
end


%GENDATL Generation of Lithuanian classes
%
%  A = GENDATL(N,S)
%
% INPUT
%  N  Number of objects per class (optional; default: [50 50])
%  S  Standard deviation for the data generation (optional; default: 1)
%
% OUTPUT
%  A  Dataset
%
% DESCRIPTION
% Generation of Lithuanian classes, a 2-dimensional, 2-class dataset A
% of N objects according to the definition given by Raudys.
% The data is uniformly distributed along two sausages and is superimposed
% by a normal distribution with standard deviation S in all directions.
% Class priors are P(1) = P(2) = 0.5.
%
% SEE ALSO (PRTools Guide)
% DATASETS, PRDATASETS

% Copyright: M. Skurichina, R.P.W. Duin, duin@ph.tn.tudelft.nl
% Faculty of Applied Sciences, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands

% $Id: gendatl.m,v 1.3 2007/06/19 11:44:14 duin Exp $

function a = gendatl(N,s)
		if nargin < 1,
		prwarning(3,'Class cardinalities are not specified, assuming [50 50].');
		N = [50 50];
	end
	if nargin < 2,
		prwarning(4,'Standard deviation for the data generation is not specified, assuming 1.');
		s = 1;
	end
	if (length(N) == 1),
		N(2) = N(1);
	end;

	u1	= 2*pi/3*(rand(N(1),1)-0.5*ones(N(1),1));
	u2	= 2*pi/3*(rand(N(2),1)-0.5*ones(N(2),1));
	a 	= [[10*cos(u1) + s*randn(N(1),1) 10*sin(u1) + s*randn(N(1),1)]; ...
				[6.2*cos(u2) + s*randn(N(2),1) 6.2*sin(u2) + s*randn(N(2),1)]];
	lab = genlab(N);
	a 	= prdataset(a,lab,'name','Lithuanian Classes');
	a   = setlablist(a,[1 2]');
	a   = setprior(a,[0.5 0.5]);
return;


function An = slnormalize(A, p, d)
%SLNORMALIZE Normalize the sub-arrays
%
% $ Syntax $
%   - An = slnormalize(A)
%   - An = slnormalize(A, p)
%   - An = slnormalize(A, [], d)
%   - An = slnormalize(A, p, d)
%
% $ Arguments $
%   - A:        the input array
%   - p:        the order of the norm (default = 2)
%   - d:        the dimension of subarrays (default = 1, column vectors)
%   - An:       the normalized array
%
% $ Description $
%   - An = slnormalize(A) normalizes the column vectors of A by 2nd-order.
%
%   - An = slnormalize(A, p) normalizes the column vectors of a by
%     pth-order.
%
%   - An = slnormalize(A, [], d) normalizes the subarrays of A along
%     dimensions specified by d by 2nd-order.
%
%   - An = slnormalize(A, p, d) normalizes the subarrays of A along
%     dimensions specified by d by pth-order.
%
% $ Remarks $
%   # Normalize an array by pth order means dividing the elements of
%     the array by its p-th norm.
%   # p can be inf or -inf. If p = inf, then the Lp norm is simply the
%     maximum magnitude value; while if p = -inf, then the Lp norm is the
%     minimum magnitude value.
%
% $ History $
%   - Created by Dahua Lin on Nov 19th, 2005
%   - Modified by Dahua Lin on Sep 10th, 2006
%       - replace slmul by slmulvec to increase efficiency
%

%% parse and verify input arguments
if nargin < 2 || isempty(p)
    p = 2;
end
if nargin < 3 || isempty(d)
    d = 1;
end
if ~isscalar(p)
    error('sltoolbox:notscalar', 'p should be a scalar');
end
if p == 0
    error('sltoolbox:zeroerr', 'p should not be zero');
end

%% compute
nrms = slnorm(A, p, d);
nrms = slenforce(nrms, 'positive');
An = slmulvec(A, 1 ./ nrms);


function [ mO ] = ImageConvFrequencyDomain( mI, mH, convShape )
% ----------------------------------------------------------------------------------------------- %
% [ mO ] = ImageConvFrequencyDomain( mI, mH, convShape )
% Applies Image Convolution in the Frequency Domain.
% Input:
%   - mI                -   Input Image.
%                           Structure: Matrix (numRows x numCols).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - mH                -   Filtering Kernel.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - convShape         -   Convolution Shape.
%                           Sets the convolution shape.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: {1, 2, 3}.
% Output:
%   - mI                -   Output Image.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
% References:
%   1.  MATLAB's 'conv2()' - https://www.mathworks.com/help/matlab/ref/conv2.html.
% Remarks:
%   1.  For the transformation the (0, 0) of the image and the kernel is
%       the top left corner of teh matrix (i = 1, j = 1). Hence it can be
%       thought that a shifting is needed (To center the kernel).
%   1.  The function supports single channel image only.
% TODO:
%   1.
%   Release Notes:
%   -   1.0.000     29/04/2021  Royi Avital     RoyiAvital@yahoo.com
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

CONV_SHAPE_FULL     = 1;
CONV_SHAPE_SAME     = 2;
CONV_SHAPE_VALID    = 3;

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

numRowsKernel = size(mH, 1);
numColsKernel = size(mH, 2);

switch(convShape)
    case(CONV_SHAPE_FULL)
        numRowsFft  = numRows + numRowsKernel - 1;
        numColsFft  = numCols + numColsKernel - 1;
        firstRowIdx = 1;
        firstColIdx = 1;
        lastRowIdx  = numRowsFft;
        lastColdIdx = numColsFft;
    case(CONV_SHAPE_SAME)
        numRowsFft  = numRows + numRowsKernel;
        numColsFft  = numCols + numColsKernel;
        firstRowIdx = ceil((numRowsKernel + 1) / 2);
        firstColIdx = ceil((numColsKernel + 1) / 2);
        lastRowIdx  = firstRowIdx + numRows - 1;
        lastColdIdx = firstColIdx + numCols - 1;
    case(CONV_SHAPE_VALID)
        numRowsFft = numRows;
        numColsFft = numCols;
        firstRowIdx = numRowsKernel;
        firstColIdx = numColsKernel;
        lastRowIdx  = numRowsFft;
        lastColdIdx = numColsFft;
end

mO = ifft2(fft2(mI, numRowsFft, numColsFft) .* fft2(mH, numRowsFft, numColsFft), 'symmetric');
mO = mO(firstRowIdx:lastRowIdx, firstColIdx:lastColdIdx);

end


%
% Written by M. Harper Langston - 5/10/00
% harper@cims.nyu.edu
%
% Using Lemma 10.5, form the orthogonal matrix, Q, the block matrix of
% matrices of eigenvectors of a TST block matrix. Then use this to form Gamma
% See Iselres page 246 or Lemma 10.5 for more info for Q.
% Gamma will be transformed into a plain tridiagonal matrix, using the method
% in Iserles, page 247 and 249.
function [Gam] = Form_Gamma(m,N)
for j = 1:m
   for k = 1:m
      Q(j,k) = sqrt(2/(m+1))*sin(pi*j*k/(m+1));
   end
end
% Now, form Gamma.  As per Iserles, page 247, we can rearrange columns into
% rows of the vectors, so Gamma will be tridiagonal.  The only difference is
% that in the problem, Gamma*t = c, solving for t, c must be converted and
% then t will have to be converted back.  See Iselres, pages 247 and 249
% for more informtion.
if N==9 | N==10
	S = (diag((-10/3)*ones(m,1)) + diag((2/3)*ones(m-1,1),1) + diag((2/3)*ones(m-1,1),-1));
   T = (diag((2/3)*ones(m,1)) + diag((1/6)*ones(m-1,1),1) + diag((1/6)*ones(m-1,1),-1));
elseif N==5
   S = (diag((-4)*ones(m,1)) + diag((1)*ones(m-1,1),1) + diag((1)*ones(m-1,1),-1));
   T = diag((1)*ones(m,1));
elseif N==101 % N = 101 is called by Modified_Right.m only, to  speed up
              % the modified 9=point scheme
   S = (diag((2/3)*ones(m,1)) + diag((1/12)*ones(m-1,1),1) + diag((1/12)*ones(m-1,1),-1));
   T = (diag((1/12)*ones(m,1)));
else
   error('Must either use 5 or 9-point scheme (N=5 or N=9 in poisson.m)');
end
% inv(Q) = Q, so don't need to invert Q to diagonalize S and T
GS = diag(Q*S*Q);
GT = diag(Q*T*Q);
Gam = sparse(zeros(size(Q)));
for j = 1:m
   temp = (j-1)*m +1;
   Gam(temp:j*m,temp:j*m) = diag(GS(j)*ones(m,1)) ...
	        + diag((GT(j))*ones(m-1,1),1) + diag((GT(j))*ones(m-1,1),-1);
end
Gam = sparse(Gam);
%
% Written by M. Harper Langston - 5/10/00
% harper@cims.nyu.edu
%


function chebyshev_polynomial_test01 ( )

%*****************************************************************************80
%
%% CHEBYSHEV_POLYNOMIAL_TEST01 tests T_PROJECT_COEFFICIENTS_DATA.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 April 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CHEBYSHEV_POLYNOMIAL_TEST01:\n' );
  fprintf ( 1, '  T_PROJECT_COEFFICIENTS_DATA estimates the Chebyshev polynomial\n' );
  fprintf ( 1, '  coefficients for a function given as data (x,fx).\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here, we use fx = f(x) = x^2 for the data.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Since T(0,x) = 1 and T(2,x) = 2*x^2 - 1, the correct expansion is\n' );
  fprintf ( 1, '  f(x) = 1/2 T(0,x) + 0 T(1,x) + 1/2 T(2,x) + 0 * all other polys.\n' );
%
%  Data in [0,1];
%
  a = 0.0;
  b = 1.0;
  m = 20;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_01 ( m, seed );
  d = x.^2;

  r8vec2_print ( m, x, d, '  Data ( X, D ):' );

  n = 4;
  c = t_project_coefficients_data ( a, b, m, n, x, d );

  r8vec_print ( n, c, '  Coefficients of Chebyshev expansion of degree 4.' );
%
%  Compare Chebyshev expansion and original function.
%
  d2 = t_project_value ( m, n, x, c );

  fprintf ( 1, '\n' );
  fprintf ( 1, '   I      X(I)     Data(I)      Chebyshev(X(I))\n' );
  fprintf ( 1, '\n' );
  for i = 1 : m
    fprintf ( 1, '  %2d  %12g  %12g  %12g\n', i, x(i), d(i), d2(i) );
  end

  return
end


function f = local ( m, x )

%*****************************************************************************80
%
%% LOCAL computes the local function.
%
%  Discussion:
%
%    This function has a local minimizer:
%
%      X* = ( 0.2858054412..., 0.2793263206...), F(X*) = 5.9225...
%
%    and a global minimizer:
%
%      X* = ( -21.02667179..., -36.75997872...), F(X*) = 0.
%
%    Suggested starting point for local minimizer:
%
%      X = ( 1, 1 ), F(X) = 3.33 * 10^6.
%
%    Suggested starting point for global minimizer:
%
%      X = ( -15, -35), F(X) = 1.49 * 10^8.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    David Himmelblau,
%    Applied Nonlinear Programming,
%    McGraw Hill, 1972,
%    ISBN13: 978-0070289215,
%    LC: T57.8.H55.
%
%  Parameters:
%
%    Input, integer M, the number of variables.
%
%    Input, real X(M), the argument of the function.
%
%    Output, real F, the value of the function at X.
%
  f = ( x(1)^2 + 12.0 * x(2) - 1.0 )^2 ...
    + ( 49.0 * x(1)^2 + 49.0 * x(2)^2 + 84.0 * x(1) + 2324.0 * x(2) - 681.0 )^2;

  return
end


function [J, grad] = lrCostFunction(theta, X, y, lambda)
%LRCOSTFUNCTION Compute cost and gradient for logistic regression with %regularization
%   J = LRCOSTFUNCTION(theta, X, y, lambda) computes the cost of using
%   theta as the parameter for regularized logistic regression and the
%   gradient of the cost w.r.t. to the parameters.

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

% You need to return the following variables correctly
J = 0;
grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Hint: The computation of the cost function and gradients can be
%       efficiently vectorized. For example, consider the computation
%
%           sigmoid(X * theta)
%
%       Each row of the resulting matrix will contain the value of the
%       prediction for that example. You can make use of this to vectorize
%       the cost function and gradient computations.
%
% Hint: When computing the gradient of the regularized cost function,
%       there're many possible vectorized solutions, but one solution
%       looks like:
%           grad = (unregularized gradient for logistic regression)
%           temp = theta;
%           temp(1) = 0;   % because we don't add anything for j = 0
%           grad = grad + YOUR_CODE_HERE (using the temp variable)
%

% Cost function
h = sigmoid(X * theta);
theta1 = [0; theta(2:size(theta)) ];

cost = (1 / m) * sum( (-y .* log(h)) - ((1 - y) .* log(1 - h)) );
reg_cost = (lambda / (2 * m)) .* (theta1' * theta);

J = cost + reg_cost;

grad = (1 / m) * X' * (h - y);
reg_grad = (lambda / m) .* theta1;

grad = grad + reg_grad;

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

grad = grad(:);

end


function [ X,i ] = gmm_sample(nbSamples,Priors,Mu,Sigma )
%GMM_SAMPLE Samples points from a Gaussian Mixture Model
%
%   input -----------------------------------------------------------------
%
%       o nbSamples : (1 x 1), number of samples to return
%
%       o Priors    : (1 x K), gmm weights
%
%       o Mu        : (D x K), gmm means
%
%       o Sigma     : (D x D x K), gmm covariance
%
%   output ----------------------------------------------------------------
%
%       o X         : (D x N), N samples of dimension D
%
%       o i         : (N x 1), index of Gaussian center from which the data
%                              points were sampled form.

D = size(Mu,1);
X = zeros(D,nbSamples);

i = discretesample(Priors', nbSamples);

if D == 1

    for v=1:nbSamples

        X(v) = normrnd(Mu(i(v)), sqrt(Sigma(i(v))) );

    end
else

    for v = 1:nbSamples
        j = i(v);
        X(:,v) = mvnrnd(Mu(:,j),Sigma(:,:,j));
    end

end

end


function pSum=polySum(p1,p2)
%%POLYSUM Add together two vectors representing 1D polynomials as power
%         series. The format of the polynomial vectors is the same as that
%         used in Matlab's polyval function: The coefficients are ordered
%         y(z)=p(end)+p(end-1)*z+p(end-2)*z^2+...
%
%INPUTS: p1,p2 Coefficients for the two power series. The number of terms
%              in the different series can be different. Thus p1 and p2 do
%              not have the same length. p1(1) is the coefficient of the
%              highest order term. p(end) is the additive constant term. p1
%              and p2 can be row or column vectors.
%
%OUTPUTS: pSum A column vector holding the sum of p1 and p2. The first
%              element corresponds to the highest term, as used in Matlab's
%              polyval function. Note that the vector is not shortened when
%              the sum of high order terms equals zero (terms cancel).
%
%Polynomials are summed by adding corresponding terms.
%
%As an example, consider adding
%x^2-3*x+2
%to
%x^5+3*x^3-4*x^2+1
%This is done as
% p1=[1;-3;2];
% p2=[1;0;3;-4;0;1];
% pSum=polySum(p1,p2)
%One will see that the result is pSum'=[1,0,3,-3,-3,3], which corresponds
%to x^5+3*x^3-3*x^2-3*x+3.
%
%August 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

pSum=[zeros(length(p1)-length(p2),1);p2(:)]+[zeros(length(p2)-length(p1),1);p1(:)];

end

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


function y = sumlogs(x,dim)
%SUMLOGS Sum of elements where numbers are represented by their logarithms.
%
%  Description
%    C=SUMLOGS(A) computes C=log(sum(exp(A))) in such a fashion
%    that it works even when elements have large magnitude.
%
%    C=SUMLOGS(A,DIM) sums along the dimension DIM.
%
%    See also SUM
%
% Copyright (c) 2013 Aki Vehtari

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

if nargin<2
  dim=find(size(x)>1,1);
end
maxx=max(x(:));
y=maxx+log(sum(exp(x-maxx),dim));


function call_price=bs_european_call(S, K, r, sigma, time)

%--------------------------------------------------------------------------
%
% DESCRIPTION:
%
% European put option using Black-Scholes' formula
%
%
% Reference:
%
% John Hull, "Options, Futures and other Derivative Securities",
% Prentice-Hall, second edition, 1993.
%
%--------------------------------------------------------------------------
%
% INPUTS:
%
%   S:      spot price
%   K:      strike price
%   r:      interest rate
%   sigma:  volatility
%   time:   time to maturity
%
%--------------------------------------------------------------------------
%
% OUTPUT:
%
% call_price: price of a call option
%
%--------------------------------------------------------------------------
%
% Author:  Paolo Z., February 2012
%
%--------------------------------------------------------------------------

time_sqrt = sqrt(time);

d1 = (log(S/K)+r*time)/(sigma*time_sqrt)+0.5*sigma*time_sqrt;
d2 = d1-(sigma*time_sqrt);

call_price  = S*normcdf(d1)-K*exp(-r*time)*normcdf(d2);


function P = xyz2polar(X)
% XYZ2POLAR Transformation of cartesian coordinates to polar coordinates.
% ------------------------------------------------------------------------------
% DESCRIPTION/NOTES
% Transformation of cartesian coordinates [x, y, z] to polar coordinates
% [distance, horizontal angle, vertical angle].
% ------------------------------------------------------------------------------
% INPUT
% X
%   Matrix of cartesian coordinates x, y and z. Each point in a row.
% ------------------------------------------------------------------------------
% OUTPUT
% P
%   Matrix of polar coordinates distace, horizontal angle and vertical angle.
%   Each point in a row.
%   Horizontal angle is defined mathematically positive starting from x-axis.
%   Vertical   angle is defined as angle between point and zenith.
% ------------------------------------------------------------------------------
% EXAMPLES
% Transformation of randomly generated points into polar coordinates and back.
%   X1   = [rand(10,1)*10 rand(10,1)*5 rand(10,1)];
%   P    = xyz2polar(X1);
%   X2   = polar2xyz(P);
%   Diff = X1-X2;
% ------------------------------------------------------------------------------
% philipp.glira@gmail.com
% ------------------------------------------------------------------------------

% Input parsing ----------------------------------------------------------------

p = inputParser;
p.addRequired('X', @(x) isreal(x) && size(x,2) == 3);
p.parse(X);
p = p.Results;
% Clear required inputs to avoid confusion
clear X

% Distance ---------------------------------------------------------------------

d = sqrt(p.X(:,1).^2 + p.X(:,2).^2 + p.X(:,3).^2);

% Vertical angle ---------------------------------------------------------------

va = acosg(p.X(:,3) ./ d); % always positive [0,200]

% Horizontal angle -------------------------------------------------------------

% Compute all 4 solutions for the horizontal angle
hSol(:,1) = acosg( p.X(:,1) ./ (d.*sing(va)) ); % sol1: always positive [   0,200]
hSol(:,2) = 400 - hSol(:,1);                    % sol2: always positive [ 200,400]
hSol(:,3) = asing( p.X(:,2) ./ (d.*sing(va)) ); % sol3: can be negative [-100,100]
hSol(:,4) = 200 - hSol(:,3);                    % sol4: always positive [ 100,300]

% Eliminate complex part (occure if argument of acosg/asing is not in range
% [-1, 1]); should be the case just for few points
hSol = real(hSol);

% If some values of sol3 are negativ, transform them into positive range
idxNeg = hSol(:,3) < 0;
hSol(idxNeg,3) = hSol(idxNeg,3) + 400; % now positive

% Compute the differences between the solutions
% Pairs for comparisons: 1,3 1,4 2,3 2,4
diff = [hSol(:,1)-hSol(:,3), hSol(:,1)-hSol(:,4), hSol(:,2)-hSol(:,3), hSol(:,2)-hSol(:,4)];
% Find for each point the pair with the lowest difference
[~, idx] = min(abs(diff), [], 2);

% If pair 1 (1,3) take column 1 of hSol (i.e. sol1)
% If pair 2 (1,4) take column 1 of hSol (i.e. sol1)
% If pair 3 (2,3) take column 2 of hSol (i.e. sol2)
% If pair 4 (2,4) take column 2 of hSol (i.e. sol2)
idx(idx == 2) = 1;
idx(idx == 3) = 2;
idx(idx == 4) = 2;

% Convert subscripts to linear indices to access the elements
idxLin = sub2ind(size(hSol), [1:size(hSol,1)]', idx);

% Get values
ha = hSol(idxLin);

% Output -----------------------------------------------------------------------

P = [d ha va];

end


function p = norm_density(x, mu, sigma)
% Compute density of normal distribution function
%
% file:      	norm_density.m, (c) Matthew Roughan, Tue Jul 21 2009
% directory:   /home/mroughan/src/matlab/NUMERICAL_ROUTINES/
% created: 	Tue Jul 21 2009
% author:  	Matthew Roughan
% email:   	matthew.roughan@adelaide.edu.au
%
% Calculate normal density in 1D.
%
% INPUTS:
%   x      = a vector of points at which to calculate the normal CDF
%   mu     = mean of the normal
%   sigma  = std dev. of the normal
%
%
p = exp( -(x-mu).^2 / (2*sigma^2) ) / (sigma * sqrt(2*pi) );


function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
                                  num_features, lambda)
%COFICOSTFUNC Collaborative filtering cost function
%   [J, grad] = COFICOSTFUNC(params, Y, R, num_users, num_movies, ...
%   num_features, lambda) returns the cost and gradient for the
%   collaborative filtering problem.
%

% Unfold the U and W matrices from params
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(params(num_movies*num_features+1:end), ...
                num_users, num_features);

% You need to return the following values correctly
J = 0;
X_grad = zeros(size(X));
Theta_grad = zeros(size(Theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost function and gradient for collaborative
%               filtering. Concretely, you should first implement the cost
%               function (without regularization) and make sure it is
%               matches our costs. After that, you should implement the
%               gradient and use the checkCostFunction routine to check
%               that the gradient is correct. Finally, you should implement
%               regularization.
%
% Notes: X - num_movies  x num_features matrix of movie features
%        Theta - num_users  x num_features matrix of user features
%        Y - num_movies x num_users matrix of user ratings of movies
%        R - num_movies x num_users matrix, where R(i, j) = 1 if the
%            i-th movie was rated by the j-th user
%
% You should set the following variables correctly:
%
%        X_grad - num_movies x num_features matrix, containing the
%                 partial derivatives w.r.t. to each element of X
%        Theta_grad - num_users x num_features matrix, containing the
%                     partial derivatives w.r.t. to each element of Theta
%

% X.shape=[nm, n]; Theta.shape=[nu, n]
% Y.shape=[nm, nu];
J = 1.0 / 2 * sum(sum(R.*(X*Theta'-Y).^2));
J = J + lambda/2*sum(sum(Theta.^2)) + lambda/2*sum(sum(X.^2));

% X_grad.shape=[nm, n]; Theta.grad.shape=[nu, n]
X_grad = R.*(X*Theta'-Y)*Theta;
X_grad = X_grad + lambda*X;
Theta_grad = (R.*(X*Theta'-Y))'*X;
Theta_grad = Theta_grad + lambda*Theta;

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

grad = [X_grad(:); Theta_grad(:)];

end


function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
%GRADIENTDESCENTMULTI Performs gradient descent to learn theta
%   theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by
%   taking num_iters gradient steps with learning rate alpha

% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    % ====================== YOUR CODE HERE ======================
    % Instructions: Perform a single gradient step on the parameter vector
    %               theta.
    %
    % Hint: While debugging, it can be useful to print out the values
    %       of the cost function (computeCostMulti) and gradient here.
    %

    S = (1 / m) * (X' * (X * theta - y));
    theta = theta - alpha .* S;

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

    % Save the cost J in every iteration
    J_history(iter) = computeCostMulti(X, y, theta);

end

end


function cdf = empirical_discrete_cdf ( x, a, b, c )

%*****************************************************************************80
%
%% EMPIRICAL_DISCRETE_CDF evaluates the Empirical Discrete CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the CDF.
%
%    Input, integer A, the number of values.
%    0 < A.
%
%    Input, real B(A), the weights of each value.
%    0 <= B(1:A) and at least one value is nonzero.
%
%    Input, real C(A), the values.
%    The values must be distinct and in ascending order.
%
%    Output, real CDF, the value of the CDF.
%
  cdf = 0.0;

  bsum = sum ( b(1:a) );

  for i = 1 : a

    if ( x < c(i) )
      return
    end

    cdf = cdf + b(i) / bsum;

  end

  return
end


function h = orientedGaussianKernel(size, sigma, theta)
%ORIENTEDGAUSSIANKERNEL Oriented Gaussian kernel for directional filtering
%
%   H = orientedGaussianKernel(SIZE, SIGMA, THETA)
%   THETA is in degrees.
%
%   Example
%     orientedGaussianKernel
%
%   See also
%     imDirectionalFilter, orientedLaplacianKernel, imfilter

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

% ensure size is a vector
if length(size) == 1
    size = [size size];
end

% ensure sigma is a vector
if length(sigma) == 1
    sigma = [sigma sigma];
end

% compute reference for each axis
nx = round((size(1) - 1) / 2);
ny = round((size(2) - 1) / 2);

% create 3D grid
[x, y] = meshgrid(-nx:nx, -ny:ny);

% precompute angles
cot = cosd(-theta);
sit = sind(-theta);

% Apply rotation by -theta
x2 = x * cot - y * sit;
y2 = x * sit + y * cot;

% compute gaussian function for each point of the grid
sx2 = 2 * sigma(1) ^ 2;
sy2 = 2 * sigma(2) ^ 2;
h = exp(-(x2.^2 / sx2)) .* exp(-(y2.^2 / sy2));

% normalize intensities
h = h / (sum(h(:)));


function [ v_weight, predecessor ] = bellman_ford ( v_num, e_num, source, ...
  e, e_weight )

%*****************************************************************************80
%
%  Purpose:
%
%    BELLMAN_FORD finds shortest paths from a given vertex of a weighted directed graph.
%
%  Discussion:
%
%    The Bellman-Ford algorithm is used.
%
%    Each edge of the graph has a weight, which may be negative.  However,
%    it should not be the case that there is any negative loop, that is,
%    a circuit whose total weight is negative.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 November 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer V_NUM, the number of vertices.
%
%    Input, integer E_NUM, the number of edges.
%
%    Input, integer SOURCE, the vertex from which distances will
%    be calculated.
%
%    Input, integer E(2,E_NUM), the edges, given as pairs of
%    vertex indices.
%
%    Input, real E_WEIGHT(E_NUM), the weight of each edge.
%
%    Output, real V_WEIGHT(V_NUM), the weight of each node,
%    that is, its minimum distance from SOURCE.
%
%    Output, integer PREDECESSOR(V_NUM), a list of predecessors,
%    which can be used to recover the shortest path from any node back to SOURCE.
%
  r8_big = 1.0E+30;
%
%  Step 1: initialize the graph.
%
  v_weight(1:v_num) = r8_big;
  v_weight(source) = 0.0;

  predecessor(1:v_num) = -1;
%
%  Step 2: Relax edges repeatedly.
%
  for i = 1 : v_num - 1
    for j = 1 : e_num
      u = e(2,j);
      v = e(1,j);
      t = v_weight(u) + e_weight(j);
      if ( t < v_weight(v) )
        v_weight(v) = t;
        predecessor(v) = u;
      end
    end
  end
%
%  Step 3: check for negative-weight cycles
%
  for j = 1 : e_num
    u = e(2,j);
    v = e(1,j);
    if ( v_weight(u) + e_weight(j) < v_weight(v) )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'BELLMAN_FORD - Fatal error!\n' );
      fprintf ( 1, '  Graph contains a cycle with negative weight.\n' );
      error ( 'BELLMAN_FORD - Fatal error!' );
    end
  end

  return
end


function [ mO ] = CompressImageSvd( mI, energyThr, blockRadius )
% ----------------------------------------------------------------------------------------------- %
% [ mO ] = CompressImageSvd( mI, energyThr, blockRadius )
%   Compresses the image using SVD.
% Input:
%   - mI            -   Input Image.
%                       Structure: Image Matrix (Signle Channel or RGB).
%                       Type: 'Single' / 'Double'.
%                       Range: [0, 1].
%   - energyThr     -   Energy Threshold.
%                       Sets the threshold for Singular Value kept energy.
%                       Structure: Scalar.
%                       Type: 'Single' / 'Double'.
%                       Range: [0, 1].
%   - blockRadius   -   Block Radius.
%                       Sets the block radius for the compression.
%                       Structure: Scalar.
%                       Type: 'Single' / 'Double'.
%                       Range: {1, 2, ...}.
% Output:
%   - mO            -   Output Image.
%                       Structure: Image Matrix (Signle Channel or RGB).
%                       Type: 'Single' / 'Double'.
%                       Range: [0, 1].
% References
%   1.  SVD Wikipedia - https://en.wikipedia.org/wiki/Singular_value_decomposition.
% Remarks:
%   1.  a
% TODO:
%   1.  U.
% Release Notes:
%   -   1.0.000     01/09/2017  Royi
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

FALSE   = 0;
TRUE    = 1;

OFF     = 0;
ON      = 1;

numRows = size(mI, 1);
numCols = size(mI, 2);
numChan = size(mI, 3); %<! Num Channels

vImageDim = [numRows, numCols];

blockLength = (2 * blockRadius) + 1;
vBlockDim   = [blockLength, blockLength];

mO = zeros([numRows, numCols, numChan]);

for ii = 1:numChan

    mII     = mI(:, :, ii);
    dcLevel = mean(mII(:)); %<! Extracting DC Level
    mII     = mII - dcLevel;

    % Decomposing the image into blocks. Each block becomes a vector in the
    % Columns Images.
    mColImage   = im2col(mII, vBlockDim, 'distinct');

    % The SVD Step
    [mU, mS, mV] = svd(mColImage);

    vSingularValues = diag(mS);

    vSingularValueEnergy = cumsum(vSingularValues) / sum(vSingularValues);
    lastIdx = find(vSingularValueEnergy >= energyThr, 1, 'first');

    vSingularValues(lastIdx + 1:end) = 0;
    % mS isn't necessarily square matrix. Hence only work on its main
    % diagonal.
    mS(1:length(vSingularValues), 1:length(vSingularValues)) = diag(vSingularValues);

    % Reconstruction of the image using "Less Energy".
    mColImage = mU * mS * mV.';

    % Restorig the original structure and the DC Level
    mO(:, :, ii) = col2im(mColImage, vBlockDim, vImageDim, 'distinct') + dcLevel;

end

end


% this m-file calculates the real roots of the given polynomial using
% newton raphson technique.this m-file calls the functions in the two m-files named as syn_division and
% derivate.
% coeff_function is the 1xn matrix conatining the coeff of the polynomial.
% Keerthi Venkateswara Rao
function [final_roots,functionvalue] = newton(coeff_function,initial_guess,error_tolerance,max_iterations)
iterations=0;
max_no_roots=size(coeff_function,2);
final_roots=0;
functionvalue=0;
for no_roots=1:max_no_roots-1
    fun_root_new=initial_guess;
    flag=1;
    coeff_der_function=derivate(coeff_function);
    order_fun=size(coeff_function,2);
    order_der_fun=size(coeff_der_function,2);
    while flag==1
        fun_root_old=fun_root_new;
        fx=0;
        dfx=0;
        nonzero=1;
        while nonzero==1
            powers=order_fun-1;
            for index=1:order_fun
                fx=fx+coeff_function(index)*fun_root_old^powers;
                powers=powers-1;
            end
            powers=order_der_fun-1;
            for index=1:order_der_fun
                dfx=dfx+coeff_der_function(index)*fun_root_old^powers;
                powers=powers-1;
            end
            if dfx==0
                fun_root_old=fun_root_old+1;
            else
                nonzero=0;
            end
        end
        iterations = iterations + 1;
        fun_root_new = fun_root_old - fx/dfx;
        if iterations >= max_iterations
            flag=0;
        elseif  abs(fun_root_new-fun_root_old)<=error_tolerance
            flag=0;
            final_roots(no_roots)=fun_root_new;
            functionvalue(no_roots)=fx;
        end
    end
    coeff_function=syn_division(coeff_function,fun_root_new);
 end


function variance = bradford_variance ( a, b, c )

%*****************************************************************************80
%
%% BRADFORD_VARIANCE returns the variance of the Bradford PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, C, the parameters of the PDF.
%    A < B,
%    0.0 < C.
%
%    Output, real VARIANCE, the variance of the PDF.
%
  variance = ( b - a )^2 * ...
    ( c * ( log ( c + 1.0 ) - 2.0 ) + 2.0 * log ( c + 1.0 ) ) ...
    / ( 2.0 * c * ( log ( c + 1.0 ) )^2 );

  return
end


function p = triangle_circumcenter ( n, t )

%*****************************************************************************80
%
%% TRIANGLE_CIRCUMCENTER computes the circumcenter of a triangle in ND.
%
%  Discussion:
%
%    Three ND points A, B and C lie on a circle.
%
%    The circumcenter P has the formula
%
%      P = ( Area ( PBC ) * A + Area ( APC) * B + Area ( ABP ) * C )
%        / ( Area ( PBC )     + Area ( APC )    + Area ( ABP ) )
%
%    The details of the formula rely on information supplied
%    by Oscar Lanzi III.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 October 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the spatial dimension.
%
%    Input, real T(N,3), the triangle vertices.
%
%    Output, real P(N,1), the circumcenter of the triangle.
%
  a = r8vec_normsq_affine ( n, t(1:n,2), t(1:n,3) );
  b = r8vec_normsq_affine ( n, t(1:n,3), t(1:n,1) );
  c = r8vec_normsq_affine ( n, t(1:n,1), t(1:n,2) );

  pbc = a * ( - a + b + c );
  apc = b * (   a - b + c );
  abp = c * (   a + b - c );

  p = zeros ( n, 1 );

  p(1:n,1) = ( pbc * t(1:n,1) + apc * t(1:n,2) + abp * t(1:n,3) ) ...
           / ( pbc            + apc            + abp );

  return
end


function [logval val]=mndensity(x,mu,sigma,k)

% function [logval val]=mndensity(x,mu,sigma,k)
% computes the density of the multivariate normal distribution
% uses the log of the density (a.2.1), split into several parts for computation ease
% inputs:  - vector 'x': the argument of the density function
%          - vector 'mu': the mean of the distribution
%          - matrix 'sigma': the covariance of the distribution
%          - integer 'k': the dimension of the argument vector
% outputs: - scalar 'logval': the log of the density value
%          - scalar 'val': the density value

temp(1,1)=-(k/2)*log(2*pi);
temp(2,1)=-0.5*log(det(sigma));
temp(3,1)=-0.5*(x-mu)'*(sigma\(x-mu));

% temp(3,1)=-0.5*(x-mu)'*inv(sigma)*(x-mu);

logval=sum(temp);
val=exp(logval);


function n2 = dist2(x, c)
%DIST2	Calculates squared distance between two sets of points.
%
%	Description
%	D = DIST2(X, C) takes two matrices of vectors and calculates the
%	squared Euclidean distance between them.  Both matrices must be of
%	the same column dimension.  If X has M rows and N columns, and C has
%	L rows and N columns, then the result has M rows and L columns.  The
%	I, Jth entry is the  squared distance from the Ith row of X to the
%	Jth row of C.
%   D(i,j) = norm(X(i,:)-C(j,:)).^2;
%
%	See also
%	GMMACTIV, KMEANS, RBFFWD
%

%	Copyright (c) Christopher M Bishop, Ian T Nabney (1996, 1997)

%	Dec 6, 2011: Modified by Da Kuang, with performance improvement.

[ndata, dimx] = size(x);
[ncentres, dimc] = size(c);
if dimx ~= dimc
	error('Data dimension does not match dimension of centres')
end

tempx = full(sum(x.^2, 2));
tempc = full(sum(c.^2, 2)');

n2 = tempx(:, ones(1,ncentres)) + ...
  		tempc(ones(1,ndata), :) - ...
  		2.*(x*(c'));


function wval = lagrange_factor ( npol, xpol, nval, xval )

%*****************************************************************************80
%
%% LAGRANGE_FACTOR evaluates the polynomial Lagrange factor at a point.
%
%  Formula:
%
%    W(X) = Product ( 1 <= I <= NPOL ) ( X - XPOL(I) )
%
%  Discussion:
%
%    Suppose F(X) is at least N times continuously differentiable in the
%    interval [A,B].  Pick NPOL distinct points XPOL(I) in [A,B] and compute
%    the interpolating polynomial P(X) of order NPOL ( and degree NPOL-1)
%    which passes through all the points ( XPOL(I), F(XPOL(I)) ).
%    Then in the interval [A,B], the maximum error
%
%      abs ( F(X) - P(X) )
%
%    is bounded by:
%
%      C * FNMAX * W(X)
%
%    where
%
%      C is a constant,
%      FNMAX is the maximum value of the NPOL-th derivative of F in [A,B],
%      W(X) is the Lagrange factor.
%
%    Thus, the value of W(X) is useful as part of an estimated bound
%    for the interpolation error.
%
%    Note that the Chebyshev abscissas have the property that they minimize
%    the value of W(X) over the interval [A,B].  Hence, if the abscissas may
%    be chosen arbitrarily, the Chebyshev abscissas have this advantage over
%    other choices.
%
%    For a set of points XPOL(I), 1 <= I <= NPOL, the IPOL-th Lagrange basis
%    polynomial L(IPOL)(X), has the property:
%
%      L(IPOL)( XPOL(J) ) = delta ( IPOL, J )
%
%    and may be expressed as:
%
%      L(IPOL)(X) = W(X) / ( ( X - XPOL(IPOL) ) * W'(XPOL(IPOL)) )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NPOL, the number of abscissas.
%    NPOL must be at least 1.
%
%    Input, real XPOL(NPOL), the abscissas, which should
%    be distinct.
%
%    Input, integer NVAL, the number of evaluation points.
%
%    Input, real XVA(NVAL), the points at which the Lagrange
%    factor is to be evaluated.
%
%    Output, real WVAL(NVAL), the value of the Lagrange factor at XVAL.
%
  wval = zeros ( nval, 1 );

  for ival = 1 : nval

    wval(ival) = prod ( xval(ival) - xpol(1:npol) );

  end

  return
end


function r=ksrlin(x,y,h,N)
% KSRLIN   Local linear kernel smoothing regression
%
% r=ksrlin(x,y) returns the local linear Gaussian kernel regression in
% structure r such that r.f(r.x) = y(x) + e. The bandwidth and number of
% samples are also stored in r.h and r.n respectively.
%
% r=ksrlin(x,y,h) performs the regression using the specified bandwidth, h.
%
% r=ksrlin(x,y,h,n) calculates the regression in n points (default n=100).
%
% Without output, ksrlin(x,y) or ksrlin(x,y,h) will display the regression
% plot.
%
% Algorithm
% The kernel regression is a non-parametric approach to
% estimate the conditional expectation of a random variable:
%
% E(Y|X) = f(X)
%
% where f is a non-parametric function. The normal kernel regression is a
% local constant estimator. The extension of local linear estimator is
% obtained by solving the least squares problem:
%
% min sum (y-alpha-beta(x-X))^2 kerf((x-X)/h)
%
% The local linear estimator can be given an explicit formula
%
% f(x) = 1/n sum((s2-s1*(x-X)).*kerf((x-X)/h).*Y)/(s2*s0-s1^2)
%
%where si = sum((x-X)^i*kerf((x-X)/h))/n. Compare with local constant
%estimator, the local linear estimator can improve the estimation near the
%edge of the region over which the data have been collected.
%
% See also gkde, ksdensity, ksr

% Reference:
% Bowman, A.W. and Azzalini, A., Applied Smoothing Techniques for Data
% Analysis, Clarendon Press, 1997 (p.50)

% Example 1: smooth curve with noise
%{
x = 1:100;
y = sin(x/10)+(x/50).^2;
yn = y + 0.2*randn(1,100);
r=ksrlin(x,yn);
r1=ksr(x,yn); % downloadable from FEX ID 19195
plot(x,y,'b-',x,yn,'co',r.x,r.f,'r--',r1.x,r1.f,'m-.','linewidth',2)
legend('true','data','local linear','local constant','location','northwest');
title('Gaussian kernel regression')
%}
% Example 2: with missing data
%{
x = sort(rand(1,100)*99)+1;
y = sin(x/10)+(x/50).^2;
y(round(rand(1,20)*100)) = NaN;
yn = y + 0.2*randn(1,100);
r=ksrlin(x,yn);
r1=ksr(x,yn); % downloadable from FEX ID 19195
plot(x,y,'b-',x,yn,'co',r.x,r.f,'r--',r1.x,r1.f,'m-.','linewidth',2)
legend('true','data','local linear','local constant','location','northwest');
title('Gaussian kernel regression with 20% missing data')
%}

% By Yi Cao at Cranfield University on 12 April 2008.
%

% Check input and output
error(nargchk(2,4,nargin));
error(nargoutchk(0,1,nargout));
if numel(x)~=numel(y)
    error('x and y are in different sizes.');
end

x=x(:);
y=y(:);
% clean missing or invalid data points
inv=(x~=x)|(y~=y)|(abs(x)==Inf)|(abs(y)==Inf);
x(inv)=[];
y(inv)=[];

% Default parameters
if nargin<4
    N=100;
elseif ~isscalar(N)
    error('N must be a scalar.')
end
r.n=length(x);
if nargin<3
    % optimal bandwidth suggested by Bowman and Azzalini (1997) p.31
    hx=median(abs(x-median(x)))/0.6745*(4/3/r.n)^0.2;
    hy=median(abs(y-median(y)))/0.6745*(4/3/r.n)^0.2;
    h=sqrt(hy*hx);
elseif ~isscalar(h)
    error('h must be a scalar.')
end
r.h=h;

% Gaussian kernel function
kerf=@(z)exp(-z.*z/2)/sqrt(2*pi);

r.x=linspace(min(x),max(x),N);
r.f=zeros(1,N);
for k=1:N
    d=r.x(k)-x;
    z=kerf(d/h);
    s1=d.*z;
    s2=sum(d.*s1);
    s1=sum(s1);
    r.f(k)=sum((s2-s1*d).*z.*y)/(s2*sum(z)-s1*s1);
end

% Plot
if ~nargout
    plot(r.x,r.f,'r',x,y,'bo')
    ylabel('f(x)')
    xlabel('x')
    title('Kernel Smoothing Regression');
end


function cdf = half_normal_cdf ( x, a, b )

%*****************************************************************************80
%
%% HALF_NORMAL_CDF evaluates the Half Normal CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the CDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 < B.
%
%    Output, real CDF, the value of the CDF.
%
  if ( x <= a )
    cdf = 0.0;
  else
    cdf2 = normal_cdf ( x, a, b );
    cdf = 2.0 * cdf2 - 1.0;
  end

  return
end