%% Simplicial Complex in 3D
%
% We describe general idea of the data structure generated for three
% dimensional triangular grids, suppose $N,NE,NF,NT$ represents the number
% of vertices, edges, faces and elements resprectively.

%% Construct Data Structure
% elem is $NT\times 4$ matrix with $NT$ be the number of the tetrahedrons.
% elem(i,:) contain the global index of the vertex of the i-th tetrahedron.
% we sort the vertices of elem such
% that:elem(i,1)<elem(i,2)<elem(i,3)<elem(i,4). In this way, the volume is
% not always positive, because we sacrifice the righthand orientation of tet.
% We also sort vertices of face such that:face(j,1)<face(j,2)<face(j,3),and
% the vertices of edge such that: edge(k,1)<edge(k,2).
%
% The local ordering of face in a tetrahedron is locFace = [2 3 4; 1 3 4; 1 2 4; 1 2 3].
% The local ordering of edge in a face is locEdge = [2 3;1 3;1 2].
% Now the ordering of local indices is always consistent with that of global
% indices.
%
% In the following example, elem2face, a $NT\times 4$ matrix, is the
% elementwise pointer from elem to face indicies. elem(i,:) stores the
% global indicies of faces for tetrahedron i. elem2edge, a $NT\times 6$ matrix, is the
% elementwise pointer from elem to edge indicies. elem(j,:) stores the
% global indicies of edges for tetrahedron j.

%% Example
% Generate

elem = [1 4 5 8;1 4 5 7];
node = [1,0,0;1,1,1;1,-1,-1; 0,1,0; 0,0,0;1,1,-1; 0,0,1;-1,-1,-1];
[elem2edge,~,edge] = dof3edge(elem);
[elem2face,~,face] = dof3RT0(elem);
figure(1);clf;
showmesh3(node,elem);
view(-20,20);
findnode3(node,[1,4,5,7,8]);
findelem3(node,elem);
display(edge); display(elem2edge);
display(face); display(elem2face);

%% The directions.
%% Direction of face.
% While we sort the elem, face and edge in the increasing order of
% vertices. We determine the direction of a face [i j k] by the righthand
% rule. The direction of face is not always outword normal direction of
% a certain tetrahedron. We denote the direction as +1 if the direction
% of a face is the same with the normal direction in a certain elem, and -1
% otherwise. Then for locface of a tetrahedron, the directions should be
% sign(volume)*[+1 -1 +1 -1].
%% Direction of edge.
% Similarly, we determine the direction of a edge [i j] is from the node with
% smaller global index to bigger one(that is from i to j). The direction of
% edge is not always consistent with the counter clockwise direction in a
% face. When the edge direction is the same with the local counter
% clockwise direction, we set the direction as +1, otherwise -1. Then for
% locedge of a face, the directions should be [+1 -1 +1].
%% Direction of the basis.
% According to our sorted elem and face, the RT0 basis on face [i j k].
% Defined as $\phi_{i,j,k} = 2(\lambda_i \bigtriangledown \lambda_j \times
% \bigtriangledown \lambda_k+
% \lambda_j \bigtriangledown \lambda_k \times \bigtriangledown
% \lambda_i+\lambda_k \bigtriangledown \lambda_i \times \bigtriangledown
% \lambda_j)$ The direction is always consistent with the face direction.
%
%% Inward normal direction.
% Dlambda(t,:,1) is the gradient of lambda of the 1st index of the
% t-th tet. The direction of Dlambda is always inward normal direction.
[Dlambda, ~] = gradbasis3(node,elem(2,:));
display(Dlambda);


function [sig_e, bay,model] = bay_errorbar(model,Xt, type, nb, bay)
% Compute the error bars for a one dimensional regression problem
%
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2}, Xt)
% >> sig_e = bay_errorbar(model, Xt)
%
% The computation takes into account the estimated noise variance
% and the uncertainty of the model parameters, estimated by
% Bayesian inference. sig_e is the estimated standard deviation of
% the error bars of the points Xt. A plot is obtained by replacing
% Xt by the string 'figure'.
%
%
% Full syntax
%
%     1. Using the functional interface:
%
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, Xt)
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, Xt, type)
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, Xt, type, nb)
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, 'figure')
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, 'figure', type)
% >> sig_e = bay_errorbar({X,Y,'function',gam,sig2,kernel,preprocess}, 'figure', type, nb)
%
%       Outputs
%         sig_e         : Nt x 1 vector with the [$ \sigma^2$] errorbands of the test data
%       Inputs
%         X             : N x d matrix with the inputs of the training data
%         Y             : N x 1 vector with the inputs of the training data
%         type          : 'function estimation' ('f')
%         gam           : Regularization parameter
%         sig2          : Kernel parameter
%         kernel(*)     : Kernel type (by default 'RBF_kernel')
%         preprocess(*) : 'preprocess'(*) or 'original'
%         Xt            : Nt x d matrix with the inputs of the test data
%         type(*)       : 'svd'(*), 'eig', 'eigs' or 'eign'
%         nb(*)         : Number of eigenvalues/eigenvectors used in the eigenvalue decomposition approximation
%
%     2. Using the object oriented interface:
%
% >> [sig_e, bay, model] = bay_errorbar(model, Xt)
% >> [sig_e, bay, model] = bay_errorbar(model, Xt,       type)
% >> [sig_e, bay, model] = bay_errorbar(model, Xt,       type, nb)
% >> [sig_e, bay, model] = bay_errorbar(model, 'figure')
% >> [sig_e, bay, model] = bay_errorbar(model, 'figure', type)
% >> [sig_e, bay, model] = bay_errorbar(model, 'figure', type, nb)
%
%       Outputs
%         sig_e     : Nt x 1 vector with the [$ \sigma^2$] errorbands of the test data
%         model(*)  : Object oriented representation of the LS-SVM model
%         bay(*)    : Object oriented representation of the results of the Bayesian inference
%       Inputs
%         model     : Object oriented representation of the LS-SVM model
%         Xt        : Nt x d matrix with the inputs of the test data
%         type(*)   : 'svd'(*), 'eig', 'eigs' or 'eign'
%         nb(*)     : Number of eigenvalues/eigenvectors used in the eigenvalue decomposition approximation
%
% See also:
%   bay_lssvm, bay_optimize, bay_modoutClass, plotlssvm

% Copyright (c) 2002,  KULeuven-ESAT-SCD, License & help @ http://www.esat.kuleuven.ac.be/sista/lssvmlab

if iscell(model), model = initlssvm(model{:}); end

if model.type(1)~='f',
  error(['confidence bounds only for function estimation. For' ...
	 ' classification, use ''bay_modoutClass(...)'' instead;']);
end

eval('type;','type=''svd'';');
eval('nb;','nb=model.nb_data;');
if ~(strcmpi(type,'svd') | strcmpi(type,'eig') | strcmpi(type,'eigs') | strcmpi(type,'eign')),
  error('Eigenvalue decomposition via ''svd'', ''eig'', ''eigs'' or ''eign''...');
end

if strcmpi(type,'eign')
  warning('The resulting errorbars are most probably not very usefull...');
end

if ~isstr(Xt),

  eval('[sig_e, bay] = bay_confb(model,Xt,type,nb,bay);',...
       '[sig_e, bay] = bay_confb(model,Xt,type,nb);');

else

  grid = 50;
  [X,Y] = postlssvm(model,model.xtrain,model.ytrain);
  eval('[sig_e, bay] = bay_confb(model,X,type,nb,bay);',...
       '[sig_e, bay] = bay_confb(model,X,type,nb);');

  % plot the curve including confidence bound
  sige = sqrt(sig_e);
  Yt = simlssvm(model,X);

  figure;
  hold on;
  title(['LS-SVM_{\gamma=' num2str(model.gam(1)) ', \sigma^2=' num2str(model.kernel_pars(1)) ...
	 '}^{' model.kernel_type(1:3) '} and its 95% (2\sigma) error bands']);

  if model.x_dim==1,
    xlabel('X');
    ylabel('Y');
    [~,si] = sort(X);
    plot(X(si),Yt(si),'k'); hold on;
    plot(X(si),Yt(si)+2.*sige(si),'-.r');
    plot(X(si),Yt(si)-2.*sige(si),':r');
    plot(X(si),Y(si),'k*'); hold off;
  else
    xlabel('time');
    ylabel('Y');
    plot(Yt,'k'); hold on;
    plot(Yt+2.*sige,'-.r');
    plot(Yt-2.*sige,':r');
    plot(Y,'k*'); hold off;
  end

end

function [sig_e, bay] = bay_confb(model,X,type,nb,bay)
% see formula's thesis TvG blz 126

nD = size(X,1);
%tol = .0001;

%
% calculate the eigenvalues
%
eval('bay;','[c1,c2,c3,bay] = bay_lssvm(model,1,type,nb);');
omega = kernel_matrix(model.xtrain(model.selector,1:model.x_dim), ...
		      model.kernel_type, model.kernel_pars);
oo = ones(1,model.nb_data)*omega;

% kernel values of  X
theta = kernel_matrix(model.xtrain(model.selector, 1:model.x_dim), ...
		      model.kernel_type, model.kernel_pars, X);
for i=1:nD,
  kxx(i,1) = feval(model.kernel_type, X(i,:),X(i,:), model.kernel_pars);
end

Zc = eye(model.nb_data) - ones(model.nb_data)./model.nb_data;

Hd = (Zc*bay.Rscores);
Hd = Hd*diag(1./bay.mu - (bay.mu+ bay.zeta*bay.eigvals).^-1)*Hd';

% forall x
for i=1:nD,
  term1(i,1) = bay.zeta^-1 + kxx(i)/bay.mu - theta(:,i)'*Hd*theta(:,i);
  term2(i,1) = 2/model.nb_data*sum(theta(:,i)'*Hd*omega) - 2/bay.mu/model.nb_data* sum(theta(:,i));
end

% once
term3 = 1/(bay.zeta*model.nb_data) ...
	+ 1/(bay.mu*model.nb_data^2)* sum(oo)  ...
	-1/(model.nb_data^2)* oo*Hd*oo';

sig_e = term1+term2+term3;


function [u, flag, normres, Q] = gmres(varargin)
%GMRES   Iterative solution of chebfun operator equations.
%   U = GMRES(A, F) attempts to solve the operator equation A(U) = F, where F
%   and U are CHEBFUNs and A is a function handle defining a linear operator
%   on CHEBFUN.
%
%   U = GMRES(A, F, RESTART) chooses a restart parameter. Use Inf or [] for no
%   restarts. The default is Inf.
%
%   U = GMRES(A, F, RESTART, TOL) tries to find a solution for which the
%   residual norm is less than TOL relative to the norm of F. The default
%   value is 1e-10.
%
%   U = GMRES(A, F, RESTART, TOL, MAXIT) stops after MAXIT total iterations.
%   This defaults to 36.
%
%   U = GMRES(A, F, RESTART, TOL, MAXIT, M1INV, M2INV) applies the left and
%   right preconditioners M1INV and M2INV, defined as functions. They should
%   approximate the inverse of A. Note that this usage of preconditioners
%   differs from that in the built-in GMRES.
%
%   [U, FLAG] = GMRES(A,F,...) also returns a convergence FLAG:
%     0 GMRES converged to the desired tolerance TOL within MAXIT iterations.
%     1 GMRES iterated MAXIT times but did not converge.
%
%   [U, FLAG, NORMRES] = GMRES(A, F, ...) also returns a vector of the relative
%   residual norms for all iterations. Note the output ordering is not the same
%   as for built-in GMRES. This calling sequence will also print out updates on
%   the progress of the iteration.
%
% Example:
%   % To solve a simple Volterra integral equation:
%   f = chebfun('exp(-4*x.^2)', [-1 1]);
%   A = @(u) cumsum(u) + 20*u;
%   u = gmres(A, f, Inf, 1e-14);
%
% See also GMRES, CHEBOP/MLDIVIDE.

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

% Parse inputs and supply defaults:
defaults = {[], [], Inf, 1e-10, 36, [], []};
idx = nargin+1:length(defaults);
args = [varargin, defaults(idx)];
[L, f, m, tol, maxiter, M1inv, M2inv] = deal( args{:} );
showtrace = (nargout > 2);

if ( m == 0 )
    % No restarts:
    m = Inf;
end
% Avoid warning about Inf in for loop:
m = min(m, maxiter + 1);

% Initialise:
u = chebfun(0, domain(f));
normb = norm(f);
r = f;
if ( ~isempty(M1inv) )
    r = M1inv(r);
end
normres(1) = norm(r)/normb;

j = 1;                                             % total iterations
while ( (normres(j) > tol) && (j < maxiter) )      % outer iterations

    H = [];
    QTb = norm(r);
    Q = r/QTb ;                                    % Krylov basis

    for n = 1:m                                    % inner iterations

        % Next Krylov vector, with preconditioners.
        q = Q(:,n);
        if ( ~isempty(M2inv) )
            q = M2inv(q);
        end
        v = L(q);

        if ( ~isempty(M1inv) )
            v = M1inv(v);
        end

        % Modified Gram-Schmidt iteration.
        for k = 1:n
            H(k,n) = Q(:,k)' * v ;                   %#ok<AGROW>
            v = v - H(k,n)*Q(:,k);
        end
        H(n+1,n) = norm(v);                          %#ok<AGROW>

        % Use QR factorization to find the residual norm.
        % TODO: This could be made more efficient (worthwhile?).
        QTb(n+1,1) = 0;                              % by orthogonality
        j = j + 1;
        [P, R] = qr(H);
        normres(j) = abs( P(1,n+1)*QTb(1) ) / normb; %#ok<AGROW>

        % Done?
        if ( normres(j) < tol )
            showtrace = false;
            flag = 0;
            break
        end

        % Trace iteration--for debugging, not an official option.
        if ( showtrace && (rem(j - 1, 5) == 0) )
            fprintf('Iteration %2i: relative residual norm = %.3e\n', ...
                j - 1, normres(j));
        end

        % Give up?
        if ( j == maxiter + 1 )
            warning('CHEBFUN:CHEBFUN:gmres:maxiter', ...
                'Maximum number of iterations reached.')
            showtrace = false;
            break
        end

        % New basis vector:
        Q(:,n+1) = v / H(n+1,n);

        % Reorthogonalize (for research only--not an official option).
        if ( rem(n, Inf) == 0 )
            [Q, ignored] = qr(Q, 0);
        end

    end   % end inner iterations

    y = R(1:n,1:n)\(P(:,1:n)'*QTb);                % least squares soln
    u0 = Q(:,1:n)*y;                               % new part of solution
    if ( ~isempty(M2inv) )
        u0 = M2inv(u0);
    end
    u = u + u0;                                    % solution
    v = L(u0);
    if ( ~isempty(M1inv) )
        v = M1inv(v);
    end
    r = r - v;                                     % new residual
    if ( showtrace )
        fprintf('  (restart)\n')
    end

end   % end outer iterations

if ( j >= maxiter )
    flag = 1;
end
if ( nargout < 2 )
    fprintf('\n  Final relative residual: %.3e\n\n', normres(end))
end

end   % end main function


function [ o, c, f ] = lp_coefficients ( n )

%*****************************************************************************80
%
%% LP_COEFFICIENTS: coefficients of Legendre polynomials P(n,x).
%
%  Discussion:
%
%    The Legendre polynomial with index N will have O = 1 + (N/2) terms.
%    The monomials of orders N, N-2, N-2, ... will have nonzero coefficients.
%
%  First terms:
%
%     1
%     0     1
%    -1/2   0      3/2
%     0    -3/2    0     5/2
%     3/8   0    -30/8   0     35/8
%     0    15/8    0   -70/8    0     63/8
%    -5/16  0    105/16  0   -315/16   0    231/16
%     0   -35/16   0   315/16   0   -693/16   0    429/16
%
%     1.00000
%     0.00000  1.00000
%    -0.50000  0.00000  1.50000
%     0.00000 -1.50000  0.00000  2.5000
%     0.37500  0.00000 -3.75000  0.00000  4.37500
%     0.00000  1.87500  0.00000 -8.75000  0.00000  7.87500
%    -0.31250  0.00000  6.56250  0.00000 -19.6875  0.00000  14.4375
%     0.00000 -2.1875   0.00000  19.6875  0.00000 -43.3215  0.00000  26.8125
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 September 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%    Daniel Zwillinger, editor,
%    CRC Standard Mathematical Tables and Formulae,
%    30th Edition,
%    CRC Press, 1996.
%
%  Parameters:
%
%    Input, integer N, the degree of the polynomial.
%
%    Output, integer O, the number of coefficients.
%
%    Output, real C(1:O,1), the coefficients of the Legendre polynomial
%    of degree N.
%
%    Output, integer F(1:O,1), the exponents.
%

%
%  Compute the table.
%
  ctable(1:n+1,1:n+1) = 0.0;

  ctable(1,1) = 1.0;

  if ( 1 <= n)

    ctable(2,2) = 1.0;

    for i = 2 : n
      ctable(i+1,1:i-1) =                     (   - i + 1 ) * ctable(i-1,1:i-1) / i;
      ctable(i+1,2:i+1) = ctable(i+1,2:i+1) + ( i + i - 1 ) * ctable(i  ,1:i  ) / i;
    end

  end
%
%  Extract the nonzero data from the alternating columns of the last row.
%
  o = floor ( ( n + 2 ) / 2 );

  c = zeros ( o, 1 );
  f = zeros ( o, 1 );

  k = o;
  for j = n + 1 : -2 : 1
    c(k) = ctable(n+1,j);
    f(k) = j - 1;
    k = k - 1;
  end

  return
end


function plotps(x,Ts,N)
% Plot the power spectrum.
% plotps(x,[Ts,N])

if nargin < 2, Ts = 1; end
if nargin < 3, N  = 2^(ceil(log(length(x))/log(2))+2); end

Fs = 1/Ts;
X  = abs(fft(x,N)).^2;
%% X  = abs(2*pi*fft(x,N)/N*Ts).^2;

figure, plot(linspace(0,Fs/2,N/2+1),X(1:N/2+1));
set(gca,'FontSize',8,'XLim',[0 Fs/2],'YScale','log'); xlabel('Frequency'); ylabel('Amplitude');

%% figure, plot(linspace(0,Fs,N+1),[X,X(1)]);
%% set(gca,'FontSize',8,'XLim',[0 Fs],'YScale','log'); xlabel('Frequency'); ylabel('Amplitude');


function [ grid_num, point_num ] = gl_levels_minmax_size ( dim_num, ...
  level_min, level_max )

%*****************************************************************************80
%
%% GL_LEVELS_MINMAX_SIZE returns sizes for GL_LEVELS_MINMAX.
%
%  Discussion:
%
%    This routine can be used to determine the necessary size to be
%    allocated to arrays GRID_ORDER and GRID_POINT in a call to
%    GL_GRIDS_MINMAX.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 July 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer LEVEL_MIN, LEVEL_MAX, the minimum and maximum values of
%    LEVEL, the sum of the levels in each spatial coordinate.
%
%    Output, integer GRID_NUM, the number of Gauss Legendre
%    grids whose LEVEL value is between LEVEL_MIN and LEVEL_MAX.
%
%    Output, integer POINT_NUM, the total number of points in the grids.
%

%
%  Determine the total number of points that will be generated
%  by "going through the motions".
%
  point_num = 0;
  grid_num = 0;

  for level = level_min : level_max

    level_1d = [];
    more = 0;
    h = 0;
    t = 0;

    while ( 1 )

      [ level_1d, more, h, t ] = comp_next ( level, dim_num, level_1d, more, h, t );

      order_1d = gl_level_to_order ( dim_num, level_1d );

      order_nd = prod ( order_1d(1:dim_num) );

      point_num = point_num + order_nd;

      grid_num = grid_num + 1;

      if ( ~more )
        break
      end

    end

  end

  return
end


function varargout = projPointOnPolygon(point, poly, varargin)
%PROJPOINTONPOLYGON  Compute position of a point projected on a polygon.
%
%   POS = projPointOnPolygon(POINT, POLYGON)
%   Compute the position of the orthogonal projection of a point on a
%   polygon.
%   POINT is a 1-by-2 row vector containing point coordinates
%   POLYGON is a N-by-2 array containing coordinates of polygon vertices
%
%   When POINT is an array of points, returns a column vector with as many
%   rows as the number of points.
%
%   [POS, DIST] = projPointOnPolygon(...)
%   Also returns the distance between POINT and POLYGON. The distance is
%   negative if the point is located inside of the polygon.
%
%   Example
%     poly = [10 10; 20 10;20 20;10 20];
%     projPointOnPolygon([15 0], poly)
%     ans =
%         0.5000
%     projPointOnPolygon([0 16], poly)
%     ans =
%         3.4000
%
%   See also
%   points2d, polygons2d, polygonPoint, projPointOnPolyline
%   distancePointpolygon
%

% ------
% Author: David Legland
% E-mail: david.legland@grignon.inra.fr
% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b)
% Copyright 2009-2022 INRA - Cepia Software Platform

% eventually copy first point at the end to ensure closed polygon
if sum(poly(end, :) == poly(1,:)) ~= 2
    poly = [poly; poly(1,:)];
end

% compute position wrt outline
[pos, minDist] = projPointOnPolyline(point, poly);

% process output arguments
if nargout <= 1
    varargout{1} = pos;
elseif nargout == 2
    varargout{1} = pos;
    if inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2))
        minDist = -minDist;
    end
    varargout{2} = minDist;
end


function c = assemble_mass ( node_num, node_x, element_num, element_node, ...
  quad_num )

%*****************************************************************************80
%
%% ASSEMBLE_MASS assembles the finite element mass matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NODE_NUM, the number of nodes.
%
%    Input, real NODE_X(NODE_NUM), the coordinates of nodes.
%
%    Input, integer ELEMENT_NUM, the number of elements.
%
%    Input, integer ELEMENT_NODE(2,ELEMENT_NUM);
%    ELEMENT_NODE(I,J) is the global index of local node I in element J.
%
%    Input, integer QUAD_NUM, the number of quadrature points used in assembly.
%
%    Output, sparse real C(NODE_NUM,NODE_NUM), the finite element mass matrix.
%
%  Local parameters:
%
%    Local, real BI, DBIDX, the value of some basis function
%    and its first derivative at a quadrature point.
%
%    Local, real BJ, DBJDX, the value of another basis
%    function and its first derivative at a quadrature point.
%

%
%  Initialize the arrays.
%
  c = [];
  c = sparse ( node_num, node_num );
%
%  Get the quadrature weights and nodes.
%
  [ reference_w, reference_q ] = quadrature_set ( quad_num );
%
%  Consider each ELEMENT.
%
  for element = 1 : element_num

    element_x(1:2,1) = node_x(element_node(1:2,element));

    element_q(1:quad_num,1) = reference_to_physical ( element, element_node, ...
      node_x, quad_num, reference_q );

    element_area = element_x(2) - element_x(1);

    element_w(1:quad_num,1) = ( element_area / 2.0 ) * reference_w(1:quad_num);
%
%  Consider the QUAD-th quadrature point in the element.
%
    for quad = 1 : quad_num
%
%  Consider the TEST-th test function.
%
%  We generate an integral for every node associated with an unknown.
%
      for i = 1 : 2

        test = element_node(i,element);

        [ bi, dbidx ] = basis_function ( test, element, node_x, 1, element_q(quad) );
%
%  Consider the BASIS-th basis function, which is used to form the
%  value of the solution function.
%
        for j = 1 : 2

          basis = element_node(j,element);

          [ bj, dbjdx ] = basis_function ( basis, element, node_x, 1, element_q(quad) );

          c(test,basis) = c(test,basis) + element_w(quad) * bi * bj;

        end

      end

    end

  end

  return
end


function [A1nmb] = moran(initsize, popsize)
% MORAN generates a trajectory of a Moran type process
%  which gives the number of genes of allelic type A1 in a population
%  of haploid individuals that can exist in either type A1 or type A2.
%  The population size is popsize and the initial number of type A1
%  individuals os initsize.
%
%  [A1nmb] = galtonwatson(initsize, popsize)
%
%  Inputs: initsize - initial number of A1 genes
%          popsize - the total population size (preserved)
%
%  Outputs: A1nmb - the successive number of type A1 genes in the population

% Authors: R.Gaigalas, I.Kaj
% v1.2 04-Oct-02

if (nargin==0)
  initsize=10;
  popsize=30;
end

A1nmb=zeros(1,popsize);
A1nmb(1)=initsize;

lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
mu = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');

x=initsize;
i=1;
while  (x>1 & x<popsize+1)
  if (lambda(x,popsize)/(lambda(x,popsize)+mu(x,popsize))>rand)
   x=x+1;
   A1nmb(i)=x;
  else
   x=x-1;
   A1nmb(i)=x;
  end;
  i=i+1;
end;
nmbsteps=length(A1nmb);
rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
        +mu(A1nmb(1:nmbsteps-1),popsize);

jumptimes=cumsum(-log(rand(1,nmbsteps-1))./rate);
jumptimes=[0 jumptimes];

stairs(jumptimes,A1nmb);
axis([0 jumptimes(nmbsteps) 0 popsize+1]);


function out = proj_spectahedron_box(X,r,l,u,eq_flag)
%PROJ_SPECTAHEDRON_BOX computes the orthogonal projection onto the spectahedron {X : Tr(X) = r, X psd, l<=eig(X)<=u} or
%                                                onto the full spectahedron {X : Tr(X)<= r, X psd, l<=eig(X)<=u}
%
%  Usage:
%  out = PROJ_SPECTAHEDRON_BOX(X,[r],[l],[u],[eq_flag])
%  ===========================================
%  Input:
%  X - matrix to be projected
%  r - positive scalar [default: 1]
%  l - lower bound (scalar) [default: 0]
%  u - upper bound (scalar) [default: inf]
%  eq_flag - a flag that determines whether the projection is onto the spectahedron ('eq') or
%                 the full spectahedron ('ineq') [defualt: 'eq']
%  ===========================================
%  Assumptions:
%  X symmetric
%  r > 0
%  ===========================================
%  Output:
%  out - projection matrix

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

%reading the user X and setting defalut values when required.
if (nargin < 1)
    error ('usage: spectahedron_box(X,[r],[l],[u],[eq_flag])') ;
end

if (( nargin < 5) || (isempty(eq_flag)) )
    %eq_flag is not given, setting to default value: true
    eq_flag = 'eq' ;
end

if ((nargin < 4) || (isempty(u)))
    %u is not given, setting to default value: inf
    u=inf ;
end

if ((nargin < 3) || (isempty(l)))
    %l is not given, setting to default value: 0
    l=0 ;
end

if ((nargin < 2) || (isempty(r)))
    %r is not given, setting to default value: 1
    r = 1 ;
end

if ( r <= 0 )
   error('Set is infeasible') ;
end

eps = 1e-10 ; % defalut value for eps : 1e-10
if ((size(X,1) ~= size(X,2)) || (norm( X - X') > eps))
    error('usage: spectahedron_box(X,[r],[eq_flag]) - X should be a symmetric matrix') ;
end

X = 0.5 * (X + X');

[V,D] = eig(X) ;

if (strcmp(eq_flag,'eq') == 1)
    %call proj_simplex with eq
   out = V * diag(proj_hyperplane_box(diag(D),ones(length(X),1),r,l,u)) * V' ;
   out=(out+out')/2;
else
    if (strcmp(eq_flag,'ineq') == 1)
        %call proj_simplex with ineq
        out = V * diag((proj_halfspace_box(diag(D),ones(length(X),1),r,l,u))) * V' ;
        out=(out+out')/2;
    else
        error('usage: spectahedron(X,[r],[eq_flag]) - eq_flag should be either eq or ineq') ;
    end
end


function op = proj_nuclear( q, sz )

%PROJ_NUCLEAR  Projection onto the set of matrices with nuclear norm less than or equal to q.
%    OP = PROJ_NUCLEAR( q ) returns a function that implements the
%    indicator for matrices with nuclear norm less than q.
%    Q is optional; if omitted, Q=1 is assumed. But if Q is supplied,
%    it must be a positive real scalar.
%    This function is like proj_psdUTrace.m but does not assume
%    that inputs are square Hermitian positive semidefinite matrices.
%
%    OP = PROJ_NUCLEAR( ..., SZ )
%    where SZ = [n1,n2], will assume the input has been vectorized
%    and thus will reshape it into a matrix of size n1 x n2. TFOCS
%    can handle matrix variables so this form of PROJ_NUCLEAR is not
%    always necessary, but it can be easier to find bugs if using
%    only vector variables.
%
% This version uses a dense svd decomposition; future versions
% of TFOCS will take advantage of low-rank and/or sparse structure.
% Dual function: prox_spectral.m
% See also prox_spectral, proj_psdUTrace.m, proj_simplex.m, prox_nuclear.m

% June 26, 2012

if nargin == 0,
	q = 1;
elseif ~isnumeric( q ) || ~isreal( q ) || numel( q ) ~= 1 || q <= 0,
	error( 'Argument must be positive.' );
end
if nargin < 2, sz = []; end
q = proj_simplex( q );
op = @(varargin)proj_nuclear_q( q, sz, varargin{:} );

function [ v, X ] = proj_nuclear_q( eproj, sz, X, t )

VECTORIZE = false;
% Input must be a matrix

% In proj_psdUTrace.m, we allow vector inputs because
%   we can reshape them (since we have square matrices).
%   For nuclear norm, inputs can be rectangular matrices,
%   so we do not know how to correctly reshape a vector in
%   this case.

% if size(X,1) ~= size(X,2)
%     n = sqrt(length(X));
%     X = reshape(X, n, n );
%     VECTORIZE   = true;
% end

% Update, Jan 2014, allowing vector variables, as long
%   as the 'sz' variable has been given
if ~isempty(sz)
    if size(X,2) > 1
        error('proj_nuclear: when using an explicit size value "sz", variable should be a vector');
    end
    X = reshape(X, sz(1), sz(2) );
    VECTORIZE   = true;
elseif size(X,2) == 1
    warning('proj_nuclear: appears variable is a vector not a matrix. Are you sure you want the SVD of a vector?');
end

v = 0;
if nargin > 3 && t > 0,
    [U,D,V] = svd(X,'econ');
    [dum,D] = eproj(diag(D),t);
    tt = D > 0;
    X  = U(:,tt)*diag(D(tt))*V(:,tt)';
    if VECTORIZE, X = X(:); end
elseif any(svd(X)<0),
    v = Inf;
end

% TFOCS v1.3 by Stephen Becker, Emmanuel Candes, and Michael Grant.
% Copyright 2013 California Institute of Technology and CVX Research.
% See the file LICENSE for full license information.


function simp_plot_2d ( p, t )

%*****************************************************************************80
%
%% SIMP_PLOT_2D displays a plot of the triangles that form a mesh in 2D.
%
%  Licensing:
%
%    (C) 2004 Per-Olof Persson.
%    See COPYRIGHT.TXT for details.
%
%  Reference:
%
%    Per-Olof Persson and Gilbert Strang,
%    A Simple Mesh Generator in MATLAB,
%    SIAM Review,
%    Volume 46, Number 2, June 2004, pages 329-345.
%
%  Parameters:
%
%    Input, real P(NP,2), the coordinates of a set of nodes in 2D.
%
%    Input, integer T(NT,3), a list of the nodes which make up each triangle in the mesh.
%
  h = trimesh ( t, p(:,1), p(:,2), 0*p(:,1), ...
    'facecolor', 'none', 'edgecolor', 'k' );

  view ( 2 )
  axis equal
  axis off

  return
end


%% Image Moments
% We learn to calculate the moments of an image.
%
% In this sample you will learn how to use the following OpenCV functions:
%
% * <matlab:doc('cv.moments') cv.moments>
% * <matlab:doc('cv.contourArea') cv.contourArea>
% * <matlab:doc('cv.arcLength') cv.arcLength>
%
% Sources:
%
% * <https://docs.opencv.org/3.4.0/d0/d49/tutorial_moments.html>
% * <https://github.com/opencv/opencv/blob/3.4.0/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp>
%

function varargout = moments_demo_gui(im)
    % load source image
    if nargin < 1
        src = imread(fullfile(mexopencv.root(),'test','monster.jpg'));
    elseif ischar(im)
        src = imread(im);
    else
        src = im;
    end

    % Convert image to gray and blur it
    if size(src,3) == 3
        src = cv.cvtColor(src, 'RGB2GRAY');
    end
    src = cv.blur(src, 'KSize',[3 3]);

    % create the UI
    h = buildGUI(src);
    if nargout > 0, varargout{1} = h; end
end

function onChange(~,~,h)
    %ONCHANGE  Event handler for UI controls

    % retrieve current values from UI controls
    thresh = round(get(h.slid, 'Value'));
    set(h.txt, 'String',sprintf('Canny thresh: %3d',thresh));

    % Detect edges using Canny
    canny_output = cv.Canny(h.src, [thresh thresh*2], 'ApertureSize',3);

    % Find contours
    contours = cv.findContours(canny_output, 'Mode','Tree', 'Method','Simple');

    % Get the moments and compute the mass center
    mu = cell(size(contours));
    mc = cell(size(contours));
    for i=1:numel(contours)
        mu{i} = cv.moments(contours{i}, 'BinaryImage',false);
        mc{i} = [mu{i}.m10, mu{i}.m01] ./ mu{i}.m00;
    end

    % Draw contours
    drawing = zeros([size(canny_output) 3], 'uint8');
    for i=1:numel(contours)
        clr = randi([0 255], [1 3], 'uint8');
        drawing = cv.drawContours(drawing, contours, 'ContourIdx',i-1, ...
            'Color',clr, 'Thickness',2);
        drawing = cv.circle(drawing, mc{i}, 4, ...
            'Color',clr, 'Thickness','Filled');
    end

    % show result
    set(h.img, 'CData',drawing);
    drawnow;

    % Calculate the area with the moments 00 and compare with the result of
    % the OpenCV function
    fprintf('\t Info: Area and Contour Length \n');
    for i=1:numel(contours)
        fprintf([' * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f' ...
            ' - Length: %.2f \n'], i, mu{i}.m00, ...
            cv.contourArea(contours{i}), ...
            cv.arcLength(contours{i}, 'Closed',true));
    end
end

function h = buildGUI(img)
    %BUILDGUI  Creates the UI

    % parameters
    thresh = 100;
    max_thresh = 255;
    sz = size(img);
    sz(2) = max(sz(2), 250);  % minimum figure width

    % build the user interface (no resizing to keep it simple)
    h = struct();
    h.src = img;
    h.fig = figure('Name','Image Moments Demo', ...
        'NumberTitle','off', 'Menubar','none', 'Resize','off', ...
        'Position',[200 200 sz(2) sz(1)+29]);
    if ~mexopencv.isOctave()
        %HACK: not implemented in Octave
        movegui(h.fig, 'center');
    end
    h.ax = axes('Parent',h.fig, 'Units','pixels', 'Position',[1 30 sz(2) sz(1)]);
    if ~mexopencv.isOctave()
        h.img = imshow(img, 'Parent',h.ax);
    else
        %HACK: https://savannah.gnu.org/bugs/index.php?45473
        axes(h.ax);
        h.img = imshow(img);
    end
    h.txt = uicontrol('Parent',h.fig, 'Style','text', 'FontSize',11, ...
        'Position',[5 5 130 20], 'String',sprintf('Canny thresh: %3d',thresh));
    h.slid = uicontrol('Parent',h.fig, 'Style','slider', 'Value',thresh, ...
        'Min',0, 'Max',max_thresh, 'SliderStep',[1 10]./(max_thresh-0), ...
        'Position',[135 5 sz(2)-135-5 20]);

    % hook event handlers, and trigger default start
    set(h.slid, 'Callback',{@onChange,h}, ...
        'Interruptible','off', 'BusyAction','cancel');
    onChange([],[],h);
end


function [ c, seed ] = i4mat_uniform_ab ( m, n, a, b, seed )

%*****************************************************************************80
%
%% I4MAT_UNIFORM_AB returns a scaled pseudorandom I4MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 November 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Linus Schrage,
%    A Guide to Simulation,
%    Springer Verlag, pages 201-202, 1983.
%
%    Pierre L'Ecuyer,
%    Random Number Generation,
%    in Handbook of Simulation,
%    edited by Jerry Banks,
%    Wiley Interscience, page 95, 1998.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, pages 362-376, 1986.
%
%    Peter Lewis, Allen Goodman, James Miller
%    A Pseudo-Random Number Generator for the System/360,
%    IBM Systems Journal,
%    Volume 8, pages 136-143, 1969.
%
%  Parameters:
%
%    Input, integer M, N, the row and column dimensions of the matrix.
%
%    Input, integer A, B, the minimum and maximum acceptable values.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, integer C(M,N), the randomly chosen integer vector.
%
%    Output, integer SEED, the updated seed.
%
  if ( seed == 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4MAT_UNIFORM_AB - Fatal error!\n' );
    fprintf ( 1, '  Input SEED = 0!\n' );
    error ( 'I4MAT_UNIFORM_AB - Fatal error!' );
  end

  seed = floor ( seed );
  a = round ( a );
  b = round ( b );

  for j = 1 : n

    for i = 1 : m

      seed = mod ( seed, 2147483647 );

      if ( seed < 0 )
        seed = seed + 2147483647;
      end

      k = floor ( seed / 127773 );

      seed = 16807 * ( seed - k * 127773 ) - k * 2836;

      if ( seed < 0 )
        seed = seed + 2147483647;
      end

      r = seed * 4.656612875E-10;
%
%  Scale R to lie between A-0.5 and B+0.5.
%
      r = ( 1.0 - r ) * ( min ( a, b ) - 0.5 ) ...
        +         r   * ( max ( a, b ) + 0.5 );
%
%  Use rounding to convert R to an integer between A and B.
%
      value = round ( r );

      value = max ( value, min ( a, b ) );
      value = min ( value, max ( a, b ) );

      c(i,j) = value;

    end
  end

  return
end


function ulimit = SlopeLimitLin(ul,xl,vm1,v0,vp1);

% function ulimit = SlopeLimitLin(ul,xl,vm1,v0,vp1);
% Purpose: Apply slopelimited on linear function ul(Np,1) on x(Np,1)
%          (vm1,v0,vp1) are cell averages left, center, and right

Globals1D;

% Compute various geometric measures
ulimit = ul; h = xl(Np,:)-xl(1,:);
x0 = ones(Np,1)*(xl(1,:) + h/2);

hN = ones(Np,1)*h;

% Limit function
ux = (2./hN).*(Dr*ul);

ulimit = ones(Np,1)*v0+(xl-x0).*(ones(Np,1)*minmod([ux(1,:);(vp1-v0)./h;(v0-vm1)./h]));
%ulimit = ones(Np,1)*v0+(xl-x0).*(ones(Np,1)*minmodB([ux(1,:);(vp1-v0)./h;(v0-vm1)./h],1e-2,h));
return


function y=rdct(x,n)
%RDCT     Discrete cosine transform of real data Y=(X,N)
% Data is truncated/padded to length N.
%
% This routine is equivalent to multiplying by the matrix
%
%   rdct(eye(n)) = diag([sqrt(2) 2*ones(1,n-1)]) * cos((0:n-1)'*(0.5:n)*pi/n)
%
% The rows and columns of the matrix are orthogonal but not unit modulus.
% Various versions of the DCT are obtained by pre-multiplying the above
% matrix by diag([b/a ones(1,n-1)/a]) and post-multiplying the
% inverse transform matrix by its inverse. A common choice is a=n and/or b=sqrt(2).
% Choose a=sqrt(2n) and b=1 to make the matrix orthogonal.
% If b~=1 then the columns are no longer orthogonal.
%
% see IRDCT for the inverse transform

%      Copyright (C) Mike Brookes 1998
%
%      Last modified Tue Apr 13 15:56:48 1999
%
%   VOICEBOX is a MATLAB toolbox for speech processing. Home page is at
%   http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   ftp://prep.ai.mit.edu/pub/gnu/COPYING-2.0 or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fl=size(x,1)==1;
if fl x=x(:); end
[m,k]=size(x);
if nargin<2 n=m;
elseif n>m x=[x; zeros(n-m,k)];
elseif n<m x(n+1:m,:)=[];
end

x=[x(1:2:n,:); x(2*fix(n/2):-2:2,:)];
z=[sqrt(2) 2*exp((-0.5i*pi/n)*(1:n-1))].';
y=real(fft(x).*z(:,ones(1,k)));

if fl y=y.'; end


% This is a demonstration of deterministic neoclassical growth model in
% macro economic theory programed for phd course I'm taking in CMU
% for full reference of model See  "Recersive methods in Economi Dynamics", Nancy L stockey and robert E. Lucas. Jr.
% you can change model parameter for your need
%
% There is no population growth or technology progress
% Labor supply is inelastic
% Method=1----Deterministic, discrete state space model, No interpolation
% Method=2----Deterministic, continuous state space model, With interpolation
%
% Utility function is util.m
% Production function is cobb.m
% Plotting function vgc_glot.m
%
% Author Dan Li, Carnegie Mellon University
% Email :  danli@andrew.cmu.edu
% Homepage  www.danli.org
% April.2003

clc;
clear all;

% ------Model Parameter specification---------
global gamma alpha
gamma=1;        % risk aversion coefficient, log utility function
alpha=0.3;      % capital share
beta=0.96;      % discount factor
delta=.1;       %   depreciation rate
z=1  ;           % initial state for deteriministic case

method=input(['Method=?,\n'...
             '1 for Deterministic,No interpolation \n' ...
             '2 for Deterministic With Interpolation,\n']);

%------ Parameter of computation--------------------------
nk=input(['Number of grid?(20-200 for Method 1)\n'...
          '(<=30 for Method 2, <=200 for Method 3)>>']);   % number of grid
maxloop=40;         % number of maximum iteration
tol=10^(-3);        % tolerence level for value function iteration

tic; % start the clock

% ******Low and upper bound of state variable k ******
% Steady state value kstar,   f'(kstar)=1/beta-1+delta

kstar=(((1/(alpha*beta))-((1-delta)/alpha)))^(1/(alpha-1));
lowk=0.8*kstar;
upk=1.2*kstar;

k=linspace(lowk,upk,nk)';  % build up grid
[K,Kprime]=meshgrid(k);

v=zeros(size(k))*ones(size(z));     vn=v;
g=v;     gn=g;
loop=0;     dv=1;   dk=1;

if method==1
%--------------------------------------
%  No Interpolation Method, Method=1
%---------------------------------------
	C=cobb(K)+(1-delta)*K-Kprime;
	U=util(C);

	kpos=100*ones(size(k));% initial value of loop and distance of value

	while dv>tol & loop<=maxloop & dk
        loop=loop+1;
        [vn,kposn]=max(U+beta*v*ones(1,nk));  %new value vector
        vn=vn'; kposn=kposn';
        dv=max(abs((vn-v)./(v+eps)));
        dk=~all(kpos==kposn); % whether or not position exactly the same
        v=vn; kpos=kposn;
	end
	g=k(kpos);  %  policy  function of next period capital

elseif method==2;
%--------------------------------------
%  Interpolation Method, Method=2
%---------------------------------------
   	while dv>tol & dk>tol & loop<=maxloop
	loop=loop+1;
	pp = spline(k,v);
	vf=inline('-(util(-y+cobb(k)+(1-delta)*k)+beta*ppval(pp,y))','y','k','delta','beta','pp');
		for ik=1:nk
            [gn(ik),vn(ik)]=fminbnd(vf,lowk,upk,[],k(ik),delta,beta,pp) ;
            vn(ik)=-vn(ik);
		end;
	dk=max(abs((gn-g)./(g+eps)));
    dv=max(abs((vn-v)./(v+eps)));
	v=vn; g=gn;
    end;
end
%------------------------------------------------------------
% use calculated k g to get consumption policy and plot , save
%--------------------------------------------------------------
%Polc=cobb(k)*z+(1-delta)*k*ones(size(z))-g; %  policy function of consumption
Polc=cobb(k)+(1-delta)*k-g; %  policy function of consumption

vgc_plot(k,kstar,v,Polc,g, method);

%--------------so other output for observation of convergence--------------
t=toc  % read clock


function c = mycross(a,b,dim)
%% MYCROSS cross product
%
% c = mycross(a,b) computes the cross product of vectors a and b. It is
% used to replace the built-in cross function which is two times slower.
%
% c = mycross(a,b,dim) the input a, b could be matrix of vectors. The input
% dim specifies the dimension. By default, dim = 2. Namely each row of a
% and b is a vector in R3.
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

if ~exist('dim','var'), dim = 2; end

% Check dimensions
if (size(a,dim)~=3) || (size(b,dim)~=3),
  error(message('MATLAB:cross:InvalidDimAorBForCrossProd'))
end

c = zeros(size(a,1),3);
c(:,1) = a(:,2).*b(:,3) - a(:,3).*b(:,2);
c(:,2) = a(:,3).*b(:,1) - a(:,1).*b(:,3);
c(:,3) = a(:,1).*b(:,2) - a(:,2).*b(:,1);


function [sbc, fpe, logdp, np] = ARFIT_arord(R, m, mcor, ne, pmin, pmax)
%ARORD	Evaluates criteria for selecting the order of an AR model.
%
%  [SBC,FPE]=ARORD(R,m,mcor,ne,pmin,pmax) returns approximate values
%  of the order selection criteria SBC and FPE for models of order
%  pmin:pmax. The input matrix R is the upper triangular factor in the
%  QR factorization of the AR model; m is the dimension of the state
%  vectors; the flag mcor indicates whether or not an intercept vector
%  is being fitted; and ne is the number of block equations of size m
%  used in the estimation. The returned values of the order selection
%  criteria are approximate in that in evaluating a selection
%  criterion for an AR model of order p < pmax, pmax-p initial values
%  of the given time series are ignored.
%
%  ARORD is called by ARFIT.
%
%  See also ARFIT, ARQR.

%  For testing purposes, ARORD also returns the vectors logdp and np,
%  containing the logarithms of the determinants of the (scaled)
%  covariance matrix estimates and the number of parameter vectors at
%  each order pmin:pmax.

%  Modified 17-Dec-99
%  Author: Tapio Schneider
%          tapio@gps.caltech.edu

  imax 	  = pmax-pmin+1;        % maximum index of output vectors

  % initialize output vectors
  sbc     = zeros(1, imax);     % Schwarz's Bayesian Criterion
  fpe     = zeros(1, imax);     % log of Akaike's Final Prediction Error
  logdp   = zeros(1, imax);     % determinant of (scaled) covariance matrix
  np      = zeros(1, imax);     % number of parameter vectors of length m
  np(imax)= m*pmax+mcor;

  % Get lower right triangle R22 of R:
  %
  %   | R11  R12 |
  % R=|          |
  %   | 0    R22 |
  %
  R22     = R(np(imax)+1 : np(imax)+m, np(imax)+1 : np(imax)+m);

  % From R22, get inverse of residual cross-product matrix for model
  % of order pmax
  invR22  = inv(R22);
  Mp      = invR22*invR22';

  % For order selection, get determinant of residual cross-product matrix
  %       logdp = log det(residual cross-product matrix)
  logdp(imax) = 2.*log(abs(prod(diag(R22))));

  % Compute approximate order selection criteria for models of
  % order pmin:pmax
  i = imax;
  for p = pmax:-1:pmin
    np(i)      = m*p + mcor;	% number of parameter vectors of length m
   if p < pmax
      % Downdate determinant of residual cross-product matrix
      % Rp: Part of R to be added to Cholesky factor of covariance matrix
      Rp       = R(np(i)+1:np(i)+m, np(imax)+1:np(imax)+m);

      % Get Mp, the downdated inverse of the residual cross-product
      % matrix, using the Woodbury formula
      L        = chol(eye(m) + Rp*Mp*Rp')';
      N        = L \ Rp*Mp;
      Mp       = Mp - N'*N;

      % Get downdated logarithm of determinant
      logdp(i) = logdp(i+1) + 2.* log(abs(prod(diag(L))));
   end

   % Schwarz's Bayesian Criterion
   sbc(i) = logdp(i)/m - log(ne) * (ne-np(i))/ne;

   % logarithm of Akaike's Final Prediction Error
   fpe(i) = logdp(i)/m - log(ne*(ne-np(i))/(ne+np(i)));

   % Modified Schwarz criterion (MSC):
   % msc(i) = logdp(i)/m - (log(ne) - 2.5) * (1 - 2.5*np(i)/(ne-np(i)));

   i      = i-1;                % go to next lower order
end


function y = apm_quadprog(H,f,A,b,Aeq,beq,lb,ub,x0)
%apm_quadprog Quadratic programming.
%   y = apm_quadprog(H,f,A,b,Aeq,beq,LB,UB,X0) writes a quadratic
%   programming model in APMonitor Modeling Language and attempts
%   to solve the quadratic programming problem:
%
%            min 0.5*x'*H*x + f'*x   subject to:  A*x <= b, Aeq*x = beq
%             x
%
%   lb and ub are a set of lower and upper bounds on the design variables,
%   x, so that the solution is in the range lb <= x <= ub. Use empty
%   matrices for any of the arguments. Set lb(i) = -1e20 if x(i) has no
%   lower limit and set ub(i) = 1e20 if x(i) has no upper limit. x0 is
%   the initial guess and starting point to x. This is similar to the
%   Matlab quadprog solver but uses different solvers such as IPOPT,
%   APOPT, and BPOPT to solve the QP. Additional nonlinear constraints
%   can be added to the qp.apm model for nonlinear programming solution
%   with support for possible mixed-integer variables.
%
%   The solution is returned in the structure y with y.names (variable
%   names), y.values (variable values), y.nvar (number of variables),
%   and y.x (a structure containing each variable and value).
%
%   Example usage is below:
%
% clear all; close all; clc
% disp('APM MATLAB available for download at http://apmonitor.com')
% addpath('apm')
%
% %% example Quadratic program
% H = [1 -1; -1 2];
% f = [-2; -6];
% A = [1 1; -1 2; 2 1];
% b = [2; 2; 3];
% Aeq = [];
% beq = [];
% lb = zeros(2,1);
% ub = [];
% x0 = [];
%
% %% generate APMonitor QP model
% y1 = apm_quadprog(H,f,A,b,Aeq,beq,lb,ub,x0);
%
% %% compare solution to quadprog (MATLAB)
% y2 = quadprog(H,f,A,b,Aeq,beq,lb,ub,x0)
%
% disp('Validate Results with MATLAB linprog')
% for i = 1:nx,
%     disp(['x[' int2str(i) ']: ' num2str(y1.values(i)) ' = ' num2str(y2(i))])
% end

% filename to write
filename = ['qp.apm'];

% extract H and f in sparse form
if ~isempty(H),
    [mH,nH] = size(H);
    if (mH~=nH),
        error('H must be a square matrix');
    end
    if isempty(f),
        f = zeros(mH,1);
        mf = mH;
    else
        if size(f,1)==1,
            f = f';
        end
        [mf,nf] = size(f);
    end
    if (mH~=mf),
        error('Rows of H and f must agree');
    end

    % convert to sparse form
    [hi,hj,hv] = find(sparse(H));
    h = [hi,hj,hv]';
    [fi,fj,fv] = find(sparse(f));
    f = [fi,fj,fv]';
    if(size(f,2)==0),
        f = [1,1,0]';
    end
    fr = [f(1,:); f(3,:)];
end

% extract A and b in sparse form
if ~isempty(A),
    [mA,nA] = size(A);
    if isempty(b),
        b = zeros(mA,1);
        mB = mA;
    else
        if size(b,1)==1,
            b = b';
        end
        [mB,nB] = size(b);
    end
    if (mA~=mB),
        error('Rows of A and b must agree');
    end

    % convert to sparse form
    [ai,aj,av] = find(sparse(A));
    if (mA==1),
        a = [ai;aj;av];
    else
        a = [ai,aj,av]';
    end
    [bi,bj,bv] = find(sparse(b));
    b = [bi,bj,bv]';
    if(size(b,2)==0),
        b = [1,1,0]';
    end
    br = [b(1,:); b(3,:)];
end

% extract Aeq and beq in sparse form
if ~isempty(Aeq),
    [mAeq,nAeq] = size(Aeq);
    if isempty(beq),
        beq = zeros(mAeq,1);
        mBeq = mAeq;
    else
        if size(beq,1)==1,
            beq = beq';
        end
        [mBeq,nBeq] = size(beq);
    end
    if (mAeq~=mBeq),
        error('Rows of Aeq and beq must agree');
    end

    % convert to sparse form
    [aeqi,aeqj,aeqv] = find(sparse(Aeq));
    if (mAeq==1),
        aeq = [aeqi;aeqj;aeqv];
    else
        aeq = [aeqi,aeqj,aeqv]';
    end
    [beqi,beqj,beqv] = find(sparse(beq));
    beq = [beqi,beqj,beqv]';
    if(size(beq,2)==0),
        beq = [1,1,0]';
    end
    beqr = [beq(1,:); beq(3,:)];
end

disp('Creating Quadratic Programming Model qp.apm');
fid = fopen(filename,'w');
fprintf( fid,'\n');
fprintf( fid,'Objects \n');
if ~isempty(H),
    fprintf( fid,[' h = qobj\n']);
end
if ~isempty(A),
    fprintf( fid,[' a = axb\n']);
end
if ~isempty(Aeq),
    fprintf( fid,[' aeq = axb\n']);
end
fprintf( fid,'End Objects \n');
fprintf( fid,'\n');
fprintf( fid,'Connections\n');
sz = -1;
if ~isempty(H),
    fprintf( fid,['  x[1:%d] = h.x[1:%d]\n'],nH,nH);
    sz = nH;
end
if ~isempty(A),
    fprintf( fid,['  x[1:%d] = a.x[1:%d]\n'],nA,nA);
    if (sz>=0),
        if (nA~=sz),
            error('Variables in Ax < b model must be consistent');
        end
    end
end
if ~isempty(Aeq),
    fprintf( fid,['  x[1:%d] = aeq.x[1:%d]\n'],nAeq,nAeq);
    if (sz>=0),
        if (nAeq~=sz),
            error('Variables in Ax = b model must be consistent');
        end
    end
end
fprintf( fid,'End Connections\n');
fprintf( fid,'\n');
fprintf( fid,'Model \n');
fprintf( fid,'  Variables \n');
if (isempty(x0)&&isempty(lb)&&isempty(ub)),
    % default initial conditions
    fprintf( fid,'    x[1:%d] = 0\n',nH);
else
    % create default values
    if (isempty(x0)),
        x0 = zeros(nH,1);
    end
    if (isempty(lb)),
        lb = -1e10 * ones(nH,1);
    end
    if (isempty(ub)),
        ub = 1e10 * ones(nH,1);
    end
    % generate initial conditions and bounds
    for i = 1:nH,
        fprintf( fid,'    x[%i] > %d = %d < %d\n',i,lb(i),x0(i),ub(i));
    end
end
fprintf( fid,'  End Variables \n');
fprintf( fid,'\n');
fprintf( fid,'  Equations \n');
fprintf( fid,'    ! add any additional equations here \n');
fprintf( fid,'  End Equations \n');
fprintf( fid,'End Model \n');
fprintf( fid,'\n');

if ~isempty(H),
    fprintf( fid,'\n');
    fprintf( fid,['File h.txt\n']);
    fprintf( fid,['  sparse, minimize  ! dense or sparse, minimize or maximize\n']);
    fprintf( fid,'  %d      ! n=number of variables \n',mH);
    fprintf( fid,'End File\n');
    fprintf( fid,'\n');
    fprintf( fid,['File h.a.txt \n']);
    fprintf( fid,'   %d %d %f\n', h );
    fprintf( fid,'End File \n');
    fprintf( fid,'\n');
    fprintf( fid,['File h.b.txt \n']);
    fprintf( fid,'   %d %f\n', fr );
    fprintf( fid,'End File \n');
end

if ~isempty(A),
    fprintf( fid,'\n');
    fprintf( fid,['File a.txt\n']);
    fprintf( fid,['  sparse, Ax<b \n']);
    fprintf( fid,'  %d      ! m=number of rows in A and b \n',mA);
    fprintf( fid,'  %d      ! n=number of columns in A or variables x\n',nA);
    fprintf( fid,'End File\n');
    fprintf( fid,'\n');
    fprintf( fid,['File a.a.txt \n']);
    fprintf( fid,'   %d %d %f\n', a );
    fprintf( fid,'End File \n');
    fprintf( fid,'\n');
    fprintf( fid,['File a.b.txt \n']);
    fprintf( fid,'   %d %f\n', br );
    fprintf( fid,'End File \n');
end

if ~isempty(Aeq),
    fprintf( fid,'\n');
    fprintf( fid,['File aeq.txt\n']);
    fprintf( fid,['  sparse, Ax=b \n']);
    fprintf( fid,'  %d      ! m=number of rows in A and b \n',mAeq);
    fprintf( fid,'  %d      ! n=number of columns in A or variables x\n',nAeq);
    fprintf( fid,'End File\n');
    fprintf( fid,'\n');
    fprintf( fid,['File aeq.a.txt \n']);
    fprintf( fid,'   %d %d %f\n', aeq );
    fprintf( fid,'End File \n');
    fprintf( fid,'\n');
    fprintf( fid,['File aeq.b.txt \n']);
    fprintf( fid,'   %d %f\n', beqr );
    fprintf( fid,'End File \n');
end
fclose(fid);

disp('Solving Quadratic Programming Model qp.apm');
s = 'http://xps.apmonitor.com';
a = 'qp';
apm(s,a,'clear all');
apm_load(s,a,'qp.apm');
% select solver (1=APOPT,2=BPOPT,3=IPOPT)
apm_option(s,a,'nlc.solver',1);
output = apm(s,a,'solve');
disp(output);

% return solution
y = apm_sol(s,a);

end


function b = r8ci_mxv ( n, a, x )

%*****************************************************************************80
%
%% R8CI_MXV multiplies a R8CI matrix times a vector.
%
%  Discussion:
%
%    The R8CI storage format is used for an N by N circulant matrix.
%    An N by N circulant matrix A has the property that the entries on
%    row I appear again on row I+1, shifted one position to the right,
%    with the final entry of row I appearing as the first of row I+1.
%    The format simply records the first row of the matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A(N), the R8CI matrix.
%
%    Input, real X(N), the vector to be multiplied by A.
%
%    Output, real B(N), the product A * x.
%
  for i = 1 : n
    b(i) = sum ( a(n+2-i:n) .* x(1:i-1) ) + sum ( a(1:n+1-i) .* x(i:n) );
  end

  return
end


function v = compute_crossp_vf_vf(v1,v2)

% compute_crossp_vf_vf - compute the crossproduct of 2 3D vector fields.
%
%   v = compute_crossp_vf_vf(v1,v2);
%
%   Copyright (c) 2004 Gabriel Peyre

if size(v1,3)~=3
    error('Works only for 3D vector fields.');
end

v = v1;

v(:,:,1) =  v1(:,:,2).*v2(:,:,3)-v1(:,:,3).*v2(:,:,2);
v(:,:,2) = -v1(:,:,1).*v2(:,:,3)+v1(:,:,3).*v2(:,:,1);
v(:,:,3) =  v1(:,:,1).*v2(:,:,2)-v1(:,:,2).*v2(:,:,1);


clear;

% LPV model
lpv = {...
    @(p)1      @(p)p(1);
    @(p)p(2)^2 @(p)p(1)^2+p(2);
};
% number of states (size of the A matrix)
n = 4;
% parameter dependencies:
% dep(i,j,k) is 1 if Sp{i,j} depends on p(k)
dep = zeros([size(lpv) 2]);
dep(1,2,:) = [1 0];
dep(2,1,:) = [0 1];
dep(2,2,:) = [1 1];

% sampling intervals for each parameter
domain = [-5 5; -5 5];
% grid size: number of grid points for each parameter
gridsize = [11 11];

% hosvd_lpv
D1 = sampling_lpv(lpv, dep, domain, gridsize);
[S1 U1] = hosvd_lpv(D1, dep, gridsize);

% hosvd of a full array
f = @(p) [lpv{1,1}(p) lpv{1,2}(p); lpv{2,1}(p) lpv{2,2}(p)];
D2 = sampling_vec(f, domain, gridsize);
[S2 U2] = hosvd(D2, [1 1 0 0], 0.01);

% signs in U and S might be different
Sdiff = abs(S1(:)) - abs(S2(:));

% should be small
disp ' '
disp 'error (should be small):'
disp(norm(Sdiff))


function [ X ] = hyperFcls( M, U )
%HYPERFCLS Performs fully constrained least squares on pixels of M.
% hyperFcls performs fully constrained least squares of each pixel in M
% using the endmember signatures of U.  Fully constrained least squares
% is least squares with the abundance sum-to-one constraint (ASC) and the
% abundance nonnegative constraint (ANC).
%
% Usage
%   [ X ] = hyperFcls( M, U )
% Inputs
%   M - HSI data matrix (p x N)
%   U - Matrix of endmembers (p x q)
% Outputs
%   X - Abundance maps (q x N)
%
% References
%   "Fully Constrained Least-Squares Based Linear Unmixing." Daniel Heinz,
% Chein-I Chang, and Mark L.G. Althouse. IEEE. 1999.
%
% Written by
%    Matlab Hyperspectral Toolbox - Toolbox of advanced algorithms for
%    hyperspectral processing and exploitation.
%    http://sourceforge.net/apps/mediawiki/matlabhyperspec/index.php?title=Main_Page.
%    Toolbox Available at http://sourceforge.net/projects/matlabhyperspec/.

if (ndims(U) ~= 2)
    error('M must be a p x q matrix.');
end

[p1, N] = size(M);
[p2, q] = size(U);
if (p1 ~= p2)
    error('M and U must have the same number of spectral bands.');
end

p = p1;
X = zeros(q, N);
Mbckp = U;
for n1 = 1:N
    count = q;
    done = 0;
    ref = 1:q;
    r = M(:, n1);
    U = Mbckp;
    while not(done)
        als_hat = inv(U.'*U)*U.'*r;
        s = inv(U.'*U)*ones(count, 1);

        % IEEE Magazine method (http://www.planetary.brown.edu/pdfs/3096.pdf)
        % Contains correction to sign.  Error in original paper.
        afcls_hat = als_hat - inv(U.'*U)*ones(count, 1)*inv(ones(1, count)*inv(U.'*U)*ones(count, 1))*(ones(1, count)*als_hat-1);

        % See if all components are positive.  If so, then stop.
        if (sum(afcls_hat>0) == count)
            alpha = zeros(q, 1);
            alpha(ref) = afcls_hat;
            break;
        end
        % Multiply negative elements by their counterpart in the s vector.
        % Find largest abs(a_ij, s_ij) and remove entry from alpha.
        idx = find(afcls_hat<0);
        afcls_hat(idx) = afcls_hat(idx) ./ s(idx);
        [val, maxIdx] = max(abs(afcls_hat(idx)));
        maxIdx = idx(maxIdx);
        alpha(maxIdx) = 0;
        keep = setdiff(1:size(U, 2), maxIdx);
        U = U(:, keep);
        count = count - 1;
        ref = ref(keep);
    end
    X(:, n1) = alpha;
end

return;


%UDC Uncorrelated normal based quadratic Bayes classifier (BayesNormal_U)
%
%  W = UDC(A)
%  W = A*UDC
%
% INPUT
%  A  input dataset
%
% OUTPUT
%  W   output mapping
%
% DESCRIPTION
% Computation a quadratic classifier between the classes in the
% dataset A assuming normal densities with uncorrelated features.
%
% The use of probabilistic labels is supported.  The classification A*W is
% computed by normal_map.
%
% EXAMPLES
% PREX_DENSITY
%
% SEE ALSO (PRTools Guide)
% MAPPINGS, DATASETS, NMC, NMSC, LDC, QDC, QUADRC, NORMAL_MAP

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

% $Id: udc.m,v 1.6 2007/06/05 12:45:44 duin Exp $

function W = udc(a)

	if nargin == 0
		W = prmapping(mfilename);
		W = setname(W,'Bayes-Normal-U');
		return
	end

	islabtype(a,'crisp','soft');
	isvaldfile(a,2,2); % at least 2 objects per class, 2 classes
	[m,k,c] = getsize(a);

	[U,G] = meancov(a); %computing mean and covariance matrix
	p = getprior(a);
	for j = 1:c
		G(:,:,j) = diag(diag(G(:,:,j)));
	end
	w.mean = +U;
	w.cov = G;
	w.prior = p;
	%W = prmapping('normal_map','trained',w,getlab(U),k,c);
	W = normal_map(w,getlab(U),k,c);
	W = setname(W,'Bayes-Normal-U');
	W = setcost(W,a);

return


function output = precision(tp,fp)
%
%
% Precision = tp/(tp+fp)
% (see page 268 of Manning and Schutze)
%
% Inputs
%    tp: True Positive
%    fp: False Positive
% Outputs
%    precision measure

output = tp/(tp+fp);

end


% DEMO  --  Chebyshev Polynomial Multivariate Interpolation
% UPDATED  --  October 28, 2013
% Written by Matthew Kelly, Cornell University
%
% This script demonstrates how to approximate a multivariable function with
% a chebyshev polynomial interpolant. Here we use it to approximate the
% position and velocity of a simple harmonic oscillator.
%

%What order chebyshev polynomial to use?
order = 25;

%set up the time span for the system integration using ode45
tspan = [0,1];
nTime = 1001;

%Initial conditions for the simple harmonic oscillator
z0 = [0.25;0];   %[Position, Velocity]

%Physical parameters for the simple harmonic osciallator
P.m = 0.1;
P.c = 0.4;
P.k = 100;

%Function handle for the simple harmonic oscillator
userFunc = @(t,z)simpleHarmonicOscillator(z,P);

%Use ode45 to get the solution
Options = odeset(...
    'RelTol',1e-10,...   %ode45 complains if reltol is much smaller
    'AbsTol',1e-10);
sol = ode45(userFunc,tspan,z0,Options);

%Get the "exact" solution at each point in tspan
time = linspace(tspan(1),tspan(2),nTime);
z = deval(sol,time);
pos = z(1,:);
vel = z(2,:);

%Plot ode45 stuff
figure(404); clf
subplot(2,1,1); hold on
    plot(time,pos,'r-','LineWidth',2)
    title('Position')
    xlabel('Time')
    ylabel('Position')
subplot(2,1,2); hold on
    plot(time,vel,'r-','LineWidth',2)
    title('Velocity')
    xlabel('Time')
    ylabel('Velocity')

%% Chebyshev Stuff

IO.input = time;
IO.output = z;

%Check the grid points
[f,d,x] = chebyshevFit(IO, order);
subplot(2,1,1);
    plot(x,f(1,:),'ko','MarkerSize',7,'LineWidth',1)
subplot(2,1,2);
    plot(x,f(2,:),'ko','MarkerSize',7,'LineWidth',1)

%Check the interpolation
tic
y = chebyshevInterpolate(f,time,d);
toc
posCheck = y(1,:);
velCheck = y(2,:);

%Plots for the chebyshev interpolant
subplot(2,1,1);
    plot(time,posCheck,'k:','LineWidth',1)
    legend('ode45','chebPts','cheb-pos')
subplot(2,1,2);
    plot(time,velCheck,'k:','LineWidth',1)
legend('ode45','chebPts','cheb-vel')


classdef linear_svm
% This file defines l2-regularized SVM problem
%
% Inputs:
%       x_train     train data matrix of x of size dxn.
%       y_train     train data vector of y of size 1xn.
%       x_test      test data matrix of x of size dxn.
%       y_test      test data vector of y of size 1xn.
%       lambda      l2-regularized parameter.
% Output:
%       Problem     problem instance.
%
%
% The problem of interest is defined as
%
%           min f(w) = 1/n * sum_i^n f_i(w),
%           where
%           f_i(w) = 1/2 * (max(0.0, 1 - y_i .* (w'*x_i) )^2 + lambda/2 * w^2.
%
% "w" is the model parameter of size d vector.
%
%
% This file is part of GDLibrary and SGDLibrary.
%
% Created by H.Kasai on Feb. 17, 2016
% Modified by H.Kasai on Mar. 23, 2018

    properties
        name;
        dim;
        samples;
        lambda;
        classes;
        hessain_w_independent;
        d;
        n_train;
        n_test;
        x_train;
        y_train;
        x_test;
        y_test;
        x_norm;
        x;
    end

    methods
        function obj = linear_svm(x_train, y_train, x_test, y_test, varargin)

            obj.x_train = x_train;
            obj.y_train = y_train;
            obj.x_test = x_test;
            obj.y_test = y_test;

            if nargin < 5
                obj.lambda = 0.1;
            else
                obj.lambda = varargin{1};
            end

            obj.d = size(x_train, 1);
            obj.n_train = length(y_train);
            obj.n_test = length(y_test);

            obj.name = 'linear_svm';
            obj.dim = obj.d;
            obj.samples = obj.n_train;
            obj.classes = 2;
            obj.hessain_w_independent = false;
            obj.x_norm = sum(obj.x_train.^2,1);
            obj.x = obj.x_train;
        end

        function f = cost(obj, w)

            f_sum = 0.5 * sum(max(0.0, 1 - obj.y_train' .*(w'*obj.x_train)').^2);
            f = f_sum/obj.n_train + obj.lambda/2 * w(:)'*w(:);

        end

        function g = grad(obj, w, indices)

            alpha = w' * obj.x_train(:,indices);
            flag = obj.y_train(indices) .* alpha;
            flag(flag<1.0) = 1;
            flag(flag>1.0) = 0;

            coeff = flag' .* (1 - obj.y_train(indices)' .* alpha') .* obj.y_train(indices)';
            coeff = coeff';
            coeff = repmat(coeff,[obj.d 1]);
            g = obj.lambda * w - sum(coeff .* obj.x_train(:,indices),2)/length(indices);

        end

        function g = full_grad(obj, w)

            g = obj.grad(w, 1:obj.n_train);

        end

        function h = hess(obj, w, indices)

            alpha = w' * obj.x_train(:,indices);
            flag = obj.y_train(indices) .* alpha;
            flag_indices = flag<1.0;

            x_part_new = obj.x_train(:,indices);
            x_part_new = x_part_new(:,flag_indices);

            h = obj.lambda * eye(obj.d) + x_part_new * x_part_new'/length(indices);
        end

        function hv = hess_vec(obj, w, v, indices)

            alpha = w' * obj.x_train(:,indices);
            flag = obj.y_train(indices) .* alpha;
            flag_indices = flag<1.0;

            x_part_new = obj.x_train(:,indices);
            x_part_new = x_part_new(:,flag_indices);

            hv = obj.lambda * v + (x_part_new * (x_part_new'*v) )/length(indices);
        end

        function p = prediction(obj, w)

            p = w' * obj.x_test;

            class1_idx = p>0;
            class2_idx = p<=0;
            p(class1_idx) = 1;
            p(class2_idx) = -1;

        end

        function a = accuracy(obj, y_pred)

            a = sum(y_pred == obj.y_test) / obj.n_test;

        end

        function w_opt = calc_solution(obj, maxiter, method)

            if nargin < 3
                method = 'lbfgs';
            end

            options.max_iter = maxiter;
            options.verbose = true;
            options.tol_optgap = 1.0e-24;
            options.tol_gnorm = 1.0e-16;
            options.step_alg = 'backtracking';

            if strcmp(method, 'sd')
                [w_opt,~] = sd(obj, options);
            elseif strcmp(method, 'cg')
                [w_opt,~] = ncg(obj, options);
            elseif strcmp(method, 'newton')
                options.sub_mode = 'INEXACT';
                options.step_alg = 'non-backtracking';
                [w_opt,~] = newton(obj, options);
            else
                options.step_alg = 'backtracking';
                options.mem_size = 5;
                [w_opt,~] = lbfgs(obj, options);
            end
        end
    end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Author: Eugenio Alcala Baselga
% Date: 02/06/2018
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [ A, B ] = A_OL_KINEMATIC_3VARS_DISCRETE( vd, omega, theta_Err, Ts )

    A3by3 = [1        omega*Ts   0;
            -omega*Ts   1     vd*(sin(theta_Err)/theta_Err)*Ts;
             0          0     1];

    B3by2 = [-Ts 0;
              0 0;
              0 -Ts];
    A = A3by3;
    B = B3by2;
end


%LAPLACIAN  Calculates the Laplacian of an image
%
%     dst = cv.Laplacian(src)
%     dst = cv.Laplacian(..., 'OptionName', optionValue, ...)
%
% ## Input
% * __src__ Source image.
%
% ## Output
% * __dst__ Destination image of the same size and the same number of channels
%   as `src`.
%
% ## Options
% * __DDepth__ Desired depth of the destination image. default -1, which uses
%   the same type as the input `src`.
% * __KSize__ Aperture size used to compute the second-derivative filters. See
%   cv.getDerivKernels for details. The size must be positive and odd.
%   default 1
% * __Scale__ Optional scale factor for the computed Laplacian values. By
%   default, no scaling is applied. See cv.getDerivKernels for details.
%   default 1
% * __Delta__ Optional delta value that is added to the results prior to
%   storing them in `dst`. default 0
% * __BorderType__ Pixel extrapolation method, see cv.copyMakeBorder.
%   Default 'Default'
%
% The function calculates the Laplacian of the source image by adding up the
% second x and y derivatives calculated using the Sobel operator:
%
%     dst = \Delta src = d^2(src)/dx^2 + d^2(src)/dy^2
%
% This is done when `KSize > 1`. When `KSize = 1`, the Laplacian is computed
% by filtering the image with the following 3x3 aperture:
%
%     [0, 1, 0; 1,-4, 1; 0, 1, 0]
%
% See also: cv.Sobel, cv.Scharr, imfilter, fspecial
%


% HISTWC  Weighted histogram count given number of bins
%
% This function generates a vector of cumulative weights for data
% histogram. Equal number of bins will be considered using minimum and
% maximum values of the data. Weights will be summed in the given bin.
%
% Usage: [histw, vinterval] = histwc(vv, ww, nbins)
%
% Arguments:
%       vv    - values as a vector
%       ww    - weights as a vector
%       nbins - number of bins
%
% Returns:
%       histw     - weighted histogram
%       vinterval - intervals used
%
%
%
% See also: HISTC, HISTWCV

% Author:
% mehmet.suzen physics org
% BSD License
% July 2013

function [histw, vinterval] = histwc(vv, ww, nbins)
  minV  = min(vv);
  maxV  = max(vv);
  delta = (maxV-minV)/nbins;
  vinterval = linspace(minV, maxV, nbins)-delta/2.0;
  histw = zeros(nbins, 1);
  for i=1:length(vv)
    ind = find(vinterval < vv(i), 1, 'last' );
    if ~isempty(ind)
      histw(ind) = histw(ind) + ww(i);
    end
  end
end


function dist = imDistance(varargin)
%IMDISTANCE Distance map computed from a set of points
%
%   DIST = imDistance(DIM, POINTS);
%   Create a distance map of the point given by POINTS, in the image with
%   size given by DIM = [NY NX].
%   POINTS is a N-by-2 array of double containing point coordinates
%
%   DIST = imDistance(LX, LY, POINTS)
%   Specify the position of vertices along each axis. See meshgrid for
%   details.
%
%   DIST = imDistance(..., N)
%   Use N point randomly and independently created inside the image bounds.
%
%   DIST = imDistance(..., EDGE)
%   Also specify edge condition. EDGE can be one of:
%   - 'free': regions touching image borders are removed
%   - 'periodic': copy the set of points to simulate periodic set
%   - 'remove': image edges will be set to distance 0, and neighbor pixels
%       set accordingly.
%
%   TODO: manage different types of distance (now is only euclidian).
%
%   Example
%   % basic example with integer coordinates
%     img = imDistance([100 100], [10 10;90 90;90 10;10 90;50 50]);
%     imshow(img, [0 max(img(:))]);
%
%   % specify floating coordinates, with periodic edge conditions
%     lx = 1:100;
%     ly = 1:100;
%     pts = [10.2 10.3;90.4 90.5; 10.8 90.8;50.1 50.0]
%     img = imDistance(lx, ly, pts, 'periodic');
%     figure; imshow(img, [0 max(img(:))]);
%

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

%   HISTORY
%   28/06/2004 use faster algorithm
%   22/05/2006 allocate d1 and d2 only once (should be faster)
%   29/05/2009 add possibility to specify grid with meshgrid-like syntax

%% Extract input arguments

% default parameters values
points      = [];       % points array
N           = 20;       % default number of germs
edgecond    = 'free';   % edge condition
lx = 1:100;
ly = 1:100;

% extraction of image dimensions
if ~isempty(varargin)
    var = varargin{1};
    if size(var, 1) > 1 && size(var, 2) > 2
        % case of a 2x3 matrix with starting position, increment, end
        % position for each coordinate
        lx = var(1,1):var(1,2):var(1,3);
        ly = var(2,1):var(2,2):var(2,3);
        varargin(1) = [];

    elseif size(var, 1) == 1 && size(var, 2) == 2
        % first argument contains the size of the output image
        lx = 1:var(2);
        ly = 1:var(1);
        varargin(1) = [];

    elseif length(varargin) > 1
        % first and second arguments contain vector for each coordinate
        % respectively
        lx = varargin{1};
        ly = varargin{2};
        varargin(1:2) = [];

    else
        error('wrong input arguments in imDistance');
    end
end

% extraction of points, or number of points
if ~isempty(varargin)
    var = varargin{1};

    if length(var)>1    % use an array of germs
        points = var;
    else                % get number of germs
        N = var;
    end

    varargin(1) = [];
end

% extraction of edge condition
if ~isempty(varargin)
    edgecond = varargin{1};
end

%% Initialisations

% create array of points, if does not exist
if isempty(points)
    % generation of germs array
    points = zeros(N, 2);
    for i = 1:N
        points(i,1) = rand * lx(end) + lx(1);
        points(i,2) = rand * ly(end) + ly(1);
    end
end

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

% size of output image
Nx = length(lx);
Ny = length(ly);

% create periodic conditions if needed
if strcmp(edgecond, 'periodic')
    % compute size of the box
    wx = lx(end)  + lx(2) - 2*lx(1);
    wy = ly(end)  + ly(2) - 2*ly(1);

    points = repmat(points, [9 1]);
    for i = [1 2 3]
        points((i-1)*N+1:i*N, 1) = points((i-1)*N+1:i*N, 1) - wx;
    end

    for i = [7 8 9]
        points((i-1)*N+1:i*N, 1) = points((i-1)*N+1:i*N, 1) + wx;
    end

    for i = [1 4 7]
        points((i-1)*N+1:i*N, 2) = points((i-1)*N+1:i*N, 2) - wy;
    end

    for i = [3 6 9]
        points((i-1)*N+1:i*N, 2) = points((i-1)*N+1:i*N, 2) + wy;
    end

    % re-compute number of points
    N = size(points, 1);
end

%% Generation of distance function

% allocate memory
dist = Nx * Ny * ones([Ny Nx]);

% pixels coordinates
[x, y] = meshgrid(lx, ly);

% update distance for each point
for p = 1:N
    dist = min(dist, hypot(x - points(p,1), y - points(p,2)));
end

%old algorithm, slower
%dist = zeros(dim);
%for i=1:dim(1)
    %disp (int2str(x));
    %for j=1:dim(2)
        %mat = points - ones(N,1)*[i j];
        %dist(i, j) = min(sqrt(diag(mat*mat')));
        % end
    %end

%% Optional processing for borders

% distance from borders of image
if strcmp(edgecond, 'remove')
    d1 = min(repmat((1:Ny)'-1, [1 Nx]), repmat((Ny:-1:1)'-1, [1 Nx]));
    dist = min(dist, d1);
    d1 = min(repmat((1:Nx)-1,  [Ny 1]), repmat((Nx:-1:1)-1,  [Ny 1]));
    dist = min(dist, d1);
end


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

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

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

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

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

  % Compute train / val errors when training linear
  theta = trainLinearReg(X, y, lambda);

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

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

end


function [trainX, testX, minimums, ranges] = featNormalize(trainX, testX)

	minimums = min(trainX, [], 1);
	ranges = max(trainX, [], 1) - minimums + eps;
%
	trainX = (trainX - repmat(minimums, size(trainX, 1), 1)) ./ repmat(ranges, size(trainX, 1), 1);

	testX = (testX - repmat(minimums, size(testX, 1), 1)) ./ repmat(ranges, size(testX, 1), 1);

%     trainX = bsxfun(@rdivide,trainX,sqrt(sum(trainX.^2,2)));
% 	testX = bsxfun(@rdivide,testX,sqrt(sum(testX.^2,2)));
end


% Draw various graphs obtained from the same point set.
%
%   output = drawSampleGraphs(input)
%
%   Example
%   drawSampleGraphs
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% INRAE - BIA Research Unit - BIBS Platform (Nantes)
% Created: 2020-06-04,    using Matlab 9.8.0.1323502 (R2020a)
% Copyright 2020 INRAE.

%% Read input points

% read a set of 16 points within a [10 28]^2 bounding box
pts = load('sedgewick_points.txt');

% display the sample points
figure; axis equal; axis([10 28 10 28]); hold on;
drawPoint(pts, 'bo');
title('Sample points');

%% Delaunay Graph

% compute the graph
[nodes, edges] = delaunayGraph(pts);

% display the sample points
figure; axis equal; axis([10 28 10 28]); hold on;
drawPoint(pts, 'bo');

% display the graph
drawGraphEdges(nodes, edges);
title('Delaunay Graph');

%% Minimal Spanning Tree

% compute the graph
edges = euclideanMST(pts);

% display the sample points
figure; axis equal; axis([10 28 10 28]); hold on;
drawPoint(pts, 'bo');

% display the graph
drawGraphEdges(pts, edges);
title('Minimal Spanning Tree');

%% Relative Neighborhood Graph

% compute the graph
edges = relativeNeighborhoodGraph(pts);

% display the sample points
figure; axis equal; axis([10 28 10 28]); hold on;
drawPoint(pts, 'bo');

% display the graph
drawGraphEdges(pts, edges);
title('Relative Neighborhood Graph');

%% Gabriel Graph

% compute the graph
edges = gabrielGraph(pts);

% display the sample points
figure; axis equal; axis([10 28 10 28]); hold on;
drawPoint(pts, 'bo');

% display the graph
drawGraphEdges(pts, edges);
title('Gabriel Graph');


function [fx,dF_dX,dF_dTheta] = f_doubleWell(Xt,Theta,ut,inF)
% damped double Well Lyapunov evolution function
% function [f,J] = f_doubleWell(t,x,theta)
%
% This function computes the evolution function that comes from a .
% IN:
%   - t: time index (not used here)
%   - x: the current state of the system
%   - theta: a 2x1 vector parameter (containing the position of the two
%   wells.
% OUT:
%   - f: the current value of the evolution function
%   - J: the jacobbian of the system

deltat = inF.deltat;

a   = Theta(1);
b   = Theta(2);
k   = Theta(3);
x1  = Xt(1);
x2  = Xt(2);

f   = [ x2  ;  -2*(x1-a)*(x1-b)^2-2*(x1-a)^2*(x1-b)-k.*x2 ];
J   = [ 0                                               1
        -2*(x1-b)^2-8*(x1-a)*(x1-b)-2*(x1-a)^2        -k ];

fx                  = deltat.*f + Xt;
dF_dX               = deltat.*J' + eye(2);
dF_dTheta           = deltat.*[ 0 2*(x1-b)^2+4*(x1-a)*(x1-b)
                                0 4*(x1-a)*(x1-b)+2*(x1-a)^2
                                0 -x2                        ];


function Speciation
% Speciation
%    using MATLAB
%
%   $Ekkehard Holzbecher  $Date: 2006/05/03 $
%--------------------------------------------------------------------------
toll = 1.e-15;                    % tolerance
nmax = 50;                        % max. no. of iterations
Se = [-1 -1 1];                   % reaction matrix
logc = [1.e-10; 1.e-10; 0];       % initial guess (log)
logK = [-0.93];                   % equilibrium constants (log)
logu = [-0.301; 0];               % total concentrations (log)

ln10 = 2.3026;
n=size(Se,1); m=size(Se,2);
S1 = Se(:,1:m-n);
S2 = Se(:,m-n+1:m);
S1star = -S2\S1;
U = [eye(m-n),S1star'];

c=exp(ln10*logc);
u(1:m-n,1) = exp(ln10*logu);
err = toll+1; nit = 0;
while (nit < nmax & err > toll),
    nit = nit+1;
    F = [U*c-u; Se*log10(c)-logK];
    DF = [U; Se*diag((1/ln10)./c)];
    dc = -DF\F;
    cn = max(c+dc,0.005*abs(c));
    err = max(abs(cn-c));
    c = cn;
    logc = log10(c);
end
display (['Species concentrations obtained after ' num2str(nit) ' iterations:']);
c
exp(ln10*logK)-c(3)/c(1)/c(2)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: this function mimics the movement of the simulation for target
%           points based on an angular movement
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function test_Rotations()

angVec = 0:0.05:4*pi;

for i=1:length(angVec)

    % Declare how open you want the movements to go
    full_ang = pi/3;
    dbl_ang = 2*full_ang;

    % Find associated angle
    ang1 = mod( angVec(i), dbl_ang );
    if ( (ang1 > full_ang ) && (ang1 <= dbl_ang) )
        ang1 = dbl_ang-ang1;
    end

    ang2 = mod( angVec(i), dbl_ang );
    if ( (ang2 > full_ang ) && (ang2 <= dbl_ang) )
        ang2 = dbl_ang-ang2;
    end

    % Read In Pts!
    [xRef,yRef] = read_File_In('corals.vertex');

    plot(xRef,yRef,'b*'); hold on;
    axis([0 1 0 1]);

    % Store Left/Right Points
    xL_Ref = xRef(1:end/2);     yL_Ref = yRef(1:end/2);
    xR_Ref = xRef(end/2+1:end); yR_Ref = yRef(end/2+1:end);

    % Store Values for Centers of Rotation
    %xL = xRef(1);       yL = yRef(1);
    %xR = xRef(end/2+1); yR = yRef(end/2+1);

    % Rotate Geometry
    %[xR_Ref,yR_Ref] = rotate_Geometry(-ang,xR,yR,xR_Ref,yR_Ref);
    %[xL_Ref,yL_Ref] = rotate_Geometry(ang,xL,yL,xL_Ref,yL_Ref);

    % Store Values for Centers of Rotation
    xL_1 = xRef(1);       yL_1 = yRef(1);           % Left side of Left Pair
    xR_1 = xRef(end/4+1); yR_1 = yRef(end/4+1);     % Right side of Left Pair

    xL_2 = xRef(end/2+1);   yL_2 = yRef(end/2+1);   % Left side of Right Pair
    xR_2 = xRef(3*end/4+1); yR_2 = yRef(3*end/4+1); % Right side of Right Pair

    % -> Rotate Geometry <- %
    % LEFT PAIR %
    [xR_Ref_1,yR_Ref_1] = rotate_Geometry(-ang1,xR_1,yR_1,xRef(end/4+1:end/2),yRef(end/4+1:end/2) );
    [xL_Ref_1,yL_Ref_1] = rotate_Geometry(ang1,xL_1,yL_1,xRef(1:end/4),yRef(1:end/4) );
    % RIGHT PAIR %
    [xR_Ref_2,yR_Ref_2] = rotate_Geometry(-ang2,xR_2,yR_2,xRef(3*end/4+1:end),yRef(3*end/4+1:end) );
    [xL_Ref_2,yL_Ref_2] = rotate_Geometry(ang2,xL_2,yL_2,xRef(end/2+1:3*end/4),yRef(end/2+1:3*end/4) );

    % Store New Geometry
    xRef2 = [xL_Ref_1 xR_Ref_1 xR_Ref_2 xL_Ref_2];
    yRef2 = [yL_Ref_1 yR_Ref_1 yR_Ref_2 yL_Ref_2];

    plot(xRef2,yRef2,'k*'); hold on;
    axis([0 1 0 1]);
    pause(0.01);
    clf;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: rotate geometry
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [x,y] = rotate_Geometry(ang,xC,yC,xRef,yRef)

len = length(xRef);
x = zeros(1,len); y=x;

xRef = xRef - xC;
yRef = yRef - yC;

for i=1:len
   x(i) =  xRef(i)*cos(ang) - yRef(i)*sin(ang);
   y(i) =  xRef(i)*sin(ang) + yRef(i)*cos(ang);
end

x = x + xC;
y = y + yC;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: reads in info from file
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [x1,y1] = read_File_In(file_name)

filename = file_name;  %Name of file to read in

fileID = fopen(filename);

    % Read in the file, use 'CollectOutput' to gather all similar data together
    % and 'CommentStyle' to to end and be able to skip lines in file.
    C = textscan(fileID,'%f %f','CollectOutput',1);

fclose(fileID);        %Close the data file.

mat_info = C{1};   %Stores all read in data

%Store all elements in matrix
mat = mat_info(2:end,1:end);

x1 =  mat(:,1); %store xVals
y1 =  mat(:,2); %store yVals


function Ri = get_Ri(r_i, theta_i, sigma_r, sigma_theta)
% computes the covariance of the point p_i = r_i*[cos(theta_i); sin(theta_i)
% in cartesian coordinates

% first we compute the matrix square root of R, which consists of the
% Jacobian * sqrt(R_in_polar_coords)
Ri = [cos(theta_i) -r_i*sin(theta_i)
      sin(theta_i)  r_i*cos(theta_i) ] * diag([sigma_r sigma_theta]);

% and then we get the entire Ri
Ri = Ri * Ri';


function [beta_gibbs sigma_gibbs]=dogibbs(It,Bu,Bcap,phicap,Scap,alphacap,alphatop,n,k)

% start iterations
for ii=1:It-Bu

% draw B from a matrix-variate student distribution with location Bcap, scale Scap and phicap and degrees of freedom alphatop
B=bear.matrixtdraw(Bcap,Scap,phicap,alphatop,k,n);

% then draw sigma from an inverse Wishart distribution with scale matrix Scap and degrees of freedom alphacap (step 3)
sigma=bear.iwdraw(Scap,alphacap);

% record values before starting next iteration
beta_gibbs(:,ii)=B(:);
sigma_gibbs(:,ii)=sigma(:);

% go for next iteration
end


function fz = trifunc (z)

% triaxial objective function

% input

%  z = function argument

% output

%  fz = function value at z

% Orbital Mechanics with Matlab

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

global cx cy cz vcon ucon caxis

den1 = (cz + vcon * z) ^ 2;

den2 = (cz + ucon * z) ^ 2;

fz = (1.0 + (cy / den1) + (cx / den2)) * z ^ 2 - caxis ^ 2;


% fig_taper_cos3
% compare 3 different interpolation kernels:
%	min-max kernel with uniform scaling factors
%	min-max kernel with optimized scaling factors
%	cos^3-tapered dirichlet kernel of magnusson

J = 6;
N = 1000;
K = 2 * N;
k = linspace(-J/2,J/2,101)';
fm = diric(2*pi*k/J, J) .* cos((2*pi*k/J)/2).^3;	% tapered
fn = nufft1_kernel(k, N, J, K, 1, 0);			% min-max unif
fo = nufft1_kernel(k, N, J, K, 'best');
fo = fo / max(fo);

%fm = 0*fm;
%fn = nufft1_kernel(k, N, J, 9*N, 1, 0);
%fo = nufft1_kernel(k, N, J, 2*N, 1, 0);

plot(k, fn, '-', k, fm, '--', k, fo, '-.')
axisy(-0.3,1.1)
legend('min-max', 'Magnusson', 'optimized')
title(sprintf('J=%d K/N=%g', J, K/N))


function [meanMap,stdMap,TcircSq,p]=computeStatsOnComplexVectors(cVectors)
% [meanMap,stdMap]=computeStatsOnComplexVectors(cVectors)
% PURPOSE : Computes the mean and std along the 3rd dimension
%   on a 3D or 4D set of complex vectors
%   produced by getSingleCycleVectors or getSingleCycleVectorsMultipleScans
%   It's almost redundant except that if you pass in a 4D array, it
%   reshapes to a 3D array before computing the std and mean along the 3rd
%   dimension.

s=size(cVectors);
if (length(s)==4)
    cVectors=reshape(cVectors,[s(1),s(2),s(3)*s(4)]);
end
s=size(cVectors);
if (length(s)~=3)
    error('S must be a 3 or 4D array');
end

meanMap=mean(cVectors,3);
stdMap=std(cVectors,[],3);

zeroMean=cVectors-repmat(meanMap,[1,1,s(3)]);

rStd=sum(real(zeroMean).^2/s(3),3);
iStd=sum(imag(zeroMean).^2/s(3),3);

Vindiv=(rStd+iStd)/(2*(s(3)-1));

Vgroup=(s(3)/2)*(abs(meanMap).^2);
TcircSq=(1/s(3))*(Vgroup./Vindiv);
p=FTest(2,(2*s(3)-2),s(3)*TcircSq);

return


function [Xco Tau MT] = HC_explicit_nh (Tin,TC,DE,HC,SE,DI,TS,TT,TBC,BC)
%
% DESCRIPTION:
%
% Explicit numerical method for one dimensional unsteady state
% heat transfer by conduction for non-homogenous material
%
% Basic PDE equation :
%
%     dT         d^2 T
%   ------ = TD ------             for 0 < x < DI  and  tau > 0
%    dtau        dx^2
%
% Principle of method :
%       ^
%  time |
%       |      m-1     m     m+1
%       |       |      |      |
%       |    ---+------x------+-----   p+1
%       |  dtau |      |      |
%       |    ---o------o------o-----   p
%       |  dtau |      |      |
%       |    ---+------+------+-----   p-1
%       |       |  dx  |  dx  |
%       |
%       +-------------------------------->
%                                        x
% Space description:
%                  DI
%   |<------------------------------>|
%   +   +   +   +   +  . . .     +   +
%   1   2   3   4   5           n-1  n
%   |<->|
%     SE
%
% Difference equation :
%
%   T(m,p+1) - T(m,p)      TD
%  ------------------- = ------- (T(m-1,p) - 2.T(m,p) + T(m+1,p))
%          TS             SE.SE
%
%       TD.TS
%  M = -------- <= 0,5
%       SE.SE
%
%  T(m,p+1) = M.T(m-1,p) + (1 - 2.M)T(m,p) + M.T(m+1,p)
%
%  T(m,p+1) = M(m-1).T(m-1,p) + (1 - (M(m-1)+M(m)))T(m,p) + M(m).T(m+1,p)
%  for m <2;n-1>
%
%  First-type boundary condition:
%    - temperatures T(1,p) and T(n,p) are given
%    - temperatures T(m,p) for m = 2, n-1 :
%      T(m,p+1) = M (T(m-1,p) + T(m+1,p)) + T(m,p).(1 - 2.M)
%
%  Second-type boundary condition:
%    - heat flux iQ(1,p) and iQ(n,p) are given
%    - temperature T(1,p) :
%                                   SE
%      T(1,p) = T(2,p-1) - iQ(1,p) ----
%                                   TC
%    - temperature T(n,p) :
%                                       SE
%      T(end,p) = T(n-1,p-1) - iQ(n,p) ----
%                                       TC
%    - temperatures T(m,p) for m = 2, n-1 :
%      T(m,p+1) = M (T(m-1,p) + T(m+1,p)) + T(m,p).(1 - 2.M)
%
%
% INPUTS:
%
% Tin  - initialization temperatures                        [ K           ]
% TC   - thermal conductivity                               [ W.m^-1.K^-1 ]
% DE   - density                                            [ kg.m^-3     ]
% HC   - specific heat capacity                             [ kg.m^-3     ]
% SE   - size of element                                    [ m           ]
% DI   - distance                                           [ m           ]
% TS   - time step                                          [ s           ]
% TT   - total time of simulation                           [ s           ]
% TBC  - type of boundary condition
%        (1 = first-type, 2 = second-type)                  [ -           ]
% BC   - boundary condition
%         - first-type : BC(1) = T(1),  BC(2) = T(n)        [ K           ]
%         - second-type: BC(1) = iQ(1), BC(2) = iQ(n)       [ W.m^-2      ]
%
% OUTPUTS:
%
% Xco  - vector of X coordinate                             [ m           ]
% Tau  - vector of time                                     [ s           ]
% MT   - matrix of temperatures                             [ K           ]
%
% AUXILIARY VARIABLE:
%
% r    - time  step  number                                 [ -           ]
% n    - space point number                                 [ -           ]
% TD   - thermal diffusivity                                [ m^2.m^-1    ]
% M    - modul (Fourier number)                             [ -           ]
%
% Copyright (C) 2013, Technical University of Kosice
% Author  : Zecova Monika, Terpak Jan
% Revision: 27.08.2013
%
  r = round(TT/TS) + 1;
  n = round(DI/SE) + 1;

  Xco = 0.0:SE:DI;
  Tau = 0.0:TS:TT;
  MT  = zeros(r,n);
  MT(1,:) = Tin;

  for j=2:r
    [T]     = explicit_nh (Tin,TC,DE,HC,SE,TS,TBC,BC);
    Tin     = T;
    MT(j,:) = Tin;
  end

end
function [T] = explicit_nh (Tin,TC,DE,HC,SE,TS,TBC,BC)

  n  = length(Tin);
  TD = zeros(1,n-1);
  for i=1:n-1
    TD(i)= TC(i)/(DE(i)*HC(i));
  end
  M  = TD*TS/(SE*SE);

  T  = Tin;

  if (M <= 0.5)

     if TBC == 1
        T(1)   = BC(1);
        T(end) = BC(2);
     end

     if TBC == 2
        T(1)   = T(2)   - BC(1)*SE/TC(1);
        T(end) = T(end-1) - BC(2)*SE/TC(end);
     end

     for m=2:length(Tin)-1
       T(m) = M(m-1)*Tin(m-1) + (1 - (M(m-1)+M(m)))*Tin(m) + M(m)*Tin(m+1);
     end
  else
     disp(['error: unstable solution, M must be <= 0,5; M = ' num2str(M)]);
  end
end


function isInside = bst_intriangle(A, B, C, P)
% BST_INTRIANGLE: Test if the orthogonal projection of points P on a triangle (A,B,C) are inside the triangle.

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2013

% Compute vectors
v0 = repmat(C - A, size(P,1), 1);
v1 = repmat(B - A, size(P,1), 1);
v2 = bst_bsxfun(@minus, P, A);

% Compute dot products
dot00 = sum(v0.^2, 2);
dot01 = sum(v0.*v1, 2);
dot02 = sum(v0.*v2, 2);
dot11 = sum(v1.^2, 2);
dot12 = sum(v1.*v2, 2);

% Compute barycentric coordinates
invDenom = 1 ./ (dot00 .* dot11 - dot01 .* dot01);
u = (dot11 .* dot02 - dot01 .* dot12) .* invDenom;
v = (dot00 .* dot12 - dot01 .* dot02) .* invDenom;

% Check if point is in triangle
isInside = (u >= 0) & (v >= 0) & (u + v < 1);


function value = r8_si ( x )

%*****************************************************************************80
%
%% R8_SI computes an approximation to the value of the sine integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 November 2009
%
%  Author:
%
%    Original FORTRAN77 version by Wayne Fullerton.
%    MATLAB version by John Burkardt.
%
%  Parameters:
%
%    Input, real X, the argument of the sine integral.
%
%    Output, real VALUE, the value of the sine integral.
%
  nsics = 12;
  sics = [ ...
    -0.1315646598184841929, -0.2776578526973601892, ...
     0.0354414054866659180, -0.0025631631447933978, ...
     0.0001162365390497009, -0.0000035904327241606, ...
     0.0000000802342123706, -0.0000000013562997693, ...
     0.0000000000179440722, -0.0000000000001908387, ...
     0.0000000000000016670, -0.0000000000000000122 ];

  eta = 0.1 * eps;
  nsi = inits ( sics, nsics, 0.1 * eps );

  i = find ( abs ( x ) < sqrt ( eps ) );
  value(i) = x(i);

  j = find ( abs ( x ) <= 4.0 );
  value(j) = csevl ( ( x(j).^2 - 8.0 ) * 0.125, sics, nsi );
  value(j) = x(j) .* ( 0.75 + value(j) );

  k = find ( 4.0 < abs ( x ) );
  [ f, g ] = r89sifg ( abs ( x(k) ) );
  value(k) = 0.5 * pi - f .* cos ( abs ( x(k) ) ) - g .* sin ( x(k) );
  l = find ( x(k) < 0.0 );
  value(l) = - value(l);

  return
end


function result = square_unit_sum ( func, norder, xtab, ytab, weight )

%*****************************************************************************80
%
%% SQUARE_UNIT_SUM carries out a quadrature rule over the unit square.
%
%  Integration region:
%
%    Points (X,Y) such that
%
%      -1 <= X <= 1, and
%      -1 <= Y <= 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, external FUNC, the name of the function to be
%    integrated.  The user must declare the name an EXTERNAL
%    parameter in the calling program, pass the name of the
%    function in FUNC, and write a function of the form
%      function value = func ( x, y )
%    which evaluates the function at the point (X,Y).
%
%    Input, integer NORDER, the order of the rule.
%
%    Input, real XTAB(NORDER), YTAB(NORDER), the abscissas of
%    the rule.
%
%    Input, real WEIGHT(NORDER), the weights of the rule.
%
%    Output, real RESULT, the approximate integral of the function.
%
  quad = 0.0E+00;
  for i = 1 : norder
    quad = quad + weight(i) * feval ( func, xtab(i), ytab(i) ) / 4.0E+00;
  end

  volume = 1.0E+00;
  result = quad * volume;

  return
end


% NMFLAB for Signal Processing written by A. Cichocki and R. Zdunek
% in cooperation with other members of Laboratory for Advanced Brain Signal
% Processing, BSI, RIKEN, Saitama, JAPAN

function [x,grad_x,k] = nmf_proj_grad(b,A,x,tol,no_iter,beta_dec,loss_fun,beta)

% Projected Gradient Algorithm based on the Armijo rule
%
% [x, grad_x, k]=nmf_proj_grad(b,A,x,tol,no_iter,beta_dec,loss_fun,beta) finds
% such x that solves the equation Ax = b.
%
% INPUTS:
% b - data matrix of dimension [m by T]
% A - fixed matrix of dimension [m by r]
% x - initial guess
% tol - tolerance
% no_iter - maximum number of iterations
% beta_dec - multiplier of learning rate in descent gradient direction
% loss_fun - index for the loss function (1--4)
% beta - parameter "alpha" in the Amari alpha-divergence
%
% OUTPUTS:
% x - estimated matrix of dimension [r by T]
% grad_x - gradient of x
% k - number of performed iterations
%
% #########################################################################

if beta == 0
   loss_fun = 2;
end

sigma = 0.01; alpha = 1; kinc = 1;

for k=1:no_iter

 switch loss_fun

      case 1 % Frobenius

           res = b - A*x;
           grad_x = -A'*res;
           F = .5*norm(res,'fro')^2;
           lower_bound = 0;

      case 2 % KL

           bx = A*x;
           grad_x = A'*(1 - b./(bx + eps));
           F = sum(sum(b.*log(b./(bx + eps)) + bx - b));
           lower_bound = 0.1;

      case 3 % Dual KL

           bx = A*x;
           grad_x = A'*log(bx./b);
           F = sum(sum(bx.*log(bx./b) + b - bx));
           lower_bound = 1E-4;

      case 4 % Amari alpha divergence

           bx = A*x;
           grad_x = (1/beta)*A'*(1 - (b./bx).^beta);
           F = sum(sum(b.*((b./bx).^(beta - 1) - 1)/(beta^2 - beta) + (bx - b)/beta));
           lower_bound = 1E-2;

  end  % switch

  tol_grad = norm(grad_x(grad_x < lower_bound | x > lower_bound));
  if tol_grad < tol,
     break
  end

%  alpha = 1;
  s = 0;

% search step size
while (alpha > 1E-15) & (alpha < 1E8)

  s = s + 1;

  xn = max(x - alpha*grad_x,lower_bound);
  delta = xn-x;

   switch loss_fun

      case 1 % Frobenius

           Fn = .5*norm(b - A*xn,'fro')^2;

      case 2 % KL

           bx = A*xn;
           Fn = sum(sum(b.*log(b./(bx + eps)) + bx - b));

      case 3 % Dual KL

           bx = A*xn;
           Fn = sum(sum(bx.*log(bx./b) + b - bx));

      case 4 % Amari alpha divergence

           bx = A*xn;
           Fn = sum(sum(b.*((b./bx).^(beta - 1) - 1)/(beta^2 - beta) + (bx - b)/beta));

  end  % switch

  cond_alpha = ((Fn - F) <= sigma*grad_x(:)'*delta(:));

  if cond_alpha | (xn == x)
   % Increase
     if ~kinc & (s > 1), x = xn; break; end
     alpha = alpha/beta_dec;
     kinc = 1; xp = xn;
  else
   % Decrease
     if kinc & (s > 1), x = xp; alpha = alpha*beta_dec; break; end
     alpha = alpha*beta_dec;
     kinc = 0;
  end

end % while

end % for k
%


function [E1 E2] = cao_deneme(x,tao,mmax)
%x : time series
%tao : time delay
%mmax : maximum embedding dimension
%reference:Cao, L. (1997), ``Practical method for determining the minimum
%embedding dimension of a scalar time series'', Physcai D, 110, pp. 43-50.
%author:"Merve Kizilkaya"
N=length(x);
for m=1:mmax
    M=N-m*tao;
    Y=psr_deneme(x,m,tao,M);
    for n=1:M
        y0=ones(M,1)*Y(n,:);
        distance=max(abs(Y-y0),[],2);
        [neardis nearpos]=sort(distance);

        newpoint=[Y(n,:) x(n+m*tao)];
        newneig=[Y(nearpos(2),:) x(nearpos(2)+m*tao)];
        R1=max(abs(newpoint-newneig),[],2);

        a(n)=R1/neardis(2);
        d(n)=abs(x(n+m*tao)-x(nearpos(2)+m*tao));
    end
    E(m)=sum(a)/M;
    Ey(m)=sum(d)/M;
end
figure
E1=E(2:end)./E(1:end-1);
E2=Ey(2:end)./Ey(1:end-1);
plot(1:length(E1),E1,'k')
hold on
plot(1:length(E2),E2)
grid on
title('embedding dimension with cao method')
legend('E1','E2',4);

function Y=psr_deneme(x,m,tao,npoint)
%Phase space reconstruction
%x : time series
%m : embedding dimension
%tao : time delay
%npoint : total number of reconstructed vectors
%Y : M x m matrix
% author:"Merve Kizilkaya"
N=length(x);
if nargin == 4
    M=npoint;
else
    M=N-(m-1)*tao;
end

Y=zeros(M,m);

for i=1:m
    Y(:,i)=x((1:M)+(i-1)*tao)';
end