function c = correlation_cubic ( n, rho, rho0 )

%*****************************************************************************80
%
%% CORRELATION_CUBIC evaluates the cubic correlation function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 March 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Petter Abrahamsen,
%    A Review of Gaussian Random Fields and Correlation Functions,
%    Norwegian Computing Center, 1997.
%
%  Parameters:
%
%    Input, integer N, the number of arguments.
%
%    Input, real RHO(N,1), the arguments.
%
%    Input, real RHO0, the correlation length.
%
%    Output, real C(N,1), the correlations.
%
  rho = rho ( : );

  rhohat = min ( abs ( rho ) / rho0, 1.0 );

  c = 1.0 - 7.0 * rhohat.^2 + 8.75 * rhohat.^3 - 3.5 * rhohat.^5 + 0.75 * rhohat.^7;

  return
end


function X = MvnRndMatchCrossCov(S, varargin)
% X = MvnRndMatchCrossCov(S, J) simulates a panel of J scenarios of a
% multivariate normal random vector with zero sample mean and sample
% covariance exactly equal to S. Each row of X is a scenario and each
% column is a variable.
%
% X = MvnRndMatchCrossCov(S, P, F, CovF) generates a multivariate normal
% panel X with zero sample mean, sample covariance S and sample cross
% covariance P with another zero-mean panel F. CovF, the sample covariance
% of F, is computed if not provided as input.

% IMPORTANT: The order of computations in the following expressions is
% important for efficiency. Please use the same order, or have a good reason
% to change it!

% Code by S. Gollamudi. This version December 2009.

% check input
N = size(S,1);
if nargin==2,
    J = varargin{1};
    K = 0;
else
    P = varargin{1};
    F = varargin{2};
    [J,K] = size(F);
    assert(all(size(P)==[K,N]), 'Incorrect dimensions of cross-covariance P.');
    if length(varargin)<=2,
        CovF = cov(F,1);
    else
        CovF = varargin{3};
    end
    sqrtJ = sqrt(J);
end

% tolerance level
eps = 1e-9;

% Algorithm: X = F*B + V*R
% where F'*V=0, V'V=J*I and R is upper triangular

if K>0,

    % Compute B
    B = CovF \ P;

    % Compute R
    Sigma_orth = S - P'*B;
    var_orth = diag(Sigma_orth);
    var_x = diag(S);
    if any(var_orth < -eps*var_x),
        error('MvnRndMatchCrossCov: S and P are incompatible.')
    end
    i_positive = (var_orth > eps*var_x);
    num_positive = sum(i_positive);
    R = zeros(num_positive,N);
    R(:,i_positive) = chol(S(i_positive,i_positive) - P(:,i_positive)'*B(:,i_positive));

    % Generate V
    Z = randn(J/2,N);
    Z=[Z
        -Z];

    % using QR decomposition
    %[V,dummy] = qr([F Z],0);
    %V = V(:,K+1:K+num_positive)*sqrtJ;

    % using modified Gram-Schmidt
    Z = Z - (F/CovF)*((F'*Z)/J);
    V = zeros(J,0);
    for n = 1:num_positive,
        u = Z(:,n) - V*((V'*Z(:,n))/J);
        V = [V u*(sqrtJ/norm(u))];
    end

    % generate panel X
    X = F*B + V*R;

else

    % generate X to have zero sample mean and sample covariance S
    Z = randn(J/2,N);
    Z = [Z
        -Z];
    X = Z * (chol(cov(Z,1)) \ chol(S));

end


% Steady state transport solutions for one fixed value of Pe and various values of Da1
x = [0:0.01:1];
Pe = 1; Da1 = 16;
s = sqrt(0.25*Pe*Pe+Pe/Da1);
mu1 = 0.5*Pe+s; mu2 = 0.5*Pe-s;
s = mu2*exp(mu2)-mu1*exp(mu1);
c = (mu2*exp(mu2)*exp(mu1*x)-mu1*exp(mu1)*exp(mu2*x))./s;
for Da1 = [8 4 2 1 0.5 0.25 0.125];
    s = sqrt(0.25*Pe*Pe+Pe/Da1);
    mu1 = 0.5*Pe+s; mu2 = 0.5*Pe-s;
    s = mu2*exp(mu2)-mu1*exp(mu1);
    c = [c;(mu2*exp(mu2)*exp(mu1*x)-mu1*exp(mu1)*exp(mu2*x))./s];
end
plot (x,c);
legend('Da_1=16','Da_1=8','Da_1=4','Da_1=2','Da_1=1','Da_1=0.5','Da_1=0.25','Da_1=0.125');
xlabel ('x/L [-]'); ylabel ('c/c_{in} [-]');


function pdf = f_pdf ( x, m, n )

%*****************************************************************************80
%
%% F_PDF evaluates the F central PDF.
%
%  Discussion:
%
%    PDF(X)(M,N) = M**(M/2) * X**((M-2)/2)
%      / ( Beta(M/2,N/2) * N**(M/2) * ( 1 + (M/N) * X )**((M+N)/2)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%    0.0 <= X
%
%    Input, integer M, N, the parameters of the PDF.
%    1 <= M,
%    1 <= N.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < 0.0 )

    pdf = 0.0;

  else

    a = m;
    b = n;

    top = sqrt ( m^m * n^n * x^( m - 2 ) );
    bot1 = beta ( m / 2.0, n / 2.0 );
    bot2 =  sqrt ( ( n + m * x )^( m + n ) );

    pdf = top / ( bot1 * bot2 );

  end

  return
end


function X = newtonraphson(Eqn_Str,Start_Point,Max_Iter)

% Function :
%        X = newtonraphson(fun_str,Start_Point)
%              Finds the root of an equation by NEWTON-RAPHSON METHOD.
%
%         x(n+1) = x(n) - (F(x(n))/diff(F(x(n)));
%
% INPUTS :
%        Eqn_Str     : The equation whose root has to be find.
%                      Eqn_Str Should be an string format.
%                      Example :
%                       if  F(x) = x^4 - x - 10
%                       the Eqn_Str = 'x^4 - x - 10';
%
%        Start_Point : Initial value of root X ==> x0
%
%        Max_Iter    : Maximum number of iterations
%
% OUTPUT :
%        X           : Estimeted root of Equation.
%--------------------------------------------------------------------------
% By :-
%      SANDEEP SOLANKI
%      rtm_sandeep@rediffmail.com
%--------------------------------------------------------------------------
if nargin < 2
    error('Not Enough Input Arguments');
end

if nargin < 3
    Max_Iter = 1000;
end

if ~ischar(Eqn_Str)
    error('Funtion Should Be an String');
end

fx = inline(Eqn_Str);
fxd = inline(diff(Eqn_Str));

x0 = Start_Point;
disp(['F(X) = ' Eqn_Str]);
disp(['X0 = ' num2str(x0)]);
% Iterating
for i = 1 : Max_Iter
    s1=sprintf('    Iteration : %1.0f',i);
    disp(s1);
    x1 = x0 - (fx(x0)/fxd(x0));

    s2=sprintf('              X(%0.0f) = %0.15f',i,x1);
    disp(s2);
    if x1 == x0
        disp('Terminating Process : Value of Root Repeated');
        break;
    else
        x0 = x1;
    end
end

if x1 == NaN
    error('Start Point is Not Correct');
end
X = x1;


function membership=paretoset(X)

% PARETOSET  To get the Pareto set from a given set of points.
% synopsis:           membership =paretoset (objectiveMatrix)
% where:
%   objectiveMatrix: [number of points X number of objectives] array
%   membership:      [number of points X 1] logical vector to indicate if ith
%                    point belongs to the Pareto set (true) or not (false).
%
% by Yi Cao, Cranfield University, 02 June 2007
% Revised by Yi Cao on 17 October 2007
% Version 3, 21 October 2007, new sorting scheme to improve speed.
% Bugfix, 25 July 2008, devided by zero error is fixed.
%
% Examples: see paretoset_examples
%

m=size(X,1);
Xmin=min(X);
X1=X-Xmin(ones(m,1),:);     %make sure X1>=0;
Xmean=mean(X1);
%sort X1 so that dominated points can be removed quickly
[x,checklist]=sort(max(X1./(Xmean(ones(m,1),:)+1)));
Y=X(checklist,:);
membership=false(m,1);
while numel(checklist)>1
    k=checklist(1);
    [membership(k),checklist,Y]=paretosub(Y,checklist);
end
membership(checklist)=true;

function [ispareto,nondominated,X]=paretosub(X,checklist)

Z=X-X(ones(size(X,1),1),:);
nondominated=any(Z<0,2);                    %retain nondominated points from the check list
ispareto=all(any(Z(nondominated,:)>0,2));   %check if current point belongs to pareto set
X=X(nondominated,:);
nondominated=checklist(nondominated);


%%%%%%%VERSION 2
%%ANOTHER DESCRIBTION OF GABOR FILTER

%The Gabor filter is basically a Gaussian (with variances sx and sy along x and y-axes respectively)
%modulated by a complex sinusoid (with centre frequencies U and V along x and y-axes respectively)
%described by the following equation
%%
%                            -1     x' ^     y'  ^
%%% G(x,y,theta,f) =  exp ([----{(----) 2+(----) 2}])*cos(2*pi*f*x');
%                             2    sx'       sy'
%%% x' = x*cos(theta)+y*sin(theta);
%%% y' = y*cos(theta)-x*sin(theta);

%% Describtion :

%% I : Input image
%% Sx & Sy : Variances along x and y-axes respectively
%% f : The frequency of the sinusoidal function
%% theta : The orientation of Gabor filter

%% G : The output filter as described above
%% gabout : The output filtered image

%%  Author : Ahmad poursaberi  e-mail : a.poursaberi@ece.ut.ac.ir
%%          Faulty of Engineering, Electrical&Computer Department,Tehran
%%          University,Iran,June 2004

function [G,gabout] = gaborfilter(I,Sx,Sy,f,theta);

if isa(I,'double')~=1
    I = double(I);
end

for x = -fix(Sx):fix(Sx)
    for y = -fix(Sy):fix(Sy)
        xPrime = x * cos(theta) + y * sin(theta);
        yPrime = y * cos(theta) - x * sin(theta);
        G(fix(Sx)+x+1,fix(Sy)+y+1) = exp(-.5*((xPrime/Sx)^2+(yPrime/Sy)^2))*cos(2*pi*f*xPrime);
    end
end

Imgabout = conv2(I,double(imag(G)),'same');
Regabout = conv2(I,double(real(G)),'same');

gabout = sqrt(Imgabout.*Imgabout + Regabout.*Regabout);


function [var, U, lambda] = ppca(x, ppca_dim)
%PPCA	Probabilistic Principal Components Analysis
%
%	Description
%	 [VAR, U, LAMBDA] = PPCA(X, PPCA_DIM) computes the principal
%	component subspace U of dimension PPCA_DIM using a centred covariance
%	matrix X. The variable VAR contains the off-subspace variance (which
%	is assumed to be spherical), while the vector LAMBDA contains the
%	variances of each of the principal components.  This is computed
%	using the eigenvalue and eigenvector  decomposition of X.
%
%	See also
%	EIGDEC, PCA
%

%	Copyright (c) Ian T Nabney (1996-2001)

if ppca_dim ~= round(ppca_dim) | ppca_dim < 1 | ppca_dim > size(x, 2)
   error('Number of PCs must be integer, >0, < dim');
end

[ndata, data_dim] = size(x);
% Assumes that x is centred and responsibility weighted
% covariance matrix
[l Utemp] = eigdec(x, data_dim);
% Zero any negative eigenvalues (caused by rounding)
l(l<0) = 0;
% Now compute the sigma squared values for all possible values
% of q
s2_temp = cumsum(l(end:-1:1))./[1:data_dim]';
% If necessary, reduce the value of q so that var is at least
% eps * largest eigenvalue
q_temp = min([ppca_dim; data_dim-min(find(s2_temp/l(1) > eps))]);
if q_temp ~= ppca_dim
  wstringpart = 'Covariance matrix ill-conditioned: extracted';
  wstring = sprintf('%s %d/%d PCs', ...
      wstringpart, q_temp, ppca_dim);
  warning(wstring);
end
if q_temp == 0
  % All the latent dimensions have disappeared, so we are
  % just left with the noise model
  var = l(1)/data_dim;
  lambda = var*ones(1, ppca_dim);
else
  var = mean(l(q_temp+1:end));
end
U = Utemp(:, 1:q_temp);
lambda(1:q_temp) = l(1:q_temp);


%==============================================================================
% Copyright (C) 2005, Jan Modersitzki and Nils Papenberg, see copyright.m,
% this file is part of the FLIRT Package, all rights reserved;
% http://www.math.uni-luebeck.de/SAFIR/FLIRT-MATLAB.html
%==============================================================================
% function [B,Bstr] = getElasticMatrixStg(Omega,m,mu,lambda);
% generates the elastic matrix B for the domain Omega with resolution m,
% by default, mu = 1, lambda = 0;
%==============================================================================
function [B,Bstr] = getElasticMatrixStg(Omega,m,mu,lambda)

Bstr = 'elastic-stg';
if ~exist('mu','var'),     mu     = 1;  end;
if ~exist('lambda','var'), lambda = 0;  end;
h = Omega./m;

dim = length(Omega);

switch dim
  case 2
    d11 = spdiags(ones(m(1),1)*[-1,1],[0,1],m(1),m(1)+1)/h(1);
    d12 = spdiags(ones(m(2)-1,1)*[-1,1],[0,1],m(2)-1,m(2))/h(2);
    d21 = spdiags(ones(m(1)-1,1)*[-1,1],[0,1],m(1)-1,m(1))/h(1);
    d22 = spdiags(ones(m(2),1)*[-1,1],[0,1],m(2),m(2)+1)/h(2);

    D11 = sparse(kron(speye(m(2)),d11));
    D12 = sparse(kron(d12,speye(m(1)+1)));
    D21 = sparse(kron(speye(m(2)+1),d21));
    D22 = sparse(kron(d22,speye(m(1))));

    % build the elastic operator
    %
    %      | \nabla 0      |
    %  B = |               |
    %      | 0      \nabla |
    %      |               |
    %      | Div1   Div2   |
    % B[U] = [\partial_1 U1,\partial_2 U1, \partial_1 U2,\partial_2 U2,div(U)]

    a  = sqrt(mu);
    b  = sqrt(mu+lambda);
    n1 = (m(1)+1)*m(2);
    n2 = m(1)*(m(2)+1);
    j1 = size(D11,1);
    j2 = size(D12,1);
    j3 = size(D21,1);
    j4 = size(D22,1);

    B = [  a*D11,sparse(j1,n2);
      a*D12,sparse(j2,n2);
      sparse(j3,n1),a*D21;
      sparse(j4,n1),a*D22;
      b*D11,b*D22];
    return;

  otherwise
    error('nyi');
end;
%==============================================================================


function eigg_segmentation
% This code was written by Muhammet Balcilar , France,
% muhammetbalcilar@gmail.com, inspired from following reference
%
%  This Matlab code implements an edge-based active contour model as an
%  application of the Distance Regularized Level Set Evolution (DRLSE) formulation in Li et al's paper:
%
%      C. Li, C. Xu, C. Gui, M. D. Fox, "Distance Regularized Level Set Evolution and Its Application to Image Segmentation",
%        IEEE Trans. Image Processing, vol. 19 (12), pp.3243-3254, 2010.

close all

%% step1, read grayscale image
Img=imread('Inputs/eigg_scotland.jpg');
Img=rgb2gray(Img);
frm=0;
%% step2, set params
timestep=5;  % time step
mu=0.2;  % coefficient of the distance regularization term R(phi)
lambda=5; %coefficient of the weighted length term L(phi)
alfa= -3;  %  coefficient of the weighted area term A(phi)
epsilon=1.5; % papramater that specifies the width of the DiracDelta function
c0=2;
maxiter=602;
sigma=2.0;    % scale parameter in Gaussian kernel

%% step3 smooth image with gaussian filter
G=fspecial('gaussian',30,sigma); % 15 Caussian kernel
Img_smooth=conv2(Img,G,'same');  % smooth image by Gaussiin convolution
figure(1);
imagesc(Img_smooth,[0, 255]); axis off; axis equal; colormap(gray);
title('Smoothed image');

%% step4 calculate edge indicator according to Eq23
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f);  % edge indicator function.
g=exp(-f);
figure(2);
imagesc(g); axis off; axis equal;
title('g,  edge indicator');

%% step5, set initial phi
phi = -c0*ones(size(Img));
phi(50:650,50:500)=c0;
%phi(350:370,200:220)=-c0;
figure(3);
imagesc(phi);
axis off; axis equal;colormap(jet);
title('initial phi matrix');

[vx, vy]=gradient(g);
figure(4);
subplot(1,2,1);imagesc(vx); title('x directioned gradient of g');
subplot(1,2,2);imagesc(vy); title('y directioned gradient of g');

for k=1:maxiter
    %% step6, check boundary conditions
    phi=NeumannBoundCond(phi);

    %% step 7 calculate differential of regularized term in Eq.30
    distRegTerm=distReg_p2(phi);

    %% step8 calculate differential of area term in Eq.30
    diracPhi=Dirac(phi,epsilon);
    areaTerm=diracPhi.*g;

    %% step9 calculate differential of length term in Eq.30
    [phi_x,phi_y]=gradient(phi);
    s=sqrt(phi_x.^2 + phi_y.^2);
    Nx=phi_x./(s+1e-10); % add a small positive number to avoid division by zero
    Ny=phi_y./(s+1e-10);
    edgeTerm=diracPhi.*(vx.*Nx+vy.*Ny) + diracPhi.*g.*div(Nx,Ny);

    %% step 10 update phi according to Eq.20
    phi=phi + timestep*(mu/timestep*distRegTerm + lambda*edgeTerm + alfa*areaTerm);

     %% show result in every 50 iteration
    if mod(k,50)==1
        frm=frm+1;
        close all
        h=figure(5);
        set(gcf,'color','w');
        subplot(1,2,1);
        II=Img;
        II(:,:,2)=Img;II(:,:,3)=Img;
        imshow(II); axis off; axis equal; hold on;
        q=contour(phi, [0,0], 'r');
        msg=['contour result , iteration number=' num2str(k)];
        title(msg);
        subplot(1,2,2);
        mesh(-phi,[-2 2]);
        hold on;  contour(phi, [0,0], 'r','LineWidth',2);

        view([180-30 -65-180]);
        msg=['phi result , iteration number=' num2str(k)];
        title(msg);
        pause(0.1)

        % gif video

        frame = getframe(h);
        im = frame2im(frame);
        [imind,cm] = rgb2ind(im,256);
        %Write to the GIF File
        if frm == 1
            imwrite(imind,cm,'Outputs/eigg.gif','gif', 'Loopcount',inf);
        else
            imwrite(imind,cm,'Outputs/eigg.gif','gif','WriteMode','append');
        end
    end

    %% step 11 if maxiter done then finish, else return step6
end
%% Step 12. show last iteration results
figure(6);
imagesc(Img,[0, 255]); axis off; axis equal; colormap(gray); hold on;  contour(phi, [0,0], 'r');
msg=['phi result , iteration number=' num2str(k)];
title(msg);

function f = distReg_p2(phi)
% compute the distance regularization term with the double-well potential p2 in eqaution (16)
[phi_x,phi_y]=gradient(phi);
s=sqrt(phi_x.^2 + phi_y.^2);
a=(s>=0) & (s<=1);
b=(s>1);
ps=a.*sin(2*pi*s)/(2*pi)+b.*(s-1);  % compute first order derivative of the double-well potential p2 in eqaution (16)
dps=((ps~=0).*ps+(ps==0))./((s~=0).*s+(s==0));  % compute d_p(s)=p'(s)/s in equation (10). As s-->0, we have d_p(s)-->1 according to equation (18)
f = div(dps.*phi_x - phi_x, dps.*phi_y - phi_y) + 4*del2(phi);

function f = div(nx,ny)
[nxx,junk]=gradient(nx);
[junk,nyy]=gradient(ny);
f=nxx+nyy;

function f = Dirac(x, sigma)
f=(1/2/sigma)*(1+cos(pi*x/sigma));
b = (x<=sigma) & (x>=-sigma);
f = f.*b;

function g = NeumannBoundCond(f)
% Make a function satisfy Neumann boundary condition
[nrow,ncol] = size(f);
g = f;
g([1 nrow],[1 ncol]) = g([3 nrow-2],[3 ncol-2]);
g([1 nrow],2:end-1) = g([3 nrow-2],2:end-1);
g(2:end-1,[1 ncol]) = g(2:end-1,[3 ncol-2]);


function x=modcent(x,r);
%MODCENT  Centered modulo
%   Usage:  y=modcent(x,r);
%
%   `modcent(x,r)` computes the modulo of *x* in the range $[-r/2,r/2[$.
%
%   As an example, to compute the modulo of *x* in the range $[-\pi,\pi[$ use
%   the call::
%
%     y = modcent(x,2*pi);

x=mod(x,r);
idx=x>r/2;
x(idx)=x(idx)-r;


function [ n_data_new, n, m, x, fx ] = legendre_associated_values ( n_data )

%*****************************************************************************80
%
%% LEGENDRE_ASSOCIATED_VALUES returns values of associated Legendre functions.
%
%  Discussion:
%
%    The function considered is the associated Legendre function P^M_N(X).
%
%    In Mathematica, the function
%
%      LegendreP [ n, m, x ]
%
%    returns the value of the associated Legendre function P^M_N(X).
%
%  Differential equation:
%
%    (1-X*X) * Y'' - 2 * X * Y + ( N (N+1) - (M*M/(1-X*X)) * Y = 0
%
%  First terms:
%
%    M = 0  ( = Legendre polynomials of first kind P(N)(X) )
%
%    P00 =    1
%    P10 =    1 X
%    P20 = (  3 X^2 -   1)/2
%    P30 = (  5 X^3 -   3 X)/2
%    P40 = ( 35 X^4 -  30 X^2 +   3)/8
%    P50 = ( 63 X^5 -  70 X^3 +  15 X)/8
%    P60 = (231 X^6 - 315 X^4 + 105 X^2 -  5)/16
%    P70 = (429 X^7 - 693 X^5 + 315 X^3 - 35 X)/16
%
%    M = 1
%
%    P01 =   0
%    P11 =   1 * SQRT(1-X*X)
%    P21 =   3 * SQRT(1-X*X) * X
%    P31 = 1.5 * SQRT(1-X*X) * (5*X*X-1)
%    P41 = 2.5 * SQRT(1-X*X) * (7*X*X*X-3*X)
%
%    M = 2
%
%    P02 =   0
%    P12 =   0
%    P22 =   3 * (1-X*X)
%    P32 =  15 * (1-X*X) * X
%    P42 = 7.5 * (1-X*X) * (7*X*X-1)
%
%    M = 3
%
%    P03 =   0
%    P13 =   0
%    P23 =   0
%    P33 =  15 * (1-X*X)^1.5
%    P43 = 105 * (1-X*X)^1.5 * X
%
%    M = 4
%
%    P04 =   0
%    P14 =   0
%    P24 =   0
%    P34 =   0
%    P44 = 105 * (1-X*X)^2
%
%  Recursion:
%
%    if N < M:
%      P(N,M) = 0
%    if N = M:
%      P(N,M) = (2*M-1)!! * (1-X*X)^(M/2) where N!! means the product of
%      all the odd integers less than or equal to N.
%    if N = M+1:
%      P(N,M) = X*(2*M+1)*P(M,M)
%    if M+1 < N:
%      P(N,M) = ( X*(2*N-1)*P(N-1,M) - (N+M-1)*P(N-2,M) )/(N-M)
%
%  Restrictions:
%
%    -1 <= X <= 1
%     0 <= M <= N
%
%  Special values:
%
%    P(N,0)(X) = P(N)(X), that is, for M=0, the associated Legendre
%    function of the first kind equals the Legendre polynomial of the
%    first kind.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%  Parameters:
%
%    Input, integer N_DATA, indicates the index of the previous test data
%    returned, or is 0 if this is the first call.  For repeated calls,
%    set the input value of N_DATA to the output value of N_DATA_NEW
%    from the previous call.
%
%    Output, integer N_DATA_NEW, the index of the test data.
%
%    Output, integer N, integer M, real X, the arguments of the function.
%
%    Output, real FX, the value of the function.
%
  n_max = 19;
  n_vec = [ ...
     1,  1,  1,  1, ...
     1,  2,  2,  2, ...
     3,  3,  3,  3, ...
     4,  5,  6,  7, ...
     8,  9, 10 ];
  m_vec = [ ...
     0,  0,  0,  0, ...
     1,  0,  1,  2, ...
     0,  1,  2,  3, ...
     2,  2,  3,  3, ...
     4,  4,  5 ];
  fx_vec = [ ...
     0.000000E+00,  0.500000E+00,  0.707107E+00,  1.000000E+00, ...
    -0.866025E+00, -0.125000E+00, -1.29904E+00,   2.25000E+00, ...
    -0.437500E+00, -0.324759E+00,  5.62500E+00,  -9.74278E+00, ...
     4.21875E+00,  -4.92187E+00,   12.7874E+00,   116.685E+00, ...
    -1050.67E+00,  -2078.49E+00,   30086.2E+00 ];
  x_vec = [ ...
    0.0E+00,       0.5E+00,       0.7071067E+00, 1.0E+00, ...
    0.5E+00,       0.5E+00,       0.5E+00,       0.5E+00, ...
    0.5E+00,       0.5E+00,       0.5E+00,       0.5E+00, ...
    0.5E+00,       0.5E+00,       0.5E+00,       0.5E+00, ...
    0.5E+00,       0.5E+00,       0.5E+00 ];

  n_data_new = n_data;

  if ( n_data_new < 0 )
    n_data_new = 0;
  end

  n_data_new = n_data_new + 1;

  if ( n_max < n_data_new )
    n_data_new = 0;
    n = 0;
    m = 0;
    x = 0.0E+00;
    fx = 0.0E+00;
  else
    n = n_vec(n_data_new);
    m = m_vec(n_data_new);
    x = x_vec(n_data_new);
    fx = fx_vec(n_data_new);
  end

  return
end


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

M=[-0.66666666666666666666666666666666666667,   0.33333333333333333333333333333333333333,   0.66666666666666666666666666666666666667;
    0.33333333333333333333333333333333333333,  -0.66666666666666666666666666666666666667,   0.66666666666666666666666666666666666667;
   -0.66666666666666666666666666666666666667,  -0.66666666666666666666666666666666666667,   0.66666666666666666666666666666666666667];

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

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


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Inverse kinematics for the 3dof planar robot
% T: homogeneous matrix
% robot: structure with arm parameters
% returns: all possible solutions or q = [q1 q2] that place the end effectors at the
% position specified by T. Two possible solutions q1 and q2 q3 and q4 are returned,
% generally called elbow up and elbow down, combined with
%   Author: Arturo Gil Aparicio arturo.gil@umh.es
%   Date: 08/03/2012
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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

fprintf('\nComputing inverse kinematics for the %s robot', robot.name);

%Initialize q
% q = [q1 q2 q3 q4], atends for two possible solutions
q=zeros(3,4);

a = eval(robot.DH.a);

%Link lengths
L1=abs(a(1));
L2=abs(a(2));
L3=abs(a(2));

%T= [ nx ox ax Px;
%     ny oy ay Py;
%     nz oz az Pz];
Q=T(1:3,4);

%find angle Phi
x3 = T(1:3,1);

cphi = x3'*[1 0 0]';
sphi = x3'*[0 1 0]';
phi = atan2(sphi, cphi);

%Find point P from P and vector (nx, ny, nz)
P = Q - a(3)*T(1:3,1);

%Distance of the point to the origin.
R= sqrt(P(1)^2+P(2)^2);

if R > (L1+L2)
   disp('\ninversekinematic_3dofplanar: unfeasible solution. The point cannot be reached');
end

%compute geometric solution
beta = atan2(P(2),P(1));
gamma = real(acos((L1^2+R^2-L2^2)/(2*R*L1)));
delta = real(acos((L1^2+L2^2-R^2)/(2*L1*L2)));

%arrange possible combinations for q(1) and q(2)
%elbow down     elbow up solutions
q =[beta+gamma beta-gamma;
    delta-pi   pi-delta];

%in this case, phi = q(1) + q(2) + q(3) and
%q(3) can be computed as q(3) = phi - q(1) - q(2)
%corresponding to each of the previous solutions, a unique q(3) can be
%computed for each case
for i=1:2 %iterate through columns
    q(3,i) = phi - q(1,i) - q(2,i);
end


% Minimize sidelobe level of an array with arbitrary 2-D geometry
% "Convex optimization examples" lecture notes (EE364) by S. Boyd
% "Antenna array pattern synthesis via convex optimization"
% by H. Lebret and S. Boyd
% (figures are generated)
%
% Designs an antenna array such that:
% - it minimizes sidelobe level outside the beamwidth of the pattern
% - it has a unit sensitivity at some target direction
% - it has nulls (zero sensitivity) at specified direction(s) (optional)
%
% This is a convex problem (after sampling it can be formulated as an SOCP).
%
%   minimize   max |y(theta)|     for theta outside the beam
%       s.t.   y(theta_tar) = 1
%              y(theta_null) = 0  (optional)
%
% where y is the antenna array gain pattern (complex function) and
% variables are w (antenna array weights or shading coefficients).
% Gain pattern is a linear function of w: y(theta) = w'*a(theta)
% for some a(theta) describing antenna array configuration and specs.
%
% Written for CVX by Almir Mutapcic 02/02/06

% select array geometry
ARRAY_GEOMETRY = '2D_RANDOM';
% ARRAY_GEOMETRY = '1D_UNIFORM_LINE';
% ARRAY_GEOMETRY = '2D_UNIFORM_LATTICE';

% select if the optimal array pattern should enforce nulls or not
HAS_NULLS = 0; % HAS_NULLS = 1;

%********************************************************************
% problem specs
%********************************************************************
lambda = 1;           % wavelength
theta_tar = 60;       % target direction (should be an integer -- discretization)
half_beamwidth = 10;  % half beamwidth around the target direction

% angles where we want nulls (optional)
if HAS_NULLS
  theta_nulls = [95 110 120 140 225];
end

%********************************************************************
% random array of n antenna elements
%********************************************************************
if strcmp( ARRAY_GEOMETRY, '2D_RANDOM' )
  % set random seed to repeat experiments
  rand('state',0);

  % (uniformly distributed on [0,L]-by-[0,L] square)
  n = 40;
  L = 5;
  loc = L*rand(n,2);
  angleRange = 360;

%********************************************************************
% uniform 1D array with n elements with inter-element spacing d
%********************************************************************
elseif strcmp( ARRAY_GEOMETRY, '1D_UNIFORM_LINE' )
  % (unifrom array on a line)
  n = 30;
  d = 0.45*lambda;
  loc = [d*[0:n-1]' zeros(n,1)];
  angleRange = 180;

%********************************************************************
% uniform 2D array with m-by-m element with d spacing
%********************************************************************
elseif strcmp( ARRAY_GEOMETRY, '2D_UNIFORM_LATTICE' )
  m = 6; n = m^2;
  d = 0.45*lambda;

  loc = zeros(n,2);
  for x = 0:m-1
    for y = 0:m-1
      loc(m*y+x+1,:) = [x y];
    end
  end
  loc = loc*d;
  angleRange = 360;

else
  error('Undefined array geometry')
end

%********************************************************************
% construct optimization data
%********************************************************************
% build matrix A that relates w and y(theta), ie, y = A*w
theta = [1:angleRange]';
A = kron(cos(pi*theta/180), loc(:,1)') + kron(sin(pi*theta/180), loc(:,2)');
A = exp(2*pi*i/lambda*A);

% target constraint matrix
[diff_closest, ind_closest] = min( abs(theta - theta_tar) );
Atar = A(ind_closest,:);

% nulls constraint matrix
if HAS_NULLS
  Anull = []; ind_nulls = [];
  for k = 1:length(theta_nulls)
    [diff_closest, ind_closest] = min( abs(theta - theta_nulls(k)) );
    Anull = [Anull; A(ind_closest,:)];
    ind_nulls = [ind_nulls ind_closest];
  end
end

% stopband constraint matrix
ind = find(theta <= (theta_tar-half_beamwidth) | ...
           theta >= (theta_tar+half_beamwidth) );
if HAS_NULLS, ind = setdiff(ind,ind_nulls); end;
As = A(ind,:);

%********************************************************************
% optimization problem
%********************************************************************
cvx_begin
  variable w(n) complex
  minimize( max( abs(As*w) ) )
  subject to
    Atar*w == 1;   % target constraint
    if HAS_NULLS   % nulls constraints
      Anull*w == 0;
    end
cvx_end

% check if problem was successfully solved
disp(['Problem is ' cvx_status])
if ~strfind(cvx_status,'Solved')
  return
end

min_sidelobe_level = 20*log10( max(abs(As*w)) );
fprintf(1,'The minimum sidelobe level is %3.2f dB.\n\n',...
          min_sidelobe_level );

%********************************************************************
% plots
%********************************************************************
figure(1), clf
plot(loc(:,1),loc(:,2),'o')
title('Antenna locations')

% plot array pattern
if angleRange == 180,
    theta = [1:360]';
    A = [ A; -A ];
end
y = A*w;
figure(2), clf
ymin = floor(0.1*min_sidelobe_level)*10-10; ymax = 0;
plot([1:360], 20*log10(abs(y)), ...
     [theta_tar theta_tar],[ymin ymax],'r--',...
     [theta_tar+half_beamwidth theta_tar+half_beamwidth],[ymin ymax],'g--',...
     [theta_tar-half_beamwidth theta_tar-half_beamwidth],[ymin ymax],'g--');
if HAS_NULLS % add lines that represent null positions
  hold on;
  for k = 1:length(theta_nulls)
    plot([theta_nulls(k) theta_nulls(k)],[ymin ymax],'m--');
  end
  hold off;
end
xlabel('look angle'), ylabel('mag y(theta) in dB');
axis([0 360 ymin ymax]);

% polar plot
figure(3), clf
zerodB = -ymin;
dBY = 20*log10(abs(y)) + zerodB;
ind = find( dBY <= 0 ); dBY(ind) = 0;
plot(dBY.*cos(pi*theta/180), dBY.*sin(pi*theta/180), '-');
axis([-zerodB zerodB -zerodB zerodB]), axis('off'), axis('square')
hold on
plot(zerodB*cos(pi*theta/180),zerodB*sin(pi*theta/180),'k:') % 0 dB
plot( (min_sidelobe_level + zerodB)*cos(pi*theta/180), ...
      (min_sidelobe_level + zerodB)*sin(pi*theta/180),'k:')  % min level
text(-zerodB,0,'0 dB')
tt = text(-(min_sidelobe_level + zerodB),0,sprintf('%0.1f dB',min_sidelobe_level));
set(tt,'HorizontalAlignment','right');
theta_1 = theta_tar+half_beamwidth;
theta_2 = theta_tar-half_beamwidth;
plot([0 55*cos(theta_tar*pi/180)], [0 55*sin(theta_tar*pi/180)], 'k:')
plot([0 55*cos(theta_1*pi/180)], [0 55*sin(theta_1*pi/180)], 'k:')
plot([0 55*cos(theta_2*pi/180)], [0 55*sin(theta_2*pi/180)], 'k:')
if HAS_NULLS % add lines that represent null positions
  for k = 1:length(theta_nulls)
    plot([0 55*cos(theta_nulls(k)*pi/180)], ...
         [0 55*sin(theta_nulls(k)*pi/180)], 'k:')
  end
end
hold off


function [ px, pxp ] = least_val2 ( nterms, b, c, d, x )

%*****************************************************************************80
%
%% LEAST_VAL2 evaluates a least squares polynomial defined by LEAST_SET.
%
%  Discussion:
%
%    This routine also computes the derivative of the polynomial.
%
%    The least squares polynomial is assumed to be defined as a sum
%
%      P(X) = SUM ( I = 1 to NTERMS ) D(I) * P(I-1,X)
%
%    where the orthogonal basis polynomials P(I,X) satisfy the following
%    three term recurrence:
%
%      P(-1,X) = 0
%      P(0,X) = 1
%      P(I,X) = ( X - B(I-1) ) * P(I-1,X) - C(I-1) * P(I-2,X)
%
%    Therefore, the least squares polynomial can be evaluated as follows:
%
%    If NTERMS is 1, then the value of P(X) is D(1) * P(0,X) = D(1).
%
%    Otherwise, P(X) is defined as the sum of NTERMS > 1 terms.  We can
%    reduce the number of terms by 1, because the polynomial P(NTERMS,X)
%    can be rewritten as a sum of polynomials;  Therefore, P(NTERMS,X)
%    can be eliminated from the sum, and its coefficient merged in with
%    those of other polynomials.  Repeat this process for P(NTERMS-1,X)
%    and so on until a single term remains.
%    P(NTERMS,X) of P(NTERMS-1,X)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 May 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NTERMS, the number of terms in the least squares
%    polynomial.  NTERMS must be at least 1.  The value of NTERMS
%    may be reduced from the value given to LEAST_SET.
%    This will cause LEAST_VAL to evaluate the least squares polynomial
%    of the lower degree specified.
%
%    Input, real B(NTERMS), C(NTERMS), D(NTERMS), the information
%    computed by LEAST_SET.
%
%    Input, real X, the point at which the least squares polynomial
%    is to be evaluated.
%
%    Output, real PX, PXP, the value and derivative of the least
%    squares polynomial at X.
%
  px = d(nterms);
  pxp = 0.0;
  pxm1 = 0.0;
  pxpm1 = 0.0;

  for i = nterms-1 : -1 : 1

    pxm2 = pxm1;
    pxpm2 = pxpm1;
    pxm1 = px;
    pxpm1 = pxp;

    if ( i == nterms-1 )
      px = d(i) + ( x - b(i) ) * pxm1;
      pxp = pxm1 + ( x - b(i) ) * pxpm1;
    else
      px = d(i) + ( x - b(i) ) * pxm1 - c(i+1) * pxm2;
      pxp = pxm1 + ( x - b(i) ) * pxpm1 - c(i+1) * pxpm2;
    end

  end

  return
end


function xCommon=findLongestCommonSubsequence(x,y)
%%FINDLONGESTCOMMONSUBSEQUENCE Given two vectors of numbers, characters,
%              etc., find the longest sequence of elements in both of them.
%              The elements must appear in order need NOT BE CONSECUTIVE.
%
%INPUTS:      x,y  Two vectors.
%
%OUTPUTS: xCommon  The longest common subsequence shared by the vectors.
%                  The elements in the subsequence need not be consecutive.
%                  For example, the longest common subsequence of "dunkin"
%                  and "doughnuts" is "dun".
%
%The algorithm is taken from Chapter 15.4 of [1], but modified so that the
%sequence comes out in order and to deal with Matlab addressing things from
%1 instead of 0.
%
%REFERENCES:
%[1] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein,
%    Introduction to Algorithms, 2nd ed. Cambridge, MA: The MIT Press,
%    2001.
%
%October 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

m=length(x);
n=length(y);

c=zeros(m+1,n+1);
for i=m:-1:1
    for j=n:-1:1
        if(x(i)==y(j))
            c(i,j)=c(i+1,j+1)+1;
        else
            c(i,j)=max(c(i,j+1),c(i+1,j));
        end
    end
end

i=1;
j=1;
%Setting xCommon to x rather than alocating with zeros assured that xCommon
%will have the same type and shape as x. This is good when x is a character
%string.
xCommon=x;
numFound=0;
while(i<=m&&j<=n)
    if(x(i)==y(j))
       numFound=numFound+1;
       xCommon(numFound)=x(i);
       i=i+1;
       j=j+1;
    elseif(c(i+1,j)>=c(i,j+1))
        i=i+1;
    else
        j=j+1;
    end
end

%Get rid of extra elements in xCommon.
xCommon=xCommon(1:numFound);
end

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


function F=HessTaylor(deltaT,dadx,d2adx,method)
%%HESSTAYLOR Simulate a nonlinear continuous-time random process specified
%            by the Langevin equation forward in time by a step-size of
%            deltaT using a Taylor scheme.
%
%INPUTS: deltaT The size of the single step over which to generate the
%               state transition matrix.
%          dadx A xDimXxDim matrix of the derivative of the drift function
%               with respect to the state at state xCur and time curT.
%         d2adx A xDimXxDimXxDim matrix of the second derivative of the
%               drift function with respect to the state at state xCur and
%               time curT. The value at point (m,k,l) represents
%               d2a(m)/dx(k)dx(l). If not provided, this is assumed to be
%               zero.
%        method Set to 0 for the shorter Euler-Maruyama expansion,
%               otherwise will the Taylor expansion will be used (default).
%
%OUTPUTS: H The Hessian matrix of a nonlinear continuous-time random
%           process specified by the Langevin equation forward in time by a
%           step-size of deltaT using a strong Taylor scheme.
%
%The second derivative state prediction matrix is derived from the
%stochastic order 1.5 Taylor scheme described in 10.4 of [1].
%
%REFERENCES:
%[1] P. E. Kloeden and E. Platen, Numerical Solution of Stochastic
%    Differential Equations. Berlin: Springer, 1999.
%
%April 2015 David Karnick, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

xDim=size(dadx,1);
if(nargin<4||isempty(method))
    method=1;
end

if(method==0)
    F=deltaT*d2adx;
else
    %Assumes 3rd derivative is zero
    term1=zeros(xDim,xDim,xDim);
    term2=zeros(xDim,xDim,xDim);
    term3=zeros(xDim,xDim,xDim);
    for m=1:xDim
        term1(:,:,m)=d2adx(:,:,m)*dadx;
        term2(:,m,:)=d2adx(:,:,m)*dadx;
        term3(:,:,m)=dadx*d2adx(:,:,m);
    end

    F=deltaT*d2adx+(deltaT^2/2)*(term1+term2+term3);
end

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


function mind = dijkstra_distance ( nv, ohd )

%*****************************************************************************80
%
%% DIJKSTRA_DISTANCE uses Dijkstra's minimum distance algorithm.
%
%  Discussion:
%
%    We essentially build a tree.  We start with only node 0 connected
%    to the tree, and this is indicated by setting CONNECTED(0) = 1.
%
%    We initialize MIND(I) to the one step distance from node 0 to node I.
%
%    Now we search among the unconnected nodes for the node MV whose minimum
%    distance is smallest, and connect it to the tree.  For each remaining
%    unconnected node I, we check to see whether the distance from 0 to MV
%    to I is less than that recorded in MIND(I), and if so, we can reduce
%    the distance.
%
%    After NV-1 steps, we have connected all the nodes to 0, and computed
%    the correct minimum distances.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 July 2010
%
%  Author:
%
%    Original C version by Norm Matloff, CS Dept, UC Davis.
%    This MATLAB version by John Burkardt.
%
%  Parameters:
%
%    Input, integer OHD(NV,NV), the distance of the direct link between
%    nodes I and J.
%
%    Output, integer MIND(NV), the minimum distance from node 1 to each node.
%

%
%  Start out with only node 1 connected to the tree.
%
  connected(1) = 1;
  connected(2:nv) = 0;
%
%  Initialize the minimum distance to the one-step distance.
%
  mind(1:nv) = ohd(1,1:nv);
%
%  Attach one more node on each iteration.
%
  for step = 2 : nv
%
%  Find the nearest unconnected node.
%
    [ md, mv ] = find_nearest ( nv, mind, connected );

    if ( mv == - 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'DIJKSTRA_DISTANCE - Warning!\n' );
      fprintf ( 1, '  Search terminated early.\n' );
      fprintf ( 1, '  Graph might not be connected.\n' );
      return
    end
%
%  Mark this node as connected.
%
    connected(mv) = 1;
%
%  Having determined the minimum distance to node MV, see if
%  that reduces the minimum distance to other nodes.
%
    mind = update_mind ( nv, mv, connected, ohd, mind );

  end

  return
end


function vol = hist_vol(ticker, N)
% HIST_VOL          Calculate historical volatility
%   vol = hist_vol(ticker, N) is used to calculate the historical
%   volatility for the underlying asset specified in TICKER over N trading
%   days.  If N is not specified, a default of 20 trading days will be
%   used.
%
%   INPUTS
%       ticker --> A string or cell array of strings specifying the ticker
%                  symbols for the underlying assets to use.
%
%       N --> An integer specifying the number of days to use in the
%             volatility calculationg
%
%   OUTPUT
%       The function will return the historical volatility for each of the
%       tickers passed to the function
%
%   NOTES
%       This program uses the function 'hist_stock_data.m', which downloads
%       historical stock data to use for the volatility calculations.
%       Therefore, you must also download this function from my File
%       Exchange and place it in the same directory as this function.
%
%       The historical volatility is calculated by using the closing prices
%       of each trading day.  Additionally, one year of historical stock
%       data will be downloaded, limiting N to a maximum of roughly 252 (as
%       there are about 252 trading days in a year).  If the user wishes to
%       allow larger N, changes must be made to the code when creating the
%       variable 'start_date'.

% Created by Josiah Renfree
% July 20, 2009

% Error checking
if nargin == 0          % If no inputs provided
    error('Please provide at least one ticker symbol')
elseif nargin > 2       % If too many inputs provided
    error('Function accepts no more than 2 inputs')
elseif ~ischar(ticker) && ~iscell(ticker)   % If ticker input is wrong type
    error('Ticker input must be either a string or cell array of strings')
elseif nargin == 1      % If N not supplied, use default
    N = 20;
elseif ~isnumeric(N) || length(N) > 1  % If N is supplied, but is wrong type
    error('N must be a single integer value')
end

% If only one ticker given, convert to cell array
if ~iscell(ticker)
    ticker = {ticker};
end

% Cycle through each ticker and calculate historical volatility
vol = zeros(length(ticker), 1);
for i = 1:length(ticker)
    % Clear for loop variables for next iteration
    clear curr_date start_date data closing log_change stdev

    % Create date strings to pass to hist_stock_data function
    curr_date = datestr(now, 'ddmmyyyy');       % get current date string
    start_date = datestr(now-365, 'ddmmyyyy');  % go back 1 year

    % First step is to download historical stock data for the ticker
    data = hist_stock_data(start_date, curr_date, ticker{i});
    closing = data.Close;   % Use only closing data

    % Calculate the percentage change over the past N trading days
    log_change = log(closing(2:N+1)./closing(1:N));

    % Get standard deviation of that change
    stdev = std(log_change);

    % Now normalize to annual volatility
    vol(i) = stdev*sqrt(252);
end


% Simple 1st order RC transient response:
% File:  rctime.m
% 9/19/02
%
clear;clc
%
K=1e3;uF=1e-6;us=1e-6;ms=1e-3;
%
R1=20*K;R2=40*K;C1=0.5*uF;Ein=1;E1=1;
%
U=1;N=1;M=1;Y=1;
%
A1=[1/R1+1/R2 1;1 0];
%
B2=[0 Ein/R1;E1 0];
%
P=C1;
%
% Template matrix equations:
%
V=A1\B2;H=V(U+1:U+N,1:N+M);AB=inv(P)*H;I=eye(N);

A=AB(1:N,1:N);B=AB(1:N,N+1:N+M);
D=V(Y:Y,1:N);E=V(Y:Y,N+1:N+M);
%
% Display A, B, D, & E
A
B
D
E
%
Rp=R1*R2/(R1+R2);
dt=500*us;kmax=100;Ein=4.5; % Ein can be changed after A, B, D, E have been computed.
%dt=100*us;kmax=500;Ein=4.5; % Try this dt after using the dt above.
Vc=zeros(1,kmax);Vo=zeros(1,kmax); % Vo(k) = Vc(k);
%
for k=2:kmax
   Vc(k)=(A*Vc(k-1)+B*Ein)*dt+Vc(k-1);
   Vo(k)=D*Vc(k)+E*Ein;
   T(k)=k*dt;
   F(k)=(Ein*Rp/R1)*(1-exp(-T(k)/(Rp*C1))); % F(k) = inverse LaPlace tranform
end
%
h=plot(T/ms,Vo,'k',T/ms,F,'r');
set(h,'LineWidth',2);
grid on
xlabel('Time (ms)');
ylabel('Volts');
title('RC Time Response');
legend('Vo(k)','F(k)');
figure(1);
%
% Note that difference between F(k) and the time iteration Vo(k).  This can be reduced by
% decreasing dt with a corresponding increase in kmax to retain the same sweep time.
% For example, if dt = 250us, kmax should be set to 200.


function out = jaccoeffs(f, n, a, b)
%JACCOEFFS   Jacobi polynomial coefficients of a CHEBFUN.
%   A = JACCOEFFS(F, N, ALPHA, BETA) returns the first N+1 coefficients in the
%   Jacobi series expansion of the CHEBFUN F, so that such that F approximately
%   equals A(1) J_0(x) + ... + A(N+1) J_N(x) where J_N(x) denotes the N-th
%   Jacobi polynomial with parameters ALPHA and BETA. A is a column vector.
%
%   If F is smooth (i.e., numel(f.funs) == 1), then A = JACCOEFFS(F, ALPHA,
%   BETA) will assume that N = length(F).
%
%   JACCOEFFS does not support quasimatrices.
%
% See also CHEBCOEFFS, LEGCOEFFS.

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

if ( (numel(f(1).funs) == 1) && (nargin < 4) )
    b = a;
    a = n;
    n = length(f);
elseif ( isempty(n) )
    n = length(f);
end

if ( numel(f) > 1 )
    out = zeros(n, numel(f));
    f = cheb2cell(f);
    for k = 1:numel(f)
        out(:,k) = jaccoeffs(f{k}, n, a, b);
    end
    return
end

%%
% Special cases:
if ( a == 0 && b == 0 )
    out = legcoeffs(f, n);
    return
elseif ( a == -.5 && b == -.5 )
    out = chebcoeffs(f, n, 'kind', 1);
    nn = 0:(n-2);
    scl = repmat([1 ; cumprod((nn'+.5)./(nn'+1))], 1, size(out, 2));
    out = out./scl;
    return
elseif ( a == .5 && b == .5 )
    out = chebcoeffs(f, n, 'kind', 2);
    nn = 0:(n-2);
    scl = repmat([1 ; cumprod((nn'+1.5)./(nn'+1))], 1, size(out, 2));
    out = (1:n)'.*out./scl;
    return
end

%%
if ( numel(f.funs) == 1 )

    % Compute Jacobi coefficients of the single fun.
    out = jaccoeffs(f.funs{1}, n, a, b);

else

    % Jacobi-Vandermonde matrix:
    Enorm = jacpoly(0:n-1, a, b, f.domain);

    % Compute the projection (with correct scaling):
    out = Enorm \ f;

end

end


function error = vennX( data, resolution )
%
% function error = vennX( data, resolution )
%
% vennX - draws an area proportional venn diagram
%
% Draws a venn diagram (either two or three set) using
% circles, where the area of each region is proportional
% to the input values.
%
% INPUT:
%      data - a vector of counts for each set partition
%
%          For a two circle diagram:
%            data is a three element vector of:
%              |A|
%              |A and B|
%              |B|
%
%          For a three circle diagram:
%            data is a seven element vector of:
%               |A|
%               |A and B|
%               |B|
%               |B and C|
%               |C|
%               |C and A|
%               |A and B and C|
%
%       resolution - A measure of accuracy on the image,
%            typical values are within 1/100 to 1/1000 of
%            the maximum partition count.  Note that smaller
%            resolutions take longer compute time.
%
% OUTPUT:
%     error - the difference in area of each partition
%             between the actual area and the input vector
%
% EXAMPLES:
%
%     vennX( [ 106 26 257 ], .05 )
%
%     vennX( [ 75 143 210 ], .1 )
%
%     vennX( [ 16 3 10 6 19 8 3 ], .05 )
%
%
% COMMENTS:
%
%     The implementation is trivial, for the two circle case, two circles
%       are drawn to scale and moved closer and closer together until the
%       overlap is 'near' to the desired intersection. For the three
%       circle case, it is repeated three times, once for each pair of
%       circles.  Hence the two circle case is almost exact, whereas the
%       three circle case has much more error since the area |A and B and C|
%       is derived.  This means that large variations from random, especially
%       close to zero, will have larger errors, for example
%
%           vennX( [ 20 10 20 10 20 10 0], .1 )
%
%       as opposed to
%
%           vennX( [ 20 10 20 10 20 10 10], .1 )
%
% ENHANCEMENTS
%
%     The implementation could be sped up tremendously using a MRA
%     (multi-resolutional analysis) type algorithm.  e.g. start with a
%     resolution of .5 and find the distance between the circles, then use
%     that as a seed for a resolution of .1, then .05, .01, etc.
%
%     The error vector could be used as a measure to 'perturb' the position
%     of the third circle as to minimize the error.  This could be done
%     with a simple gradient descent method.  This would help the
%     exceptions described above where the distribution deviates from
%     random.
%
%     When small mishapen areas are drawn, the text does not match up, e.g.
%        vennX( [ 15 143 210 ], .1 )
%
%
%  Original implementation and method by Jeremy Heil, for the Order of
%  the Red Monkey, and the Tengu
%
%  Oct. 2004
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   figure;

   if length( data ) == 3
      dist = venn2( data(1), data(2), data(3), resolution );
      error = plot_venn2( data(1), data(2), data(3), resolution, dist );
      error = data - error';
   elseif length( data ) == 7
       %get the pairwise distance of each circle center from each other
       dist_A_B = venn2( data(1)+data(6), data(2)+data(7), data(3)+data(4), resolution );
       dist_B_C = venn2( data(3)+data(2), data(4)+data(7), data(5)+data(6), resolution );
       dist_A_C = venn2( data(1)+data(2), data(6)+data(7), data(4)+data(5), resolution );

       error = plot_venn3( data(1), data(2), data(3), data(4), data(5), data(6), data(7), ...
           resolution, dist_A_B, dist_B_C, dist_A_C );
       error = data - error';
   else
       'vennX error, data vector must be of length 3 or 7'
   end

    %change the colormap so that the background is white
    k = colormap;
    k = [ 1 1 1; k ];
    colormap(k)
    axis off

function error = plot_venn3( a, b, c, d, e, f, g, resolution, dist_A_B, dist_B_C, dist_A_C )

    r1 = sqrt( (a+b+f+g)/pi );
    r2 = sqrt( (b+c+d+g)/pi );
    r3 = sqrt( (d+e+f+g)/pi );

    %
    % Using a little geometry, think of the three circle's centers
    % as vertecies of a triangle.
    %
    y = ( dist_A_C^2 - dist_B_C^2 + dist_A_B^2 ) / 2 / dist_A_B;

    size_x = max( r1 + dist_A_B + r2, 2*r3 );
    size_y = max( r1, r2 ) + sqrt( dist_A_C^2 - y^2 ) + r3;

    %find the circle centers
    center1_x = r1;
    center1_y = max( r1, r2 );
    center2_x = r1 + dist_A_B;
    center2_y = center1_y;
    center3_x = r1 + y;
    center3_y = center1_y + sqrt( dist_A_C^2 - y^2 );

    [X,Y] = meshgrid( 0:resolution:size_x, 0:resolution:size_y );

    %draw the circles
    img = zeros( size(Y,1), size(Y,2) );

    img = img + 2 .* ( (X - center1_x).^2 + (Y - center1_y).^2 < r1^2 );
    img = img + 4 .* ( (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 );
    img = img + 6 .* ( (X - center3_x).^2 + (Y - center3_y).^2 < r3^2 );

    clf
    imagesc(img)
    hold on

    %add the numbers and compute the error for each partition
    error = [];

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 > r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 > r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( a ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 > r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( b ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 > r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 > r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( c ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 > r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 < r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( d ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 > r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 > r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 < r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( e ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 > r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 < r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( f ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 ), ...
           (X - center3_x).^2 + (Y - center3_y).^2 < r3^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( g ) );
    set( h, 'FontWeight', 'bold' )

function error = plot_venn2( a, b, c, resolution, dist )

    r1 = sqrt( (a+b)/pi );
    r2 = sqrt( (b+c)/pi );

    size_x = r1 + dist + r2;
    size_y = max( 2*r1, 2*r2 );

    center1_x = r1;
    center1_y = size_y/2;
    center2_x = r1 + dist;
    center2_y = size_y/2;;

    [X,Y] = meshgrid( 0:resolution:size_x, 0:resolution:size_y );

    %draw the two circles and the overlap region
    img = zeros( size(Y,1), size(Y,2) );

    img = img + 2 .* ( (X - center1_x).^2 + (Y - center1_y).^2 < r1^2 );
    img = img + 4 .* ( (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 );

    imagesc(img)
    hold on

    %
    % We want to draw the numbers at the center of mass
    % do this by computing the average x and y coordinates of
    % the center of each partition piece.
    %
    % Compute the error for each partition as the difference
    % between the area we meant to draw and the actual area
    % that was drawn
    %
    error = [];
    tmp = and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 > r2^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( a ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( b ) );
    set( h, 'FontWeight', 'bold' )

    tmp = and( ...
           (X - center1_x).^2 + (Y - center1_y).^2 > r1^2, ...
           (X - center2_x).^2 + (Y - center2_y).^2 < r2^2 );
    [ i,j ] = find( tmp > 0 );
    error = [ error; sum(sum(tmp)) * resolution^2 ];
    text_x = mean(j);
    text_y = mean(i);
    h = text( text_x, text_y, num2str( c ) );
    set( h, 'FontWeight', 'bold' )

function dist = venn2( a, b, c, resolution )
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %VENN2
    %  dist = venn2( a, b, c, resolution )
    %
    % Computes the distance between the centers of
    % the two venn diagram circles.
    %
    % a          - values of A
    % b          - value of A and B
    % c          - value of B
    % resolution - measure of error
    %
    % dist       - the distance between the two centers
    %
    %  Does this by plotting the two circles in an
    % image with the specified resolution and
    % moving the centers towards each other until
    % the area of intersection is nearest the value
    % of b
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    r1 = sqrt( (a+b)/pi );
    r2 = sqrt( (b+c)/pi );

    size_x = 2*r1+2*r2;
    size_y = max( 2*r1, 2*r2 );

    center1_x = r1;
    center1_y = size_y/2;
    center2_x = 2*r1 + r2;
    center2_y = size_y/2;;

    [X,Y] = meshgrid( 0:resolution:size_x, 0:resolution:size_y );

    for new_center = (2*r1 + r2):-resolution:r1

        img = zeros( size(Y,1), size(Y,2) );
        img = and( (X - center1_x).^2 + (Y - center1_y).^2 < r1^2, ...
            (X - new_center).^2 + (Y - center2_y).^2 < r2^2 );

        if sum(sum(img)) * resolution^2 > b
            break
        end
    end

    dist = new_center - center1_x;


function [MOIndex] = lipschitz(u, y, maxlag, model, fig)
% A method to determine the lag space, based on Lipschitz quotients
%
%% Syntax
% [MOIndex] = lipschitz(u, y, maxlag)
%
%% Description
%  Given a set of corresponding inputs and outputs the function calculates
%  so called Lipschitz number for each combination of m and l where m
%  represents the number of delayed outputs, and l the number of delayed
%  inputs for the case of dynamic system: y(t) = f(y(t-1),...,y(t-l),
%  u(t-1),..., u(t-m)).
%  To small m and l result in a large Lipschitz nuber, while to large lag
%  spaces do not have greater effect on the Lipschitz nuber. In order to
%  determine the proper lag space we have to look for the knee point, where
%  Lipscitz number stops decreasing.
%
% Input:
% * u       ... the system input(column vector)
% * y       ... the system output(column vector)
% * maxlag  ... the max lag space to investigate
% * model   ... optional - 'arx' if we only want to investigate m = l case
%
% Output:
% * MOIndex ... the maxlag by maxlag matrix containing calculated Lipscitz
%               numbers (Model order index) for each combination of m and l

%% Signature
% Written by Tomaz Sustar
% Based on the algorithm by Xiangdong He and Haruhiko Asada

if(nargin<4), model='unknown'; end;

NN = length(y);                                         % number of samples
MOIndex = zeros(maxlag);                    % matrix of lipschitz's indexes

for m=1:maxlag,                                 % number of delayed outputs
  % m,
  for l=0:maxlag,                                 % number of delayed inputs

    % if we are investigating arx model srtucture only, we calculate MOIndex only when m = l
    if(strcmp(model, 'arx') && l ~= m), continue; end;

    lag = max(l,m);       % the greater from m, l
    % Because of the lag we can construct only NN - lag input output pairs
    N    = NN-lag;    % number of input - output pairs.
    p    = floor(0.02*N); % number of Lipschitz quotients used to determine model order index

    [input target] = construct([m l], u, y); % construct regressors and target

    % calculation of Lipschitz quotients

    Q = zeros(N);      % initialize Q matrix for storing Lipschitz qotients

    for i=1:N-1,
      % for each input/output pair calculate the their Lipschitz quotients all
      % further inputs/outputs pairs. In this way all possible Lipschitz
      % quotients q(i,j) are calculated.

      Q(i,i+1:N)=(target(i)-target(i+1:N)).^2 ./ ...
       sum((repmat(input(i,:), N-i, 1)-input(i+1:N,:)).^2, 2);

    end

    Q_max = Q(Q~=0);                                         % remove zeros
    Q_max = (-sort(-Q_max(:)));        % sort qoutients in descending order
    Q_max = sqrt(Q_max(1:p));                  % take p - largest quotients

    n = m+l;
    MOIndex(m,l+1)=prod(sqrt(n)*Q_max)^(1/p); % calculates order index and stores it to the matrix

  end % end for l

end % end for m

% draw some figures

if(~strcmp(model, 'arx'))

  figure('Name', 'Model order index vs. lag space')
  surf(1:maxlag, 0:maxlag,MOIndex');
  view([-600 40]);
  set(gca, 'Zscale','log');
  set(gca, 'XTick', 1:maxlag)
  set(gca, 'XTick', 1:maxlag)
  xlabel('l - number of past outputs')
  ylabel('m - number of past inputs')
  zlabel('Model Order Index')
end

if(nargin > 4)
  figure(fig);
else
  figure('Name', 'Model order index vs. lag space - arx case')
end
semilogy(diag(MOIndex));
xlabel('m = l - number of past inputs and outputs');
ylabel('Model order index');
set(gca, 'XTick', 1:maxlag);
grid on;


function [G1,Gd1,Wd,Wn,Juu,Jud]=randcase(ny,nu,nd)
% RANDCASE  A random case for self-optimizing control
%
%   [G,Gd,Wd,Wn,Juu,Jud] = randcase(ny,nu,nd) produces matrices of a random
%   case for self-optimizing control corresponding to the following
%   optimizing control problem:
%
%   min J(y,u,d)
%   s.t.  y = G*u + Gd*Wd*d + Wn*e
%
%   with Juu = \partial^2 J/\partial u \partial u
%        Jud = \partial^2 J/\partial u \partial d
%
%  These matrices can then be used to test the b3wc program.
%
%  See also b3wc, pb3wc, b3av, pb3av

%  By Yi Cao at Cranfield University, 9th January 2009; 23rd February 2010.
%

% Example.
%{
ny=30;
nu=15;
nd=5;
[G,Gd,Wd,Wn,Juu,Jud] = randcase(ny,nu,nd);
[B,sset,ops,ctime] = b3wc(G,Gd,Wd,Wn,Juu,Jud);
[B1,sset1,ops1,ctime1] = pb3wc(G,Gd,Wd,Wn,Juu,Jud,20);
%}
G1=randn(ny,nu);
Gd1=rand(ny,nd);
Wd=diag(rand(nd,1));
Wn=diag(rand(ny,1));
x=randn(nu,nu+2*ny+nd);
Juu=diag(sum(x.*x,2));
Jud=rand(nu,nd);


function	Xcov = embed_covariance(X,D,tau)
% Covariance matrix in time delay embedding space
%  Xcov = embed_covariance(X,D,tau)
% --- Input
%  X : input signal : [Xdim x Tsample x Ntrial]
%  D : time embedding dimension  (integer)
%  tau : delay time in sample number (integer)
% --- Output
%  Xcov([i,t1],[j,t2]) = Xtau([i,t1],:) * Xtau([j,t2],:)'
%  Xtau([i,t0],t) = X(i ,t + tau*(D - t0)) : [(Xdim*D) x T x Ntrial]
%  T = Tsample - tau*(D-1)
%
% 2008-5-22 Masa-aki Sato

[N ,Tall, Nr] = size(X);

Tdelay = tau*(D-1);

T = Tall - Tdelay;

% Time delayed embedding index
Tbgn = Tdelay + 1 - (0:tau:Tdelay);
Tend = Tbgn + T - 1;

% X-dim index
Iend = (1:D)*N;
Ibgn = Iend - N + 1;

Xcov = zeros(N*D,N*D);

for i=1:D
  for j=1:i
  	XX = reshape(X(:,Tbgn(i):Tend(i),:), N,T*Nr) ...
  	   * reshape(X(:,Tbgn(j):Tend(j),:), N,T*Nr)';

  	Xcov(Ibgn(i):Iend(i), Ibgn(j):Iend(j)) = XX;
  	Xcov(Ibgn(j):Iend(j), Ibgn(i):Iend(i)) = XX';
  end
end

Xcov = (Xcov + Xcov')/2;


function geometry_test0803 ()

%*****************************************************************************80
%
%% TEST0803 tests POLYGON_INRAD_DATA_2D, POLYGON_OUTRAD_DATA_2D, POLYGON_SIDE_DATA_2D;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 March 2009
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST0803\n' );
  fprintf ( 1, '  For a REGULAR polygon in 2D:\n' );
  fprintf ( 1, '  the inradius, outradius and side are related.\n' );
  fprintf ( 1, '  POLYGON_INRAD_DATA_2D uses the inradius;\n' );
  fprintf ( 1, '  POLYGON_OUTRAD_DATA_2D uses the inradius;\n' );
  fprintf ( 1, '  POLYGON_SIDE_DATA_2D uses the inradius;\n' );

  for n = 3 : 5

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Number of polygonal sides = %d\n', n );

    side = 1.0;

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Assuming SIDE = %f\n', side );

    [ area, radin, radout ] = polygon_side_data_2d ( n, side );

    fprintf ( 1, '    AREA =   %f\n', area );
    fprintf ( 1, '    RADIN =  %f\n', radin );
    fprintf ( 1, '    RADOUT = %f\n', radout );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Assuming RADIN = %f\n', radin );

    [ area, radout, side ] = polygon_inrad_data_2d ( n, radin );

    fprintf ( 1, '    AREA =   %f\n', area );
    fprintf ( 1, '    RADOUT = %f\n', radout );
    fprintf ( 1, '    SIDE =   %f\n', side );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Assuming RADOUT = %f\n', radout );

    [ area, radin, side ] = polygon_outrad_data_2d ( n, radout );

    fprintf ( 1, '    AREA =   %f\n', area );
    fprintf ( 1, '    RADIN =  %f\n', radin );
    fprintf ( 1, '    SIDE =   %f\n', side );

  end

  return
end


function quad = piecewise_linear_product_quad ( a, b, f_num, f_x, f_v, ...
  g_num, g_x, g_v, quad_num )

%*****************************************************************************80
%
%% PIECEWISE_LINEAR_PRODUCT_QUAD: estimate piecewise linear product integral.
%
%  Discussion:
%
%    We are given two piecewise linear functions F(X) and G(X) and we wish
%    to estimate the value of the integral
%
%      INTEGRAL = Integral ( A <= X <= B ) F(X) * G(X) dx
%
%    The functions F(X) and G(X) are defined as tables of coordinates X and
%    values V.  A piecewise linear function is evaluated at a point X by
%    evaluating the interpolant to the data at the endpoints of the interval
%    containing X.
%
%    It must be the case that A <= B.
%
%    It must be the case that the node coordinates F_X(*) and G_X(*) are
%    given in ascending order.
%
%    It must be the case that:
%
%      F_X(1) <= A and B <= F_X(F_NUM)
%      G_X(1) <= A and B <= G_X(G_NUM)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the limits of integration.
%
%    Input, integer F_NUM, the number of nodes for F.
%
%    Input, real F_X(F_NUM), the node coordinates for F.
%
%    Input, real F_V(F_NUM), the nodal values for F.
%
%    Input, integer G_NUM, the number of nodes for G.
%
%    Input, real G_X(G_NUM), the node coordinates for G.
%
%    Input, real G_V(G_NUM), the nodal values for G.
%
%    Input, integer QUAD_NUM, the number of quadrature points.
%
%    Output, real QUAD, an estimate for the integral of F(X) * G(X)
%    from A to B.
%
  quad = 0.0;

  f_left = 1;
  g_left = 1;

  a2 = a;
  a2 = max ( a2, f_x(1) );
  a2 = max ( a2, g_x(1) );

  b2 = b;
  b2 = min ( b2, f_x(f_num) );
  b2 = min ( b2, g_x(g_num) );

  for i = 1 : quad_num

    xq =  ( (                2 * i - 1 ) * b2 ...
          + ( 2 * quad_num - 2 * i + 1 ) * a2 )  ...
          / ( 2 * quad_num             );

    f_left = r8vec_bracket3 ( f_num, f_x, xq, f_left );

    fq = f_v(f_left) + ( xq - f_x(f_left) ) * ( f_v(f_left+1) - f_v(f_left) ) ...
      / ( f_x(f_left+1) - f_x(f_left) );

    g_left = r8vec_bracket3 ( g_num, g_x, xq, g_left );

    gq = g_v(g_left) + ( xq - g_x(g_left) ) * ( g_v(g_left+1) - g_v(g_left) ) ...
      / ( g_x(g_left+1) - g_x(g_left) );

    quad = quad + fq * gq;

  end

  quad = quad * ( b - a ) / quad_num;

  return
end


function value = r8_fall ( x, n )

%*****************************************************************************80
%
%% R8_FALL computes the falling factorial function [X]_N.
%
%  Discussion:
%
%    Note that the number of "injections" or 1-to-1 mappings from
%    a set of N elements to a set of M elements is [M]_N.
%
%    The number of permutations of N objects out of M is [M]_N.
%
%    Moreover, the Stirling numbers of the first kind can be used
%    to convert a falling factorial into a polynomial, as follows:
%
%      [X]_N = S^0_N + S^1_N * X + S^2_N * X^2 + ... + S^N_N X^N.
%
%  Formula:
%
%    [X]_N = X * ( X - 1 ) * ( X - 2 ) * ... * ( X - N + 1 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 June 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the falling factorial function.
%
%    Input, integer N, the order of the falling factorial function.
%    If N = 0, FALL = 1, if N = 1, FALL = X.  Note that if N is
%    negative, a "rising" factorial will be computed.
%
%    Output, real VALUE, the value of the falling factorial function.
%
  value = 1.0;

  arg = x;

  if ( 0 < n )

    for i = 1 : n
      value = value * arg;
      arg = arg - 1.0;
    end

  elseif ( n < 0 )

    for i = -1 : -1 : n
      value = value * arg;
      arg = arg + 1.0;
    end

  end

  return
end


function U = fracdiffdemoydelay(alpha,alphad,beta,steps)

% A demo to the article:
% I. Podlubny, A.Chechkin, T. Skovranek, YQ Chen,
% B. M. Vinagre Jara, "Matrix approach to discrete
% fractional calculus II: partial fractional differential
% equations". http://arxiv.org/abs/0811.1355
%
% This function was used in the above article for the
% numerical solution and visualization of Example 5.
% It illustrates the ease of use of the matrix approach
% to discretization of partial differential equations
% with fractional derivatives with respect to the time
% variable with delays. Delays are considered to be multiples
% of a selected time step.
%
% This function solves the time-fractional diffusion-wave equation
% containing one delayed fractional derivative:
%  0.5*u_{t}^(\alpha) (x,t) + 0.5*u_{t}^(\alphad) (x,t-tau*steps)
%        = a2 * u_{xx}^{(2)}(x,t) + f(x,t)
% under zero initial and boundary conditions
%
% For alpha=1, alphad=1, beta=2, steps=0, and f(x,t)=8
% we have the part of the test example from the book:
% W. E. Milne. "Numerical Solution of Differential Equations".
%               New York: Wiley (London: Chapman & Hall), 1953.
%
% which is the classical heat conduction equation
%  u_{t} (x,t) = a2 * u_{xx}(x,t) + f(x,t)

a2=1;       % coefficient from the diffusion equation
L = 1;      % length of spatial interval

% Number of spatial steps + 1 is:
m = 21; % 11, 21

% Number of steps in time + 1 is:
n =148; % 37, 148

h = L / (m-1);          % spatial step
tau = h^2 / (6*a2);     % time step

% generating the matrix for approximation
B1 = ban(alpha,n-1,tau)';       % alpha-th order derivative with respect to time
TD = kron(B1, eye(m));          % time derivative matrix

Bdelay = shift (ban(alphad,n-1+steps,tau)', steps); % delayed derivative of order alphad
TDdelay = kron(Bdelay, eye(m)); % delayed time derivative matrix

B2 = ransym(beta,m,h);          % beta-th order derivative with respect to X
SD = kron(eye(n-1), B2);        % spatial derivative matrix

SystemMatrix = 0.5*TD + 0.5*TDdelay- a2*SD;   % matrix corresponding to discretization
                                      % in space and time

% remove columns with '1' and 'm' from SystemMatrix
S = eliminator (m, [1 m]);
SK = kron(eye(n-1), S);
SystemMatrix_without_columns_1_m = SystemMatrix * SK';

% remove rows with '1' and 'm' from SystemMatrix_without_columns_1_m
S = eliminator (m, [1 m]);
SK = kron(eye(n-1), S);
SystemMatrix_without_rows_columns_1_m = SK * SystemMatrix_without_columns_1_m;

% Right hand side
F = 8*ones(size(SystemMatrix_without_rows_columns_1_m,1),1);

% Solution of the system
Y = SystemMatrix_without_rows_columns_1_m\F;

% Reshape solution array -- values for k-th time step
% are in the k-th column of YS:
YS = reshape(Y,m-2,n-1);
YS = fliplr(YS);

U = YS;

% plot graph
[rows, columns] = size(U);
U = [ zeros(1, columns); U;  zeros(1, columns)];
U = [zeros(1,m)' U];
[XX,YY]=meshgrid(tau*(0:n-1),h*(0:m-1));

mesh(XX,YY,U)
xlabel('t');
ylabel('x');
zlabel('y(x,t)');
title(['\alpha = ', num2str(alpha), ', ', ...
       ' \gamma = ', num2str(alphad), ', ', ...
       ' \beta = ', num2str(beta), ', ', ...
       ' k = ', num2str(steps) ])

set(gca, 'xlim', [0 tau*n], 'zlim', [0 1])
box on


function D = EuDist2(fea_a,fea_b,bSqrt)
%EUDIST2 Efficiently Compute the Euclidean Distance Matrix by Exploring the
%Matlab matrix operations.
%
%   D = EuDist(fea_a,fea_b)
%   fea_a:    nSample_a * nFeature
%   fea_b:    nSample_b * nFeature
%   D:      nSample_a * nSample_a
%       or  nSample_a * nSample_b
%
%    Examples:
%
%       a = rand(500,10);
%       b = rand(1000,10);
%
%       A = EuDist2(a); % A: 500*500
%       D = EuDist2(a,b); % D: 500*1000
%
%   version 2.1 --November/2011
%   version 2.0 --May/2009
%   version 1.0 --November/2005
%
%   Written by Deng Cai (dengcai AT gmail.com)

if ~exist('bSqrt','var')
    bSqrt = 1;
end

if (~exist('fea_b','var')) || isempty(fea_b)
    aa = sum(fea_a.*fea_a,2);
    ab = fea_a*fea_a';

    if issparse(aa)
        aa = full(aa);
    end

    D = bsxfun(@plus,aa,aa') - 2*ab;
    D(D<0) = 0;
    if bSqrt
        D = sqrt(D);
    end
    D = max(D,D');
else
    aa = sum(fea_a.*fea_a,2);
    bb = sum(fea_b.*fea_b,2);
    ab = fea_a*fea_b';

    if issparse(aa)
        aa = full(aa);
        bb = full(bb);
    end

    D = bsxfun(@plus,aa,bb') - 2*ab;
    D(D<0) = 0;
    if bSqrt
        D = sqrt(D);
    end
end


function [k]=fetruss(el,leng,area,c,s)
%--------------------------------------------------------------
%  Purpose:
%     Compute stiffness matrices for the 2-d truss element
%     nodal dof {u_1 v_1 u_2 v_2}
%
%  Synopsis:
%     [k]=fetruss(el,leng,area,c,s)
%
%  Variable Description:
%     k - element stiffness matrix (size of 4x4)
%     el - elastic modulus ( E )
%     leng - element length
%     area - area of truss cross-section
%----------------------------------------------------------------
% syms X1 X2 X3
k=(area*el/leng)*[c*c c*s -c*c -c*s;...
                  c*s s*s -c*s -s*s;...
                  -c*c -c*s c*c c*s;...
                  -c*s -s*s c*s s*s];

github-repos/MATLAB/Sable-mcbench-benchmarks/mcbench-benchmarks-ba13b2f0296ef49491b95e3f984c7c41fccdb6d8/12401-optimize-truss-by-fsd-and-slp/Optimize Truss by FSD and SLP/fetruss.m


function c=ref_rdgt(f,g,a,M)
%REF_RDGT  Reference Real DGT
%   Usage:  c=ref_rdgt(f,g,a,M);
%
%   Linear algebra version of the algorithm. Create big matrix
%   containing all the basis functions and multiply with the transpose.

L=size(f,1);

b=L/M;
N=L/a;

Mhalf=ceil(M/2);

F=zeros(L,M*N);

l=(0:L-1).';

for n=0:N-1

  % Do the unmodulated coefficient.
  F(:,M*n+1)=circshift(g,n*a);

  for m=1:Mhalf-1
    F(:,M*n+2*m)=sqrt(2)*cos(2*pi*m*l/M).*circshift(g,n*a);

    F(:,M*n+2*m+1)=sqrt(2)*sin(2*pi*m*l/M).*circshift(g,n*a);

  end;

  if mod(M,2)==0
    F(:,M*(n+1))=cos(pi*l).*circshift(g,n*a);
  end;

end;

% dot-transpose will work because F is real.
c=F.'*f;