function [N,errL2,errH1,erruIuh] = cubePoissoncvtmeshnew
% CUBEPOISSON solves Poisson equation in a cube.
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

close all; clear all;
%% Parameters
maxIt = 4; N = zeros(maxIt,1);
errL2 = zeros(maxIt,1); errH1 = zeros(maxIt,1); erruIuh = zeros(maxIt,1);

%% Get the data of the pde
pde = sincosdata3;
% pde = polydata3;

%% Finite Element Method
for k = 1:maxIt
    [node,elem] = cvtuniformmesh(2^k);
    % solve the equation
    option.solver = 'direct';
    [u,Du,A,eqn] = Poisson3(node,elem,pde,[],[],option);
    N(k) = size(node,1);
    % compute error
    errL2(k) = getL2error3(node,elem,pde.exactu,u);
    errH1(k) = getH1error3(node,elem,pde.Du,Du);
    uI = pde.exactu(node);  % nodal interpolation
    erruIuh(k) = sqrt((u-uI)'*eqn.AD*(u-uI));
end

%% Plot convergence rates
figure(2);
r1 = showrate(N,errH1,2,'-*');
hold on;
r2 = showrate(N,errL2,2,'k-+');
r3 = showrate(N,erruIuh,2,'m-+');
legend('||Du-Du_h||',['N^{' num2str(r1) '}'], ...
       '||u-u_h||',['N^{' num2str(r2) '}'], ...
       '||DuI-Du_h||',['N^{' num2str(r3) '}'], 'LOCATION','Best');
%%
% The error in H1 and L2 norm converges at optimal rate. But no
% superconvergence on criss-cross grids.
end


% Mathematics Q454519
% https://math.stackexchange.com/questions/454519
% Least Squares with L2 Linear Norm Regularization (Not Squared)
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     22/08/2017
%   *   First release.

%% General Parameters

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = OFF;

%% Simulation Parameters

numRows     = 4;
paramBeta   = 0.5;

numIterations   = 25;

%% Generate Data

vU = randn([numRows, 1]);
vX = 1 + rand([numRows, 1]);

mX = diag(1 ./ vX);

%% Solution by CVX

cvx_begin('quiet')
    cvx_precision('best');
    variable vW(numRows)
    minimize( (0.5 * sum_square(vW - vU)) + (paramBeta * norm(vW ./ vX)) )
cvx_end

disp([' ']);
disp(['CVX Solution Summary']);
disp(['The CVX Solver Status - ', cvx_status]);
disp(['The Optimal Value Is Given By - ', num2str(cvx_optval)]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vW.'), ' ]']);
disp([' ']);

%% Solution by Iterative Reweighted Least Squares (IRLS)

hObjFun = @(vW) (0.5 * sum((vW - vU) .^ 2)) + (paramBeta * norm(vW ./ vX));

vObjVal = zeros([numIterations, 1]);

vW = vU;
vObjVal(1) = hObjFun(vW);

for ii = 2:numIterations

    % Calculation of the inverse term. Since all diagonlas terms can be
    % done using vectors.
    fctrTerm    = paramBeta / norm(vW ./ vX);
    vXX         = (1 ./ (vX .^ 2));
    vInvXX      = 1 ./ ((fctrTerm * vXX) + ones([numRows, 1]));

    vW = vInvXX .* vU;

    vObjVal(ii) = hObjFun(vW);
end

disp([' ']);
disp(['Iterative Reweighted Least Squares (IRLS) Solution Summary']);
disp(['The Optimal Value Is Given By - ', num2str(vObjVal(numIterations))]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vW.'), ' ]']);
disp([' ']);

hFigure     = figure('Position', figPosLarge);
hAxes       = axes();
hLineSeries = plot(1:numIterations, [vObjVal, cvx_optval * ones([numIterations, 1])]);
set(hLineSeries, 'LineWidth', lineWidthNormal);
set(hLineSeries(2), 'LineStyle', ':');
set(get(hAxes, 'Title'), 'String', ['Objective Function Value vs. Iteration'], ...
    'FontSize', fontSizeTitle);
set(get(hAxes, 'XLabel'), 'String', 'Iteration Number', ...
    'FontSize', fontSizeAxis);
set(get(hAxes, 'YLabel'), 'String', 'Objective Function Value', ...
    'FontSize', fontSizeAxis);
set(hAxes, 'XLim', [1, numIterations]);
hLegend = ClickableLegend({['IRLS'], ['Optimal Value (CVX)']});
set(hAxes, 'LooseInset', [0.07, 0.07, 0.07, 0.07]);

if(generateFigures == ON)
    saveas(hFigure,['Figure', num2str(figureIdx, figureCounterSpec), '.png']);
end

%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);


function z = snowflake(n,a)
%SNOWFLAKE Koch Snowflake Curve
%   Z = SNOWFLAKE(N,A) is a closed curve in the complex plane
%   with 3*2^N+1 points. N is a nonnegative integer and A is a
%   complex number with |A| < 1 and |1-A| < 1.
%   Default is A = 1/2 + i*sqrt(3)/6.
%
%   % Examples
%   plot(snowflake(10)), axis equal
%   plot(snowflake(10,0.45+0.35i)), axis equal

%   Author: Jonas Lundgren <splinefit@gmail.com> 2010

if nargin < 1, n = 0; end
if nargin < 2, a = 1/2 + sqrt(-3)/6; end

% Constants
b = 1 - a;
c = 1/2 + sqrt(-3)/2;
d = 1 - c;

% Generate point sequence
z = 1;
for k = 1:n
    z = conj(z);
    z = [a*z; b*z+a];
end

% Close snowflake
z = [0; z; 1-c*z; 1-c-d*z];


function [ as, bs, cs ] = sphere01_triangle_vertices_to_sides ( v1, v2, v3 )

%*****************************************************************************80
%
%% SPHERE01_TRIANGLE_VERTICES_TO_SIDES computes spherical triangle sides on unit sphere.
%
%  Discussion:
%
%    We can use the ACOS system call here, but the ARC_COSINE routine
%    will automatically take care of cases where the input argument is
%    (usually slightly) out of bounds.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 September 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real V1(3), V2(3), V3(3), the vertices of the spherical
%    triangle.
%
%    Output, real AS, BS, CS, the (geodesic) length of the sides
%    of the triangle.
%
  as = r8_acos ( v2(1:3)' * v3(1:3) );
  bs = r8_acos ( v3(1:3)' * v1(1:3) );
  cs = r8_acos ( v1(1:3)' * v2(1:3) );

  return
end


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni
%
%
%
% periodic signals

t=1:5;
x=sin(t);
T=2*pi;
for k=1:10
xk(k,:)=sin(t+k*T);
end
xk

%Sum of periodic continuous time signals
 t=0:.1:6*pi;
 x=cos(t)+sin(3*t);
 plot(t,x)

 %	Construction of periodic signals
 figure
 [s,t]=gensig('square',3,20,0.01);
 plot(t,s)
 ylim([-.3 1.3])

 figure
 [s,t]=gensig('pulse',2,10);
 plot(t,s)
 ylim([-.3 1.3])

 figure
 t=0:0.1:10;
 s=square(t);
 plot(t,s);
 ylim([-1.3 1.3])

 figure
 s2=square(2*pi*t);
 plot(t,s2);
 ylim([-1.3 1.3]) ;

 figure
 t=0:0.1:20;
 s=sawtooth(t);
 plot(t,s);
 ylim([-1.3 1.3])

 figure
 t=0:.1:10;
 x=t.*exp(-t);
 xp=repmat(x,1,8);
 tp=linspace(0,80,length(xp));
 plot(tp,xp)

 figure
 N=10;
 x=[1 1 -1 -1];
 xp=repmat(x,1,N);
 n=0:length(xp)-1;
 stem(n,xp);


function [V3D] = Vandermonde3D(N, r, s, t);

% function [V3D] = Vandermonde3D(N, r, s, t);
% Purpose : Initialize the 3D Vandermonde Matrix, V_{ij} = phi_j(r_i, s_i, t_i);

V3D = zeros(length(r),(N+1)*(N+2)*(N+3)/6);

% Transfer to (a,b) coordinates
[a, b, c] = rsttoabc(r, s, t);

% build the Vandermonde matrix
sk = 1;

for i=0:N % old ordering
  for j=0:N - i
    for k=0:N - i - j
      V3D(:,sk) = Simplex3DP(a,b,c,i,j,k);
      sk = sk+1;
    end
  end
end
return;


function [ a, b, c, d ] = plane_normal2imp_3d ( pp, normal )

%*****************************************************************************80
%
%% PLANE_NORMAL2IMP_3D converts a normal form plane to implicit form in 3D.
%
%  Discussion:
%
%    The normal form of a plane in 3D is
%
%      PP, a point on the plane, and
%      N, the unit normal to the plane.
%
%    The implicit form of a plane in 3D is
%
%      A * X + B * Y + C * Z + D = 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real PP(3), a point on the plane.
%
%    Input, real NORMAL(3), the unit normal vector to the plane.
%
%    Output, real A, B, C, D, the implicit plane parameters.
%
  a = normal(1);
  b = normal(2);
  c = normal(3);
  d = - a * pp(1) - b * pp(2) - c * pp(3);

  return
end


function [u,X,T,uf,t]=forcmove(a,v,tmax,nt)

% [u,X,T,uf,t]=forcmove(a,v,tmax,nt)
% See Article 9.4
% This function computes the dynamic response
% of a taut string subjected to a force moving
% along the string with constant speed. The
% string is fixed at x=0 and and x=+infinity.
% The system is initially at rest when the
% force is imposed at the left end and moves
% to the right at constant speed. If the force
% speed is larger than the wave propagation
% speed, then no disturbance occurs ahead of
% the force. If the force moves slower than the
% wave propagation speed, then the deflection
% propagates ahead of the force at the speed
% of wave propagation.
%
% v     - speed of the moving load
% a     - speed of wave propagation in the
%         string
% tmax  - maximum time for which the
%         solution is computed
% u     - matrix of deflection values where
%         time and position vary row-wise and
%         column-wise, respectively
% T,X   - matrices of time and position values
%         corresponding to the deflection
%         matrix U
% uf    - deflection values where the force acts
% t     - vector of times (same as colunms of T)

if nargin==0, a=.8; v=1; tmax=10; nt=15; end

% Obtain solution values and plot results
[u,X,T,uf,t]=ustring(a,v,tmax,nt);
if a>v, xf=X(:,2); uf=u(:,2); xw=X(:,3);
else, xf=X(:,3); uf=u(:,3); end
close, subplot(211)
waterfall(X,T,-u), xlabel('x axis')
ylabel('time'), zlabel('deflection')
titl=['INVERTED MOTION SURFACE FOR  A = ',...
      num2str(a),'  AND  V = ',num2str(v)];
title(titl), grid on, hold on
plot3(xf,t,-uf,'.k',xf,t,-uf,'k')
colormap([0 0 0]), view([-10,30]), shg
umin=min(u(:)); umax=max(u(:)); xmax=X(1,4);
range=[0,xmax,2*umin,2*umax]; hold on
Titl='T = %4.2f'; subplot(212) , axis off

% Use a dense set of points for animation
nt=80; [uu,XX,TT,uuf,tt]=ustring(a,v,tmax,nt);
umax=max(abs(uu(:))); uu=uu/umax; uuf=uuf/umax;
XX=XX/xmax; range=[0,1,-1,0.5]; h=.4;
arx=h*[0,.02,-.02,0,0]; ary=h*[0,.25,.25,0,1];
for j=1:nt
   uj=uu(j,:); xj=XX(j,:);
   xfj=v/xmax*tt(j); ufj=uuf(j);
   plot(xj,uj,'k',xfj+arx,ufj+ary,'-k')
   axis off, time=(sprintf(Titl,tt(j)));
   text(.45,.25,time), axis(range), drawnow
   pause(.05), figure(gcf), if j<nt, cla, end
end
hold off;

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

function [u,X,T,uf,t]=ustring(a,v,tmax,nt)
% [u,X,T,uf,t]=ustring(a,v,tmax,nt)
% This function computes the deflection u(x,t)
% of a semi-infinite string subjected to a
% moving force. The equation for the normalized
% deflection
% u(x,t)=1/a/(a^2-v^2)*((v-a-v*abs(x-a*t)...
%                           +a*abs(x-v*t));
% a    - speed of wave propagation in the string
% v    - speed of the force moving to the right
% tmax - maximum time for computing the solution
% nt   - number of time increments computed
% uu   - array of displacement values normalized
%        by dividing by a factor equal to the force
%        magnitude over twice the density per unit
%        length. Position varies column-wise and
%        time varies row-wise in the array.
% X,T  - position and time arrays for the solution
% uf   - deflection vector under the force
% t    - time vector for the solution (same as the
%        columns of T)
%
t=linspace(0,tmax,nt)'; xmax=1.05*tmax*max(a,v);
u=zeros(nt,4); nx=4; X=zeros(nt,nx); X(:,nx)=xmax;
c=1/a/(a^2-v^2); xw=a*t; xf=v*t; T=repmat(t,1,4);
uw=c*xw*(v-a+abs(v-a)); uf=c*xf*(v-a-abs(v-a));
if a>v
   X(:,2)=xf; X(:,3)=xw; u(:,2)=uf;
else
   X(:,2)=xw; X(:,3)=xf; u(:,2)=uw;
end


function variance = semicircular_variance ( a, b )

%*****************************************************************************80
%
%% SEMICIRCULAR_VARIANCE returns the variance of the Semicircular PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 < B.
%
%    Output, real VARIANCE, the variance of the PDF.
%
  variance = b * b / 4.0;

  return
end


function [ ndp, xdp, ydp ] = dif_deriv ( nd, xd, yd )

%*****************************************************************************80
%
%% DIF_DERIV computes the derivative of a polynomial in divided difference form.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 June 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Carl deBoor,
%    A Practical Guide to Splines,
%    Springer, 2001,
%    ISBN: 0387953663,
%    LC: QA1.A647.v27.
%
%  Parameters:
%
%    Input, integer ND, the size of the input table.
%
%    Input, real XD(ND), the abscissas for the divided
%    difference table.
%
%    Input, real YD(ND), the divided difference table.
%
%    Output, integer NDP, the size of the output table, which is ND-1.
%
%    Input, real XDP(NDP), the abscissas for the divided
%    difference table for the derivative.
%
%    Output, real YDP(NDP), the divided difference
%    table for the derivative.
%

%  Using a temporary copy of the difference table, shift the
%  abscissas to zero.
%
  xd_temp(1:nd) = xd(1:nd);
  yd_temp(1:nd) = yd(1:nd);

  [ xd_temp, yd_temp ] = dif_shift_zero ( nd, xd_temp, yd_temp );
%
%  Construct the derivative.
%
  ndp = nd - 1;

  xdp(1:ndp) = 0.0;

  for i = 1 : ndp
    ydp(i) = i * yd_temp(i+1);
  end

  return
end


%% UNO Rosenbrock
clc
%Objective
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
x0 = [0 1]';

opts = [];
opts.algorithm = nloptSolver('LN_PRAXIS');
opts.maxfeval = 1000;
opts.maxtime = 1;
opts.display = 2;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% UNO Rosenbrock [GRAD]
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.gradient = @(x) mklJac(nlprob.objective,x);
x0 = [0 1]';

opts = [];
opts.algorithm = nloptSolver('LD_LBFGS');
opts.maxfeval = 100;
opts.maxtime = 1;
opts.display = 2;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% BOUNDED Rosenbrock
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.lb = [-5;-5];
nlprob.ub = [1;0.8];
x0 = [0 0]';

opts = [];
opts.algorithm = nloptSolver('LN_PRAXIS');
opts.maxfeval = 1000;
opts.maxtime = 10;
opts.display = 2;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% BOUNDED GRAD Rosenbrock
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.gradient = @(x) mklJac(nlprob.objective,x);
nlprob.lb = [-5;-5];
nlprob.ub = [1;0.8];
x0 = [0 0]';

opts = [];
opts.algorithm = nloptSolver('LD_LBFGS');
opts.maxfeval = 1000;
opts.maxtime = 10;
opts.display = 2;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% NLCON HS71
clc
%Objective
obj = @(x) x(1)*x(4)*sum(x(1:3)) + x(3);
%Linear Constraints
lb = ones(4,1);
ub = 5*ones(4,1);
%Nonlinear Constraints
nlcon = @(x) [prod(x); sum(x.^2)];

nlprob =[];
nlprob.objective = obj;
nlprob.nlcon = nlcon;
nlprob.nlrhs = [25;40];
nlprob.nle = [1;0];
nlprob.lb = lb;
nlprob.ub = ub;

opts = [];
opts.algorithm = nloptSolver('LN_COBYLA');
opts.maxfeval = 1000;
opts.maxtime = 2;
opts.display = 2;
nlprob.options = opts;

x0 = zeros(4,1);

[x,f,e,i] = nlopt(nlprob,x0,opts)

%% NLCON GRAD HS71
%Objective & Gradient
obj = @(x) x(1)*x(4)*sum(x(1:3)) + x(3);
grad = @(x) [ x(1)*x(4) + x(4)*sum(x(1:3));
              x(1)*x(4);
              x(1)*x(4) + 1;
              x(1)*sum(x(1:3)) ];
%Linear Constraints
lb = ones(4,1);
ub = 5*ones(4,1);
%Nonlinear Constraints
nlcon = @(x) [prod(x); sum(x.^2)];
nljac = @(x) [prod(x)./x'; 2*x'];

nlprob =[];
nlprob.objective = obj;
nlprob.gradient = grad;
nlprob.nlcon = nlcon;
nlprob.nljac = nljac;
nlprob.nlrhs = [25;40];
nlprob.nle = [1;0];
nlprob.lb = lb;
nlprob.ub = ub;

opts = [];
opts.algorithm = nloptSolver('LD_SLSQP');
opts.maxfeval = 1000;
opts.maxtime = 2;
opts.display = 2;
nlprob.options = opts;

x0 = [1 5 5 1]';

[x,f,e,i] = nlopt(nlprob,x0,opts)

%% NLP1 Hock & Schittkowski #71
clc
%Objective & Gradient
obj = @(x) x(1)*x(4)*sum(x(1:3)) + x(3);
grad = @(x) [ x(1)*x(4) + x(4)*sum(x(1:3));
              x(1)*x(4);
              x(1)*x(4) + 1;
              x(1)*sum(x(1:3)) ];
%Linear Constraints
lb = ones(4,1);
ub = 5*ones(4,1);
%Nonlinear Constraints
nlcon = @(x) [ prod(x);
               sum(x.^2)];
nljac = @(x) [ prod(x)./x';
                2*x' ];
nlrhs = [25 40]';
nle = [1 0]'; % (>=, ==)
%Setup Options
opts = optiset('solver','nlopt','warnings','on','display','iter','solverOpts',nloptset('algorithm','LD_SLSQP'));
%Build & Solve
Opt = opti('obj',obj,'grad',grad,'nlmix',nlcon,nlrhs,nle,'nljac',nljac,'bounds',lb,ub,'options',opts)
x0 = [1 5 5 1]';
[x,fval,exitflag,info]= solve(Opt,x0)

%% LP [-31.4]
clc
% clear all
%Objective & Constraints
f = -[6 5]';
A = ([1,4; 6,4; 2, -5]);
b = [16;28;6];

nlprob = [];
nlprob.objective = @(x) f'*x;
nlprob.gradient = @(x) f;

nlprob.nlcon = @(x) A*x;
nlprob.nljac = @(x) A;
nlprob.nlrhs = b;
nlprob.nle = [-1;-1;-1];

nlprob.lb = [0;0];
nlprob.ub = [10;10];

opts = [];
opts.algorithm = nloptSolver('LD_SLSQP');
opts.maxfeval = 100;
opts.maxtime = 2;
opts.display = 2;
nlprob.options = opts;

x0 = [0;0];

[x,f,e,i] = nlopt(nlprob,x0)

%% LP1
clc
%Objective & Constraints
f = -[6 5]';
A = ([1,4; 6,4; 2, -5]);
b = [16;28;6];
%Build Object
Opt = opti('obj',@(x) f'*x,'grad',@(x) f,'ineq',A,b,'bounds',[0;0],[10;10],'options',optiset('solver','nlopt','solverOpts',nloptset('algorithm','LD_SLSQP')))
%Build & Solve
[x,fval,exitflag,info] = solve(Opt,[0;0])
%Plot
plot(Opt)
%Check Solution
[ok,msg] = checkSol(Opt)

%% Auglag NLP
clc
fun = @(x) log(1+x(1)^2) - x(2);
grad = @(x)[[(2*x(1))/(x(1)^2+1)];[-1]];
nlcon = @(x) (1 + x(1)^2)^2 + x(2)^2 - 4;
nljac = @(x)[[4*x(1)*(x(1)^2+1),2*x(2)]];
nlrhs = 0;
nle = 0;
x0 = [2;2];

nlprob = [];
nlprob.objective = fun;
nlprob.gradient = grad;

nlprob.nlcon = nlcon;
nlprob.nljac = nljac;
nlprob.nlrhs = nlrhs;
nlprob.nle = nle;

opts = [];
opts.algorithm = nloptSolver('LD_AUGLAG');
opts.maxfeval = 120;
opts.maxtime = 2;
opts.display = 2;

opts.local_optimizer.algorithm = nloptSolver('LD_LBFGS');
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% Error checking
clc
clear
nlprob.objective = @(x) -1;
nlprob.lb = [-1;-1];
nlprob.ub = [1;1];

nlprob.nlcon = @(x) [-1;-1];
nlprob.nlrhs = [-1;-1];
nlprob.nle = [1;1];

nlprob.options.algorithm = 25;
x0 = [1;1];

[x,f,e,i] = nlopt(nlprob,x0)

%% Stop Val Checking
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.lb = [-5;-5];
nlprob.ub = [1;1];
x0 = [0 0]';

opts = [];
opts.algorithm = nloptSolver('LN_PRAXIS');
opts.maxfeval = 1000;
opts.maxtime = 10;
opts.display = 2;
opts.stopval = 1e-6;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% Vector Storage Checking
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.gradient = @(x) mklJac(nlprob.objective,x);
nlprob.lb = [-5;-5];
nlprob.ub = [1;0.8];
x0 = [0 0]';

opts = [];
opts.algorithm = nloptSolver('LD_LBFGS');
opts.maxfeval = 1000;
opts.maxtime = 10;
opts.display = 2;
opts.vector_storage = 1;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)

%% Initial Pop Testing
clc
%Objective
nlprob = [];
nlprob.objective = @(x) (1-x(1))^2 + 100 *(x(2)-x(1)^2)^2;
nlprob.lb = [0;0];
nlprob.ub = [1;1];
x0 = [0 0]';

opts = [];
opts.algorithm = nloptSolver('GN_CRS2_LM');
opts.maxfeval = 1000;
opts.maxtime = 10;
opts.display = 1;
opts.initial_pop = 30;
nlprob.options = opts;

[x,f,e,i] = nlopt(nlprob,x0)


function [m,v]=v_chimv(n,l,s)
%V_CHIMV approximate mean and variance of non-central chi distribution [m,v]=(n,l,s)
%
%  Inputs:	n = degrees of freedom
%           l = non-centrality parameter = sqrt(sum(mean^2)) [default 0]
%               (can be a vector or matrix to calculate many different values at once)
%           s = standard deviation of Gaussian [default 1]
%
% Outputs:  m = mean of chi distribution
%           v = variance of chi distribution
%
% If x=c+randn(n,1) is a column vector of Gaussian random numbers with mean vector c, then
% z=sqrt(x'*x) has a chi distributon with n degrees of freedom and non-centrality parameter
% l=sqrt(c'*c). The mean and variance of a chi distribution are given precisely by
%
%     m = sqrt(2)*exp(gammaln(0.5*n+0.5)-gammaln(0.5*n))*hypergeom(-0.5,0.5*n,-0.5*l^2)
%       = sqrt(pi/2) L(0.5,0.5*n-1,-0.5*l^2)
%     v = n+l^2-m^2
%
% where L(n,a,x) is the generalized Laguerre polynomial L_n^{(a)}(x) but this is very slow
% to calculate so this routine approximates these expressions.
%
% For n=1, the accuracy is high; for n>1, accuracy improves with increasing n.
% Accuracy is worst when the non-centrality parameter, l, is close to s*sqrt(n).
% Worst case errors as a function of n are:
%                       n:    1       2      3       5      10
%   worst case error in m:  1e-15   0.007  0.004  0.0015  0.0005

%      Copyright (C) Mike Brookes 2014
%      Version: $Id: v_chimv.m 4969 2014-08-05 18:24:30Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: 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
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
persistent ab pp qq nab
if isempty(ab)
    nab=200; % cache a few low values of n
    pp=[ 0.595336298258636  -1.213013700592756  -0.018016200037799   1.999986150447582 0];
    qq=[ -0.161514114798972   0.368983655790737  -0.136992134476950  -0.499681107630725 2];
    ni=1./(1:nab);
    ab=[polyval(qq,ni);polyval(pp,ni)];
end
if nargin<3
    s=1;
    if nargin<2
        l=0;
    end
end
ls=l/s;
l2=(ls).^2;
s2=s^2;
if n<=nab
    if n==1
        m=l.*(1-2*normcdf(-ls))+2*s*normpdf(-ls);
    else
        m=sqrt(l2+n-1+(ab(1,n)+ab(2,n)*l2).^(-1))*s;
    end
else
    m=sqrt(l2+n-1+(polyval(qq,1/n)+polyval(pp,1/n)*l2).^(-1))*s;
end
v=(n+l2)*s2-m.^2;


function point = intersectThreePlanes(plane1, plane2, plane3)
%INTERSECTTHREEPLANES Return intersection point between 3 planes in space.
%
%   LINE = intersectThreePlanes(PLANE1, PLANE2, PLANE3)
%   Returns the point or straight line belonging to three planes.
%   PLANE:  [x0 y0 z0  dx1 dy1 dz1  dx2 dy2 dz2]
%   POINT:  [x0 y0 z0]
%   IF rank of the coefficient matrix r1 = 3 and
%   Rank of the augmented matrix r2 = 3 return point
%   Otherwise returns point with NaN values.
%
%   See also
%   planes3d, intersectPlanes, intersectLinePlane

% ------
% Author: Roozbeh Geraili Mikola
% E-mail: roozbehg@berkeley.edu or roozbehg@live.com
% Created: 2017-09-20
% Copyright 2017-2022

% plane normal
n1 = normalizeVector3d(cross(plane1(:,4:6), plane1(:, 7:9), 2));
n2 = normalizeVector3d(cross(plane2(:,4:6), plane2(:, 7:9), 2));
n3 = normalizeVector3d(cross(plane3(:,4:6), plane3(:, 7:9), 2));

% Uses Hessian form, ie : N.p = d
% I this case, d can be found as : -N.p0, when N is normalized
d1 = dot(n1, plane1(:,1:3), 2);
d2 = dot(n2, plane2(:,1:3), 2);
d3 = dot(n3, plane3(:,1:3), 2);

% create coefficient and augmented matrices
A = [n1;n2;n3];
D = [d1;d2;d3];
AD = [n1,d1;n2,d2;n3,d3];

% calculate rank of the coefficient and augmented matrices
r1 = rank(A);
r2 = rank(AD);

% if rank of the coefficient matrix r1 = 3 and
% rank of the augmented matrix r2 = 3 return point
% and if r1 = 2 and r2 = 2 return line,
% otherwise returns point with NaN values.
if r1 == 3 && r2 == 3
    % Intersecting at a point
    point = (A\D)';
else
    point = [NaN NaN NaN];
end


function unique_num = point_tol_unique_count ( m, n, a, tol )

%*****************************************************************************80
%
%% POINT_TOL_UNIQUE_COUNT counts the tolerably unique points.
%
%  Discussion:
%
%    The input data is an M x N array A, representing the M-dimensional
%    coordinates of N points.
%
%    This function uses a simple but expensive approach.  The first point
%    is accepted as unique.  Each subsequent point is accepted as unique
%    only if it is at least a tolerance away from all accepted unique points.
%    This means the expected amount of work is O(N^2).
%
%    The output is the number of unique points in the list.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 July 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows.
%
%    Input, integer N, the number of columns.
%
%    Input, real A(M,N), the array of N columns of data.
%
%    Input, real TOL, a tolerance.
%
%    Output, integer UNIQUE_NUM, the number of unique points.
%
  unique(1:n) = 1;
  unique_num = n;

  for i = 2 : n

    for j = 1 : i - 1
      if ( unique(j) )
        dist = sqrt ( sum ( ( a(1:m,i) - a(1:m,j) ).^2 ) );
        if ( dist <= tol )
          unique(i) = 0;
          unique_num = unique_num - 1;
          break
        end
      end
    end

  end

  return
end


function npart = setpart_enum ( m )

%*****************************************************************************80
%
%% SETPART_ENUM enumerates the partitions of a set of M elements.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer M, the number of elements in the set.
%    M must be positive.  However, for the enumeration routine only,
%    it is legal to call with any value of M.
%
%    Output, integer NPART, the number of partitions of the set.
%
  if ( m < 0 )

    npart = 0;

  elseif ( m == 0 )

    npart = 1;

  else

    offset = 1;
    b(0+offset) = 1;
    for j = 1 : m
      b(j+offset) = 0;
      for i = 0 : j - 1
        b(j+offset) = b(j+offset) + i4_choose ( j - 1, i ) * b(i+offset);
      end
    end

    npart = b(m+offset);

  end

  return
end


function H =  sndspd_mean(z,ssp,d)
% harmonic_mean
%
% Val Schmidt
% Center for Coastal and Ocean Mapping
% University of New Hampshire
% 2012
%
% A routine to calculate the harmonic mean sound speed.
%
%   z:         Vector of depth values. (m)
%   ssp:       Vector of sound speed values at the associated depths. (m/s)
%   d:         [Optional] maximum depth (m) (see below)
%
% Suppose one is given a sound speed profile (sound speeds [ssp] and depths [z]).
% One wishes to know how long it will take a sound pulse (say from a sonar)
% to travel down through the water column.
%
% Most people will realize that one cannot simply average the sound speeds
% and divide by the total depth. However many will incorrectly assume that
% a depth-weighted mean sound will produce the correct answer.
% Unfortunately it does not.
%
% One must instead divide the total depth by the sum of the time it takes
% to the sound to pass through each layer of constant sound speed. This is
% called the 'harmonic mean'. The harbmonic mean is calculated like so.
%
%              |    i=n                | -1
%              |  SUM    delta z(i)    |
%              |   i=1   ---------     |
%              |            c(i)       |
% C_harmonic = |   ------------------- |
%              |    i=n                |
%              |  SUM     delta z(i)   |
%              |     i=1               |
%              |                       |
%
% When the maximum depth, 'd', is specified, two possible things may result
% depending on whether d is greater or less than the maximum depth in z.
%
% Sometimes one has a complete sound speed profile, but only needs the
% harmonic sound speed to some max depth less than the maximum depth of the
% profile. One may then specify the maximum depth as the argument 'd', and
% the function will return a harmonic mean to only that depth.
%
% Alternatively, one frequently has a sound speed profile for the upper
% portion of the water column only, but desireds a harmonic sound speed all
% the way to the bottom. Below some max depth temperature and salnity are
% constant and sound speed increases nearly linearly (to about 1 part in
% 10^4) with increasing depth. In this case, one may specify a the bottom
% depth, d. The function will then approximate the the sound speed at the
% bottom linearly from the final value in the ssp vector and calculate a
% harmonic sound speed for the entire path.
%
% When the sound speed profile is a constant linear gradient rather than
% discrete values one can calculate the time required to traverse the
% layer directly rather than approximating the gradient in discrete steps.
% That time is given by
%
%       1      c(i+1)
% t =   - ln ( ------ )
%       g       c(i)
%
% This value is then added to the summation of travel times (with a
% corresponding addition to the summation of depth differences) in the
% haronic mean calculation above.

%%

% Initialize a variable. variables
t=0;

% Mackenzie Formula first-order term for sound speed as a function of
% depth.
D1=.0163;

% Check some details.
if ( ~isequal( size(z),size(ssp) ) )
    error('ERROR input vectors are not of same size');
end

% The algorithm below will produce incorrect results if the first depth
% value is not zero. So we force it to be zero, shifting the other depths
% appropriately.
top=z(1);
z=z-top;

% One can optionally specify a max bottom depth. This value may be less
% than, or deeper than, the lowest depth in the z vector. If it is less than
% than z(end), the harmonic mean to the depth, d is calculated. If it is more
% than z(end), the sound speed profile is extended to the depth d using the
% first-order depth dependent term from the Mackenzie equation and the
% results of the Harmonic mean calculation for a gradient.

if ( nargin==3 )

    % First we shift the d value as we did the z values to make sure
    % everything matches.
    d=d-top;

    % If d is less than the max depth in z truncate the z and ssp vectors
    % to that depth.
    if (d < max(z) )
        idx=find( z <= d);
        z=z(idx);
        ssp=ssp(idx);

    % Otherwise we calculate the extra time in this final layer.
    else

    % We need the sound speed at hte specified bottom.
    ss_bottom = ssp(end) + ( d - z(end) ) * D1;

    % This is the equation for the time spent in a layer having a gradient
    % sound speed, D1, and where the difference in sound speed from the top to
    % the bottom of the layer is delta_ss.
    t= 1/D1 *log( ss_bottom / ssp(end) );

    end

else
    % Give d the max depth regardless.
    d=z(end);
end

% Calculate the harmonic mean sound speed.
H = ( (sum(diff(z)./ssp(1:(length(ssp)-1))) + t ) / d )^(-1);


function node_rhs = rhs ( node_num, node_xy )

%*****************************************************************************80
%
%% RHS gives the right-hand side of the differential equation.
%
%  Discussion:
%
%    This routine is set up for the L-shaped region, with exact solution
%    U = X^2 + Y^2.  Hence, the right hand side of the equation is
%    exactly -4.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 December 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NODE_NUM, the number of nodes.
%
%    Input, real NODE_XY(2,NODE_NUM),
%    the coordinates of the points.
%
%    Output, real NODE_RHS(NODE_NUM,1), the value of the
%    right hand side function at the points.
%
  node_rhs(1:node_num,1) = -4.0                     ...
                       + node_xy(1,1:node_num).^2 ...
                       + node_xy(2,1:node_num).^2;

  return
end


function IQR=interquartileRange(x,dim,definition)
%%INTERQUARTILERANGE Determine the interquartile range of the values in x.
%             This is notionally the difference between the value in the
%             75th percentile (the third quartile) and the 25th percentile
%             (the first quartile) of the data. However, the strict
%             definition varies, which is why there are multiple options.
%
%INPUTS: x A vector, matrix or hypermatrix of real values. The
%          interquartile range is only taken over a particular dimension.
%      dim An optional parameter specifying the dimensions across which
%          the interquartile range is found. If this value is omitted or an
%          empty matrix is passed, then the interquartile range is computed
%          across the first non-singleton dimension of x.
% definition This selects the definition fo the interquartile range that is
%          to be used. Let n be the number of points in dimension dim of x.
%          The following definitions are considering each independent
%          vector in dimension dim being processed. Possible values are:
%          0 (The default if omitted or an empty matrix is passed) If an
%            odd number of points is passed, then the first quartile is the
%            median of ordered (ascending) points up to floor(n/2) and the
%            third quartile is the median of ordered points from ceil(n/2)
%            to n. Thus, the median is assigned to the upper half. If an
%            even number of points is passed, then the first quartile is
%            the median of the ordered points up to n/2 and the third
%            quartile is the median of ordered points n/2+1 to n. Thus, the
%            halves are split.
%          1 This is the same as 0, except when given an odd number of
%            points, the middle point is omitted, not assigned to the upper
%            quartile. If only 1 point is given, 0 is returned.
%          2 This is the same as 0 and 1 except when given an odd number of
%            points, the median point is included in both the lower and the
%            upper quartile. This type of interquartile range is also known
%            as the midhinge.
%          3 The first and third quartiles are given by percentileVal with
%            its definition=0.
%          4 The first and third quartiles are given by percentileVal with
%            its definition=1.
%          5 This uses the kthOrderStat to get the 1+floor(0.25*(n-1)) and
%            1+ceil(0.75*(n-1)) order statistics.
%          6 In the set of ordered points, let the split point be
%            k50=ceil(n/2). The lower quartile value is the one at index
%            ceil(k50/2) and the upper quartile value is the one at index
%            k50+ceil((n-k50)/2). This is identical to considering the
%            points part of an empirical distribution and choosing the
%            percentiles using EmpiricalD.invCDF. If none aling directly
%            with 1/4 and 3/4, choose the next highest point.
%
%OUTPUTS: IQR The interquartile range values. This is a matrix with the
%             same dimensions as x except dimension dim has become unitary.
%             If dimension dim is a singleton, then IRQ will be zero for
%             all definitions.
%
%EXAMPLE:
%Here, one sees some of the differences:
% for def=0:6
%     IQR=interquartileRange([1,2,3,4,5],[],def)
% end
% one will get 2.5, 3, 2, 2.5, 2, 2, and 2.
%
%September 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(isempty(x))
    IQR=[];
    return;
end

%Select the first non-singleton dimension if dim is not provided.
if(nargin<2||isempty(dim))
    dim=find(size(x)>1,1);
    if(isempty(dim))
        dim=1;
    end
end

if(nargin<3||isempty(definition))
    definition=0;
end

n=size(x,dim);

if(n==1)%If the interquartile range is a singleton, then zero is returned
        %for all methods.
    IQR=zeros(size(x));
    return;
end

switch(definition)
    case 0%The definition used in Mathematica and in Matlab's IQR function.
          %The middle point for an odd number of points is assigned to the
          %third quartile.
        idxVec=repmat({':'},1,ndims(x));

        x=sort(x,dim,'ascend');
        if(mod(n,2)==0)%Split the halves
            idxVec{dim}=1:(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=(n/2+1):n;
            Q3=median(x(idxVec{:}),dim);
        else%Assign the median point to the third quartile.
            idxVec{dim}=1:floor(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=ceil(n/2):n;
            Q3=median(x(idxVec{:}),dim);
        end
    case 1%Alternative successive median definition 1.
        idxVec=repmat({':'},1,ndims(x));

        x=sort(x,dim,'ascend');
        if(mod(n,2)==0)%Split the halves
            idxVec{dim}=1:(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=(n/2+1):n;
            Q3=median(x(idxVec{:}),dim);
        else%Omit the median point.
            idxVec{dim}=1:floor(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=(ceil(n/2)+1):n;
            Q3=median(x(idxVec{:}),dim);
        end
    case 2%Alternative successive median definition 2.
        idxVec=repmat({':'},1,ndims(x));

        if(mod(n,2)==0)%Split the halves
            idxVec{dim}=1:(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=(n/2+1):n;
            Q3=median(x(idxVec{:}),dim);
        else%Include the median point in both the upper and the lower
            %quartiles.
            idxVec{dim}=1:ceil(n/2);
            Q1=median(x(idxVec{:}),dim);

            idxVec{dim}=(ceil(n/2)):n;
            Q3=median(x(idxVec{:}),dim);
        end

    case 3%The percentile definition, option 0.
        Q1=percentileVal(x,25,dim,0);
        Q3=percentileVal(x,75,dim,0);
    case 4%The percentile definition, option 1.
        Q1=percentileVal(x,25,dim,1);
        Q3=percentileVal(x,75,dim,1);
    case 5%The order statistic definition.
        [Q1,x]=kthOrderStat(x,1+floor(0.25*(n-1)),dim);
        Q3=kthOrderStat(x,1+ceil(0.75*(n-1)),dim);
    case 6
        idxVec=repmat({':'},1,ndims(x));

        x=sort(x,dim,'ascend');

        k50=ceil(n/2);
        k25=ceil(k50/2);
        k75=k50+ceil((n-k50)/2);

        idxVec{dim}=k25;
        Q1=x(idxVec{:});

        idxVec{dim}=k75;
        Q3=x(idxVec{:});
    otherwise
        error('Unknown definition of the interquartile range specified.')
end

IQR=Q3-Q1;

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.


%% Analyzing Neural Time Series Data
% Matlab code for Chapter 12
% Mike X Cohen
%
% This code accompanies the book, titled "Analyzing Neural Time Series Data"
% (MIT Press). Using the code without following the book may lead to confusion,
% incorrect data analyses, and misinterpretations of results.
% Mike X Cohen assumes no responsibility for inappropriate or incorrect use of this code.

%% Figure 12.1

load sampleEEGdata

time = -1:1/EEG.srate:1;
f = 4; % frequency of sine wave in Hz

% create sine wave (actually, a cosine wave, for reasons that will become
% clear in Chapter 13)
sine_wave = cos(2*pi*f.*time);

% make a Gaussian
s=4/(2*pi*f);
gaussian_win = exp(-time.^2./(2*s^2));

figure
plot(time,sine_wave.*gaussian_win)

%% Figure 12.2

figure
subplot(511)
plot(squeeze(EEG.data(47,:,1)))
axis tight

subplot(512)
sine_wave = cos(2*pi*12.*time);
plot(sine_wave)
axis tight

subplot(513)
% boxcar envelope
boxcar = zeros(size(sine_wave));
midpoint = (length(time)-1)/2;
boxcar(midpoint-round(EEG.srate/12/5):midpoint+round(EEG.srate/12/1.25)) = 1;
plot(sine_wave.*boxcar)
axis tight

subplot(514)
% boxcar envelope
boxcar = zeros(size(sine_wave));
midpoint = (length(time)-1)/2;
boxcar(midpoint-50:midpoint+50) = 1;
plot(sine_wave.*boxcar)
axis tight

subplot(515)
% redefine gaussian for new sine wave
s=1.5/(2*pi*12); gaussian_win = exp(-time.^2./(2*s^2));
plot(time,sine_wave.*gaussian_win)
axis tight

%% Figure 12.3

srate = 500; % sampling rate in Hz
f = 10; % frequency of the sine wave in Hz
time = -1:1/srate:1; % time, from -1 to 1 second in steps of 1/sampling-rate

sine_wave = exp(2*pi*1i*f.*time); % complex wavelet

% make a Gaussian
s=6/(2*pi*f);
gaussian_win = exp(-time.^2./(2*s^2));

% and together they make a wavelet!
wavelet = sine_wave .* gaussian_win;

% make plots containing each component
figure
subplot(311)
plot(time,real(sine_wave)) % only plot the real component... we�ll learn about this later
title('Sine wave')

subplot(312)
plot(time,gaussian_win) % plots the Gaussian window
title('Gaussian window')

subplot(313)
plot(time,real(wavelet)); % plots the wavelet
title('My first wavelet!')
xlabel('Time (ms)')

%% Figure 12.4

num_wavelets      =  80;  % number of frequency bands
lowest_frequency  =   2;  % in Hz
highest_frequency = 100;  % in Hz

frequencies=linspace(lowest_frequency,highest_frequency,num_wavelets);
% note: the "linspace" function creates linearly spaced numbers between the first and second
% inputs, with the number of steps corresponding to the third input.
figure, plot(frequencies,'-*')
xlabel('Frequency order')
ylabel('Frequency in Hz')

% initialize wavelet family
wavelet_family = zeros(num_wavelets,length(time));

% Loop through frequencies and make a family of wavelets.
for fi=1:num_wavelets

    % create a sine wave at this frequency
    sinewave = exp(2*1i*pi*frequencies(fi).*time); % the "1i" makes it a complex wavelet

    % create a Gaussian window
    gaus_win = exp(-time.^2./(2*(6/(2*pi*frequencies(fi)))^2));

    % create wavelet via element-by-element multiplication of the sinewave and gaussian window
    wavelet_family(fi,:) = sinewave.*gaus_win;

    % note that you can also do this on one line:
    wavelet_family(fi,:) = exp(2*1i*pi*frequencies(fi).*time) .* exp(-time.^2./(2*(6/(2*pi*frequencies(fi)))^2));
end

% Plot a few wavelets
figure
subplot(2,1,1)
plot(time,real(wavelet_family(1:round(rand*30):end,:))')
title('A few wavelets...')

% Note that in the subplot command you don't need commas if you have fewer than 10
% rows/cols and if you are not using any variables.
subplot(212)
plot(time,real(wavelet_family(30,:)))
hold on
plot(time,imag(wavelet_family(30,:)),':')
title('Real and imaginary parts of one wavelet')
legend({'real';'imaginary'})

% finally, image the wavelet family.
figure
imagesc(time,frequencies,real(wavelet_family))
axis xy % equivalent to "set(gca,'ydir','normal')
xlabel('Time (s)')
ylabel('Frequency (Hz)')

%% bonus feature

% Running this cell will generate a movie that shows how a line -- in this
% case, a wavelet -- goes from a line that goes up and down, to a colored
% 'flat' line in a 2-D image. This is the principle that underlies viewing
% time-frequency plots.

figure, set(gcf,'color','k')
surf(repmat(real(wavelet),2,1))
shading interp
axis off
axis([0 length(time) -20 21 -1 1])
view([ -4 4 ])

for i=4:2:90
    view([ -4 i ])
    pause(.1)
end

rotate3d

%% Figure 12.5

% EEG data from one trial (electrode FCz)
eegdata = squeeze(EEG.data(47,:,10));

% create wavelet
time = -1:1/EEG.srate:1;
f = 6; % frequency of sine wave in Hz
sine_wave = exp(1i*2*pi*f.*time);
s = 4.5/(2*pi*f);
gaussian_win = exp(-time.^2./(2*s^2));
wavelet = sine_wave .* gaussian_win;
% half of the wavelet size, useful for chopping off edges after convolution.
halfwaveletsize = ceil(length(wavelet)/2);

% convolve with data
% compute Gaussian
n_conv = length(wavelet) + EEG.pnts - 1;

fft_w = fft(wavelet,n_conv);
fft_e = fft(eegdata,n_conv);
ift   = ifft(fft_e.*fft_w,n_conv)*sqrt(s)/10; % sqrt... is an empirical scaling factor that works here
wavelet_conv_data = real(ift(halfwaveletsize:end-halfwaveletsize+1));

% create filter and apply to data
% (more on how to interpret this code in a few chapters!)
nyquist       = EEG.srate/2;
transition_width = 0.2; % percent
filter_low    = 4; % Hz
filter_high   = 8; % Hz
ffrequencies  = [ 0 filter_low*(1-transition_width) filter_low filter_high filter_high*(1+transition_width) nyquist ]/nyquist;
idealresponse = [ 0 0 1 1 0 0 ];
filterweights = firls(round(3*(EEG.srate/filter_low)),ffrequencies,idealresponse);
eeg_4to8      = filtfilt(filterweights,1,double(eegdata));

% now plot all the pieces
figure

plot(EEG.times,eegdata)
hold on
plot(EEG.times,wavelet_conv_data,'r','linew',2)
plot(EEG.times,eeg_4to8,'m','linew',2)
set(gca,'xlim',[-200 1200],'ydir','r')
xlabel('Time (ms)'), ylabel('Voltage (\muV)')
legend({'Raw data';'wavelet convolved';'band-pass filtered'},0)

%% Figure 12.6

% make a theta-band-centered wavelet
time   = -1:1/EEG.srate:1;
n_conv = EEG.pnts + length(time) - 1;
n2p1   = floor(n_conv/2)+1; % n2p1 = n/2+1

f = 6;
s = 6/(2*pi*f);
wavelet = exp(2*pi*1i*f.*time) .* exp(-time.^2./(2*s^2));
halfwaveletsize = ceil(length(wavelet)/2);

eegdata = squeeze(EEG.data(47,:,10));

figure

subplot(311)
plot(EEG.times,eegdata)
set(gca,'xlim',[-500 1200])

subplot(323)
fft_w = fft(wavelet,n_conv);
hz    = linspace(0,EEG.srate/2,n2p1);
plot(hz,abs(fft_w(1:n2p1))./max(abs(fft_w(1:n2p1))),'k')
hold on

fft_e = fft(eegdata,n_conv);
hz    = linspace(0,EEG.srate/2,n2p1);
plot(hz,abs(fft_e(1:n2p1))./max(abs(fft_e(1:n2p1))),'r')
set(gca,'xlim',[0 40],'ylim',[0 1.05])
title('individual power spectra')

subplot(324)
plot(hz,abs(fft_e(1:n2p1)).*abs(fft_w(1:n2p1)))
set(gca,'xlim',[0 40])

subplot(313)
plot(EEG.times,eegdata)
hold on
ift = ifft(fft_e.*fft_w,n_conv)*sqrt(s)/10;
plot(EEG.times,real(ift(halfwaveletsize:end-halfwaveletsize+1)),'r')
set(gca,'xlim',[-500 1200])

%% Figure 12.7

% create 10 Hz wavelet (kernel)
time = -EEG.pnts/EEG.srate/2 : 1/EEG.srate : EEG.pnts/EEG.srate/2-1/EEG.srate;
f    = 10; % frequency of sine wave in Hz
s    = 4/(2*pi*f);
wavelet = cos(2*pi*f.*time) .* exp(-time.^2./(2*s^2));

% signal is one sine cycle
timeS  = 0:1/EEG.srate:(1/f); % one cycle is 1/f
signal = sin(2*pi*f.*timeS);

% now zero-pad signal
signal = [ zeros(1,EEG.pnts/2-length(timeS)/2) signal zeros(1,EEG.pnts/2-length(timeS)/2) ];

figure

% plot waves
subplot(321)
plot(wavelet)
set(gca,'xlim',[200 length(time)-200])

subplot(323)
plot(signal)
set(gca,'xlim',[200 length(time)-200])

subplot(325)
plot(conv(wavelet,signal,'same'))
set(gca,'xlim',[200 length(time)-200],'ylim',[-12 12])

% now plot dot products at selected phase lags
subplot(322)
plot(wavelet(round(100/f)-2:end),'r')
hold on
plot(signal)
set(gca,'xlim',[200 length(time)-200])
title([ 'dot product: ' num2str( fix(sum(wavelet(round(100/f)-2:end).*signal(1:end-round(100/f)+3))) ) ])

subplot(324)
plot(wavelet(round(2.3*(100/f)-2):end),'r')
hold on
plot(signal)
set(gca,'xlim',[200 length(time)-200])
title([ 'dot product: ' num2str( fix(sum(wavelet(round(2.3*(100/f)-2):end).*signal(1:end-round(2.3*(100/f)-3))) )) ])

subplot(326)
plot(wavelet,'r')
hold on
plot(signal)
set(gca,'xlim',[200 length(time)-200])
title([ 'dot product: ' num2str( fix(sum(wavelet.*signal)) ) ])

%% end


%SE2 Create planar translation and rotation transformation
%
% T = SE2(X, Y, THETA) is an SE(2) homogeneous transformation (3x3)
% representing translation X and Y, and rotation THETA in the plane.
%
% T = SE2(XY) as above where XY=[X,Y] and rotation is zero
%
% T = SE2(XY, THETA) as above where XY=[X,Y]
%
% T = SE2(XYT) as above where XYT=[X,Y,THETA]
%
% See also TRANSL2, ROT2, ISHOMOG2, ISROT2, TRPLOT2.

% Copyright (C) 1993-2015, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB 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.
%
% RTB 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 RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function t = se2(a, b, c, varargin)

    opt.deg = false;

    opt = tb_optparse(opt, varargin);

    if length(a) == 3
        x = a(1);
        y = a(2);
        th = a(3);
    elseif length(a) == 2
        x = a(1);
        y = a(2);
        if nargin < 2
            th = 0;
        else
            th = b;
        end
    else
        x = a;
        y = b;
        if nargin < 3
            th = 0;
        else
            th = c;
        end
    end

    if opt.deg
        th = th * pi/180.0;
    end
    cth = cos(th);
    sth = sin(th);
    R = [cth -sth; sth cth];

    t = [R [x; y]; 0 0 1];


function T=dewPointTemp4Pres(p,algChoice)
%%DEWPOINTTEMP4PRES For a given partial vapor pressure of water, find the
%                   dew point temperature. that is the temperature at which
%                   the air would be saturated with water, in equilibrium.
%
%INPUTS: p The (partial) pressure of the water vapor for which the dew
%          point temperature is desired in units of Newtons per square
%          meter (Pascals).
% algChoice An optional parameter specifying the algorithm to use. The
%          choices are
%          0 The corrected version of the Clausius-Clapeyron equation for
%            use over land or in the upper air.
%          1 The empirical Magnus-type equation for use over water or in
%            the upper air (-40C to 50C temperature).
%          2 The empirical Magnus-type equation for use over ice (-80C to
%            0C temperature)
%          If algChoice is omitted, then the default value of 0, the
%          corrected Clausius-Clapeyron equation is used. Choice 0 is taken
%          from [1]. Choices 1 and 2, are taken from [2].
%
%As is the case in the function dewPointPres4Temp, which is the inverse of
%this function, formulae 0 is from [1], where the numerical inversion
%method given in equations 44 and 45 in Section 5 of the paper are used.
%
%Formulas 1 and 2 are obtained by solving for the inverse of the Magnus
%approximations given in [2]. Simple, explicit solutions for the function
%inverses can be found.
%
%Note that the function dewPointPres4Temp is the inverse of this function.
%
%REFERENCES:
%[1] D. Koutsoyiannis, "Clausius-Clapeyron equation and saturation vapour
%    pressure: simple theory reconcided with practice," European Journal of
%    Physics, vol. 33, no. 2, pp. 295-305, Mar. 2012.
%[2] O. A. Alduchov and R. E. Eskridge, "Improved Magnus Form Approximation
%    of Saturation Vapor Pressure," Journal of Applied Meteorology, vol.
%    35, no. 4, pp. 601-609, Apr. 1996.
%
%February 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2||isempty(algChoice))
    algChoice=0;
end

switch(algChoice)
    case 1
        %This evaluates the inverse of Equation 21 in the Alduchov and
        %Eskridge paper.

        p=p/100;%Convert to hectoPascals.
        logRat=log(p/6.1094);

        T=-243.04*logRat./(logRat-17.625);
        %Convert the temperature to degrees Kelvin.
        T=T-Constants.absoluteZero;
    case 2
        %This evaluates the inverse of Equation 23 in the Alduchov and
        %Eskridge paper for the saturation temperature over ice.

        p=p/100;%Convert to hectoPascals.
        logRat=log(p/6.1121);

        T=-273.86*logRat./(logRat-22.587);
        %Convert the temperature to degrees Kelvin.
        T=T-Constants.absoluteZero;
    otherwise
        %The inverse of Equation 23 in the Koutsoyiannis paper is not
        %simple to find. However, the paper provides iterative solutions in
        %the form of Equations 44 and 45 for specific values related to
        %water. For general values, the initial estimate in Equation 44 is
        %T0/T=1+1/(alpha/(R*T0)-(cL-cP)/R)*ln(p0/p);
        %and the iteration to refine the ratio is
        %T0/T_{new}=1+(R*T0/alpha)*ln(p0/p)+((cL-cP)/R)/(alpha/(R*T0))*ln(T0/T_{old})
        %where R is the specific gas constant of water vapor with units of
        %J/(kg*K), T0 is the temperature at the triple point of water, with
        %units of Kelvin, p0 is the pressure at the triple point of water
        %in hecoPascals, cP and cL are the specific heat of water vapor and
        %liquid water at constant pressure with units of J/(kg*K), and
        %alpha=L0+(cL-cP)*T0, where L0 is the latent heat of water for a
        %constant pressure at the triple point with units of J/kg.
        %
        %In the implementation here, the specific numerical from the paper
        %are used. This means that alpha has been tweaked a little bit to
        %better match their real data.

        numIter=27;

        p0=6.11657*100;%The pressure at the triple point of water in Pascals.
        T0=273.16;%The temperature at the triple point of water in Kelvin.

        LPRat=log(p0./p);

        TRat=1+1/(24.921-5.06)*LPRat;
        for curIter=1:numIter
            TRat=1+(1/(24.921))*LPRat+(5.06/24.921).*log(TRat);
        end
        T=T0./TRat;
end
end

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


function X = circle_graph_layout(G,radius)
% CIRCLE_LAYOUT Layout the vertices of a graph on a circle
%
% X = circle_layout(G) generates a layout of graph with vertices uniformly
% placed on the circle.  This function does no interesting layout and just
% places the vertices around the circle in order.
%
% X = circle_layout(G,radius) places the vertices with a radius other than
% 1.0.
%
% Example:
%   G = cycle_graph(6);
%   X = circle_graph_layout(G);
%   gplot(G,X);

% David F. Gleich
% Copyright, Stanford University, 2008

%% History
%  2008-09-25: Initial coding
%%

if ~exist('radius','var') || isempty(radius), radius = 1.0; end;
pi = 3.14159;
n = num_vertices(G);
X = zeros(n,2);
X(:,1) = radius*cos( (0:n-1)'*2*pi/n );
X(:,2) = radius*sin( (0:n-1)'*2*pi/n );


function [T2Hot1] = T2Hot1(X,alpha)
%Hotelling's T-Squared test for one multivariate sample.
%
%   Syntax: function [T2Hot1] = T2Hot1(X,alpha)
%
%     Inputs:
%          X - multivariate data matrix.
%      alpha - significance level (default = 0.05).
%
%     Output:
%          n - sample-size.
%          p - variables.
%          T2 - Hotelling's T-Squared statistic.
%          Chi-sqr. or F - the approximation statistic test.
%          df's - degrees' of freedom of the approximation statistic test.
%          P - probability that null Ho: is true.
%
%
%    Example: For the example given by Johnson and Wichern (1992, p. 183),
%             with 20 cases (n = 20) and three variables (p = 3). We are interested
%             to test if there is any difference against the expected mean vector
%             [4 50 10] at a significance level = 0.10.
%                      --------------    --------------
%                       x1   x2   x3      x1   x2   x3
%                      --------------    --------------
%                      3.7  48.5  9.3    3.9  36.9 12.7
%                      5.7  65.1  8.0    4.5  58.8 12.3
%                      3.8  47.2 10.9    3.5  27.8  9.8
%                      3.2  53.2 12.0    4.5  40.2  8.4
%                      3.1  55.5  9.7    1.5  13.5 10.1
%                      4.6  36.1  7.9    8.5  56.4  7.1
%                      2.4  24.8 14.0    4.5  71.6  8.2
%                      7.2  33.1  7.6    6.5  52.8 10.9
%                      6.7  47.4  8.5    4.1  44.1 11.2
%                      5.4  54.1 11.3    5.5  40.9  9.4
%                      --------------    --------------
%
%             Total data matrix must be:
%              X=[3.7 48.5 9.3;5.7 65.1 8.0;3.8 47.2 10.9;3.2 53.2 12.0;3.1 55.5 9.7;
%              4.6 36.1 7.9;2.4 24.8 14.0;7.2 33.1 7.6;6.7 47.4 8.5;5.4 54.1 11.3;
%              3.9 36.9 12.7;4.5 58.8 12.3;3.5 27.8 9.8;4.5 40.2 8.4;1.5 13.5 10.1;
%              8.5 56.4 7.1;4.5 71.6 8.2;6.5 52.8 10.9;4.1 44.1 11.2;5.5 40.9 9.4];
%
%     Calling on Matlab the function:
%             T2Hot1(X)
%       Immediately it ask:
%             -Do you have an expected mean vector? (y/n):
%            For this example we must to put:
%             y  (meaning 'yes')
%            Then it ask:
%             -Give me the expected mean vector:
%            Giving the mean vector:
%             [4 50 10]
%            Otherwise (n; meaning 'no') it consider a zero mean vector.
%
%       Answer is:
% ------------------------------------------------------------------------------------
% Sample-size    Variables      T2          F           df1          df2          P
% ------------------------------------------------------------------------------------
%      20            3         9.7388     2.9045          3           17        0.0649
% ------------------------------------------------------------------------------------
% Mean vectors results significant.
%
%
%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%             And the special collaboration of the post-graduate students of the 2002:2
%             Multivariate Statistics Course: Karel Castro-Morales, Alejandro Espinoza-Tenorio,
%             Andrea Guia-Ramirez.
%
%  Copyright (C) December 2002
%
%  References:
%
%  Johnson, R. A. and Wichern, D. W. (1992), Applied Multivariate Statistical Analysis.
%              3rd. ed. New-Jersey:Prentice Hall. pp. 180-181,199-200.
%

if nargin < 1,
    error('Requires at least one input argument.');
end;

if nargin < 2,
    alpha = 0.05;
end;

if (alpha <= 0 | alpha >= 1)
   fprintf('Warning: significance level must be between 0 and 1\n');
   return;
end;

[n,p]=size(X);

ask=input('Do you have an expected mean vector? (y/n): ','s');
if ask=='y'
   mu=input('Give me the expected mean vector: ');
else
   mu=zeros([1,p]);
end;

if n <= p,
   error('Warning: requires that sample-size (n) must be greater than the number of variables (p).');
   return;
else

   m=mean(X); %Mean vector from data matrix X.
   S=cov(X);  %Covariance matrix from data matrix X.
   T2=n*(m-mu)*inv(S)*(m-mu)'; %Hotelling's T-Squared statistic.

   if n >= 50 %Chi-square approximation.
      X2=T2;
      v=p; %Degrees of freedom.
      P=1-chi2cdf(X2,v); %Probability that null Ho: is true.
      disp(' ')
      fprintf('----------------------------------------------------------------------------\n');
      disp(' Sample-size    Variables      T2          Chi-sqr.         df          P')
      fprintf('----------------------------------------------------------------------------\n');
      fprintf('%8.i%13.i%15.4f%14.4f%11.i%14.4f\n\n',n,p,T2,X2,v,P);
      fprintf('----------------------------------------------------------------------------\n');
      if P >= alpha;
         disp('Mean vectors results not significant.');
      else
         disp('Mean vectors results significant.');
      end;
   else  %F approximation.
      F=(n-p)/((n-1)*p)*T2;
      v1=p;  %Numerator degrees of freedom.
      v2=n-p;  %Denominator degrees of freedom.
      P=1-fcdf(F,v1,v2);  %Probability that null Ho: is true.
      disp(' ')
      fprintf('-------------------------------------------------------------------------------------\n');
      disp(' Sample-size    Variables      T2          F           df1          df2          P')
      fprintf('-------------------------------------------------------------------------------------\n');
      fprintf('%8.i%13.i%15.4f%11.4f%9.i%14.i%14.4f\n\n',n,p,T2,F,v1,v2,P);
      fprintf('-------------------------------------------------------------------------------------\n');
      if P >= alpha;
         disp('Mean vectors results not significant.');
      else
         disp('Mean vectors results significant.');
      end;
   end;
end;

return;


function [ as, bs, cs ] = sphere_triangle_vertices_to_sides ( r, v1, v2, v3 )

%*****************************************************************************80
%
%% SPHERE_TRIANGLE_VERTICES_TO_SIDES computes spherical triangle sides.
%
%  Discussion:
%
%    We can use the ACOS system call here, but the ARC_COSINE routine
%    will automatically take care of cases where the input argument is
%    (usually slightly) out of bounds.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 April 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real V1(3), V2(3), V3(3), the vertices of the spherical
%    triangle.
%
%    Output, real AS, BS, CS, the (geodesic) length of the sides
%    of the triangle.
%
  dim_num = 3;

  as = r * r8_acos ( v2(1:dim_num)' * v3(1:dim_num) / r.^2 );
  bs = r * r8_acos ( v3(1:dim_num)' * v1(1:dim_num) / r.^2 );
  cs = r * r8_acos ( v1(1:dim_num)' * v2(1:dim_num) / r.^2 );

  return
end


function [ mO ] = ImageFilteringFrequencyDomain( mI, mH, paddingMode )
% ----------------------------------------------------------------------------------------------- %
% [ mO ] = ImageFilteringFrequencyDomain( mI, mH, paddingMode )
% Applies Image Filtering in the Frequency Domain.
% Input:
%   - mI                -   Input Image.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - mH                -   Filtering Kernel.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - paddingMode       -   Padding Mode.
%                           Sets whether the padding is by Zeros,
%                           Symmetric, Replicate or Circular mode.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: {1, 2, 3, 4}.
% Output:
%   - mI                -   Output Image.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
% References:
%   1.  MATLAB's 'imfilter()' - https://www.mathworks.com/help/images/ref/imfilter.html.
% Remarks:
%   1.  A
% TODO:
%   1.
%   Release Notes:
%   -   1.0.000     04/04/2019  Royi Avital
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

PADDING_MODE_ZEROS      = 1;
PADDING_MODE_SYMMETRIC  = 2;
PADDING_MODE_REPLICATE  = 3;
PADDING_MODE_CIRCULAR   = 4;

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

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

radiusRows = floor(numRowsKernel / 2);
radiusCols = floor(numColsKernel / 2);

vPadRadius = [radiusRows; radiusCols];

switch(paddingMode)
    case(PADDING_MODE_ZEROS)
        % Size of the Linear Convolution Support
        numRowsL = numRows + numRowsKernel - 1;
        numColsL = numCols + numColsKernel - 1;

        % Equivalent of Full Linear Convolution (Zero Padding Built In).
        % This is due the fact padding with zeors at the end with symmetric
        % assumption and shifting yield correct result.
        mO = ifft2(fft2(mI, numRowsL, numColsL) .* fft2(mH, numRowsL, numColsL), 'symmetric');

        firstRowIDx = ceil((numRowsKernel + 1) / 2);
        firstColIDx = ceil((numColsKernel + 1) / 2);

        mO = mO(firstRowIDx:(firstRowIDx + numRows - 1), firstColIDx:(firstColIDx + numCols - 1));
    case({PADDING_MODE_SYMMETRIC, PADDING_MODE_REPLICATE})
        % Padding to apply "Linear Convolution" on the image pixels.
        mI = PadArray2D(mI, vPadRadius, paddingMode);

        numRowsPad = numRows + (2 * radiusRows);
        numColsPad = numCols + (2 * radiusCols);

        mHC = mH;
        mHC(numRowsPad, numColsPad) = 0;
        mHC = circshift(mHC, [-radiusRows, -radiusCols]);

        mO = ifft2(fft2(mI) .* fft2(mHC), 'symmetric');
        mO = mO((radiusRows + 1):(radiusRows + numRows), (radiusCols + 1):(radiusCols + numCols));
    case(PADDING_MODE_CIRCULAR)
        mHC = mH;
        mHC(numRows, numCols) = 0;
        mHC = circshift(mHC, [-radiusRows, -radiusCols]);

        mO = ifft2(fft2(mI) .* fft2(mHC), 'symmetric');
end

end


function a = c8mat_house ( n, x )

%*****************************************************************************80
%
%% C8MAT_HOUSE constructs a complex Householder elementary reflector matrix.
%
%  Formula:
%
%     A = I - ( 2 * X * hermitian ( X ) ) / ( conjg ( X ) * X )
%
%  Example:
%
%    N = 5, X = ( 1, 1, 1, 0, -1 )
%
%   1/2 -1/2 -1/2  0  1/2
%  -1/2  1/2 -1/2  0  1/2
%  -1/2 -1/2  1/2  0  1/2
%    0    0    0   1   0
%   1/2  1/2  1/2  0  1/2
%
%  Properties:
%
%    A is hermitian: hermitian ( A ) = A.
%
%    Because A is hermitian, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is unitary: hermitian ( A ) * A = A * hermitian ( A ) = I.
%
%    inverse ( A ) = A.
%
%    det ( A ) = -1.
%
%    LAMBDA(1) = -1.
%
%    If X is the vector used to define A, then X is an eigenvector
%    of A associated with the eigenvalue of -1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Input, complex X(N), the vector that defines the
%    Householder matrix.
%
%    Output, complex A(N,N), the matrix.
%
  a = c8mat_identity ( n );

  xdot = real ( x(1:n) * x(1:n)' );

  if ( 0.0 < xdot )

    for i = 1 : n
      for j = 1 : n
        a(i,j) = a(i,j) - 2.0 * x(i) * x(j)' / xdot;
      end
    end

  end

  return
end


function d = bayesgauss(X,C,M,P)
%BAYESGAUSS Bayes classifier for Gaussian patterns.
%   D = BAYESGAUSS(X,C,M,P) computes Bayes Gaussian decision functions
%   of the n-dimensional patterns in the rows of X. C is an array of
%   size n-by-n-by-Nc containing Nc covariance matrices of size n-by-n,
%   where Nc is the number of classes. M is a matrix of size Nc-by-n,
%   whose rows are the corresponding mean vectors. A covariance matrix
%   and a mean vector must be specified for each class. X is of size
%   K-by-n, where K is the number of patterns to be classified. P is a
%   1-by-Nc vector containing the probabilities of occurrence of each
%   class. If P is not included in the argument, the classes are assumed
%   to be equally likely.
%
%   In the output, D is a column vector of length K. Its ith element is
%   the class number assigned to the ith vector in X during
%   classification.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Verify the number of inputs.
narginchk(3,4)
n = size(C,1); % Dimension of patterns.

% Protect against the possibility that the class number is included
% as an (n + 1)th element of the vectors.
X = double(X(:,1:n));
% Number of pattern classes.
Nc = size(C,3);
% Number of patterns to classify.
K = size(X,1);
if nargin == 3
   P(1:Nc) = 1/Nc; % Classes assumed equally likely.
else
   if sum(P) ~= 1
      error('Elements of P must sum to 1.');
   end
end
% Compute the determinants.
DM = zeros(1,Nc); % Preallocate memory for loop speed.
for J = 1:Nc
   DM(J) = det(C(:,:,J));
end

% Evaluate the decision functions. Note the use of function mahalanobis
% discussed in Section 14.2.
D = zeros(K,Nc); % Preallocate memory for loop speed.
for J = 1:Nc
   Cm = C(:,:,J);
   Mm = M(J,:);
   L(1:K,1) = log(P(J));
   DET(1:K,1) = 0.5*log(DM(J));
   if P(J) == 0
      D(1:K,J) = -inf;
   else
      D(:,J) = L - DET - 0.5*mahalanobis(X,Cm,Mm);
   end
end

% Find the coordinates of the maximum value in each row. The location of
% a maximum gives the class of the corresponding pattern vector.
[i,j] = find(D == max(D,[],2));

% Re-use X. Its first element in a row is the pattern number, and the
% second is the class to which the pattern was assigned.
X = [i,j];

% Eliminate multiple classifications of the same patterns. Since the
% class assignment when two or more decision functions give the same
% value is arbitrary, we need to keep only one. Function unique
% eliminates duplicates and returns the array sorted by rows. This
% re-establishes the original order of the patterns.
[~,idx] = unique(X(:,1));
X = X(idx,:);
% X is now sorted, with the 2nd column giving the class of the pattern
% number in the 1st col.;  i.e., X(j,1) refers to the jth input pattern,
% and X(j,2) is its class number.

% Output the result of classification. d is a column vector with length
% equal to the total number of input patterns. The elements of d are the
% classes into which the patterns (in their original order) were
% classified.
d = X(:,2);


function [X,names]=elipcyl
% [X,names]=elipcyl defines elliptic
% cylinder coordinates
syms et ps z real; names=[et ps z];
X=[cosh(et)*cos(ps);
   sinh(et)*sin(ps); z];


function [R, G, B] = Lab2RGB(L, a, b)
% function [R, G, B] = Lab2RGB(L, a, b)
% Lab2RGB takes matrices corresponding to L, a, and b in CIELab space
% and transforms them into RGB.  This transform is based on ITU-R
% Recommendation  BT.709 using the D65 white point reference.
% and the error in transforming RGB -> Lab -> RGB is approximately
% 10^-5.  By Mark Ruzon from C code by Yossi Rubner, 23 September 1997.
% Updated for MATLAB 5 28 January 1998.
% Fixed a bug in conversion back to uint8 9 September 1999.

if (nargin == 1)
  b = L(:,:,3);
  a = L(:,:,2);
  L = L(:,:,1);
end

% Thresholds
T1 = 0.008856;
T2 = 0.206893;

[M, N] = size(L);
s = M * N;
L = reshape(L, 1, s);
a = reshape(a, 1, s);
b = reshape(b, 1, s);

% Compute Y
fY = ((L + 16) / 116) .^ 3;
YT = fY > T1;
fY = (~YT) .* (L / 903.3) + YT .* fY;
Y = fY;

% Alter fY slightly for further calculations
fY = YT .* (fY .^ (1/3)) + (~YT) .* (7.787 .* fY + 16/116);

% Compute X
fX = a / 500 + fY;
XT = fX > T2;
X = (XT .* (fX .^ 3) + (~XT) .* ((fX - 16/116) / 7.787));

% Compute Z
fZ = fY - b / 200;
ZT = fZ > T2;
Z = (ZT .* (fZ .^ 3) + (~ZT) .* ((fZ - 16/116) / 7.787));

X = X * 0.950456;
Z = Z * 1.088754;

MAT = [ 3.240479 -1.537150 -0.498535;
       -0.969256  1.875992  0.041556;
        0.055648 -0.204043  1.057311];

RGB = max(min(MAT * [X; Y; Z], 1), 0);

R = reshape(RGB(1,:), M, N) * 255;
G = reshape(RGB(2,:), M, N) * 255;
B = reshape(RGB(3,:), M, N) * 255;

if ((nargout == 1) | (nargout == 0))
  R = uint8(round(cat(3,R,G,B)));
end


% Example 6.4: Regressor selection problem
% Section 6.3.1, Figure 6.7
% Original by Lieven Vandenberghe
% Adapted for CVX Argyris Zymnis - 10/2005
%
% Solves
%        minimize   ||A*x-b||_2
%        subject to card(x) <= k
%
% where card(x) denotes the number of nonzero elements in x,
% by first solving (for some value of alpha close to ||x_ln||_1)
%        minimize   ||A*x-b||_2
%        subject to ||x||_1 <= alpha
%
% and iteratively decreasing alpha so as to get card(x) = k
% The sparsity pattern is then fixed in A and b and
%        minimize   ||A*x-b||_2
%
% is solved

rand('state',0);
randn('state',0);

m = 10;
n = 20;

A = randn(m,n);
b = A*[randn(round(m/2),1); zeros(n-round(m/2),1)];
b = b + 0.1*norm(b)*randn(m,1);

if (1) %%%%%%%%%%%%

% tradeoff curve for heuristic
%
% min.  ||Ax-b||_2
% s.t.  ||x||_1 <= alpha

xln = A'*((A*A')\b);
lnorm = norm(xln,1);
nopts = 100;
alphas = linspace(0,lnorm,nopts);
residuals_heur = norm(b);
card_heur = 0;

for k=2:(nopts-1)
  alpha = alphas(k);

  cvx_begin quiet
    variable x(n)
    minimize(norm(A*x-b))
    subject to
        norm(x,1) <= alpha; %#ok
  cvx_end

  x(abs(x) < 1e-3*max(abs(x))) = 0; %#ok
  ind = find(abs(x));
  sparsity = length(ind);
  fprintf(1,'Current sparsity pattern k = %d \n',sparsity);
  x = zeros(n,1);  x(ind) = A(:,ind)\b;
  card_heur = [card_heur, sparsity]; %#ok
  residuals_heur = [residuals_heur, norm(A*x-b)]; %#ok
end;

obj1 = norm(b);
obj2 = 0;
obj1 %#ok

i=1;
for k=1:m-1
  if any(card_heur == k)
     obj2(i+1) = k; %#ok
     obj1(i+1) = min(residuals_heur(card_heur ==k));
     i=i+1;
  end;
end;
obj2(i) = m;  obj1(i) = 0;

end; %%%%%%%%%%%%%%%%%%%

% globally optimal tradeoff

if (1) %%%%%%%%%%%%%

bestx = zeros(n,m);
bestres = zeros(1,m);

for k=1:m-1
  k %#ok
  % enumerate sparsity patterns with exactly k nonzeros
  bestres(k) = Inf;
  ind = 1:k %#ok
  nocases = 1;
  done = 0;
  while ~done
     done = 1;
     for i=0:k-1
       if (ind(k-i) < n-i),
          ind(k-i:k) = ind(k-i)+(1:i+1);
          done = 0;
          break;
       end;
     end;
     if done, break; end;
     x = zeros(n,1);
     x(ind) = A(:,ind)\b;
     if (norm(A*x-b) < bestres(k)),
        bestres(k) = norm(A*x-b);
        bestx(:,k) = x;
     end;
     nocases = nocases + 1;
  end;
  nocases %#ok
  factorial(n)/(factorial(n-k)*factorial(k)) %#ok
end;

x = A\b;
bestres(m) = norm(A*x-b);
bestres = [norm(b) bestres];

end; %%%%%%%%%

figure
hold off
obj1dbl =[];
obj2dbl =[];
for i=1:length(obj1)-1
  obj1dbl = [obj1dbl, obj1(i), obj1(i)]; %#ok
  obj2dbl = [obj2dbl, obj2(i), obj2(i+1)]; %#ok
end;
obj1dbl = [obj1dbl, obj1(length(obj1))];
obj2dbl = [obj2dbl, obj2(length(obj1))];

bestobj1 = bestres;
bestobj2 = 0:m;
bestobj1dbl =[];
bestobj2dbl =[];
for i=1:length(bestobj1)-1
  bestobj1dbl = [bestobj1dbl, bestobj1(i), bestobj1(i)]; %#ok
  bestobj2dbl = [bestobj2dbl, bestobj2(i), bestobj2(i+1)]; %#ok
end;
bestobj1dbl = [bestobj1dbl, bestobj1(length(bestobj1))];
bestobj2dbl = [bestobj2dbl, bestobj2(length(bestobj1))];

plot(obj1dbl,obj2dbl,'-', bestobj1dbl, bestobj2dbl,'--');
hold on
plot(obj1,obj2,'o', bestobj1, bestobj2,'o');
axis([0 ceil(2*norm(b))/2 0 m+1])
xlabel('x');
ylabel('y');
hold off

%print -deps sparse_regressor_global_helv.eps
%save regressor_results


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

%*****************************************************************************80
%
%% JED_TO_YMDF_GREGORIAN2 converts a JED to a Gregorian YMDF date.
%
%  Discussion:
%
%    The theory behind this routine is very clean.  The Gregorian
%    calendar has cycles of 1, 4, 100 and 400 years, and we can
%    analyze a date by determining where it lies within these cycles.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Reingold, Nachum Dershowitz, Stewart Clamen,
%    Calendrical Calculations, II: Three Historical Calendars,
%    Software - Practice and Experience,
%    Volume 23, Number 4, pages 383-404, April 1993.
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, integer Y, M, D, real F, the YMDF date.
%
  g1 = 365;
  g4 = 1461;
  g100 = 36524;
  g400 = 146097;

  jed_epoch = epoch_to_jed_gregorian ( );

  j = floor ( jed - jed_epoch );
  f1 = ( jed - jed_epoch ) - j;

  d0 = j;
  n400 = 0;

  while ( d0 < 0 )
    d0 = d0 + g400;
    n400 = n400 - 1;
  end

  n400 = n400 + floor ( d0 / g400 );
  d1 = i4_modp ( d0, g400 );

  n100 = floor ( d1 / g100 );
  d2 = i4_modp ( d1, g100 );

  n4 = floor ( d2 / g4 );
  d3 = i4_modp ( d2, g4 );

  n1 = floor ( d3 / g1 );
  d4 = i4_modp ( d3, g1 );

  if ( n100 == 4 || n1 == 4 )
    j1 = 366;
    y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1;
  else
    j1 = d4 + 1;
    y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1 + 1;
  end
%
%  Any year before 1 AD must be moved one year further back, since
%  this calendar does not include a year 0.
%
  y1 = y_astronomical_to_common ( y1 );

  [ y, m, d, f ] = yjf_to_ymdf_gregorian ( y1, j1, f1 );

  return
end


function oev = eci2orb1 (mu, r, v)

% convert eci state vector to six classical orbital
% elements via equinoctial elements

% input

%  mu = central body gravitational constant (km**3/sec**2)
%  r  = eci position vector (kilometers)
%  v  = eci velocity vector (kilometers/second)

% output

%  oev(1) = semimajor axis (kilometers)
%  oev(2) = orbital eccentricity (non-dimensional)
%           (0 <= eccentricity < 1)
%  oev(3) = orbital inclination (radians)
%           (0 <= inclination <= pi)
%  oev(4) = argument of perigee (radians)
%           (0 <= argument of perigee <= 2 pi)
%  oev(5) = right ascension of ascending node (radians)
%           (0 <= raan <= 2 pi)
%  oev(6) = true anomaly (radians)
%           (0 <= true anomaly <= 2 pi)

% Orbital Mechanics with MATLAB

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

pi2 = 2.0 * pi;

% position and velocity magnitude

rmag = norm(r);

vmag = norm(v);

% position unit vector

rhat = r / rmag;

% angular momentum vectors

hv = cross(r, v);

hhat = hv / norm(hv);

% eccentricity vector

vtmp = v / mu;

ecc = cross(vtmp, hv);

ecc = ecc - rhat;

% semimajor axis

sma = 1.0 / (2.0 / rmag - vmag * vmag / mu);

p = hhat(1) / (1.0 + hhat(3));

q = -hhat(2) / (1.0 + hhat(3));

const1 = 1.0 / (1.0 + p * p + q * q);

fhat(1) = const1 * (1.0 - p * p + q * q);
fhat(2) = const1 * 2.0 * p * q;
fhat(3) = -const1 * 2.0 * p;

ghat(1) = const1 * 2.0 * p * q;
ghat(2) = const1 * (1.0 + p * p - q * q);
ghat(3) = const1 * 2.0 * q;

h = dot(ecc, ghat);

xk = dot(ecc, fhat);

x1 = dot(r, fhat);

y1 = dot(r, ghat);

% orbital eccentricity

eccm = sqrt(h * h + xk * xk);

% orbital inclination

inc = 2.0 * atan(sqrt(p * p + q * q));

% true longitude

xlambdat = atan3(y1, x1);

% check for equatorial orbit

if (inc > 0.00000001)
    raan = atan3(p, q);
else
    raan = 0.0;
end

% check for circular orbit

if (eccm > 0.00000001)
    argper = mod(atan3(h, xk) - raan, pi2);
else
    argper = 0.0;
end

% true anomaly

tanom = mod(xlambdat - raan - argper, pi2);

% load orbital element vector

oev(1) = sma;
oev(2) = eccm;
oev(3) = inc;
oev(4) = argper;
oev(5) = raan;
oev(6) = tanom;


%% Example 9.18: Hermite expansion of Benes SDE
%
% Copyright:
%   2018 - Simo Särkkä and Arno Solin
%
% License:
%   This software is provided under the MIT License. See the accompanying
%   LICENSE file for details.

%% Plot the Hermite expansion example

    x0 = 1/2;
    trans_dens = @(xx,t) 1./sqrt(2*pi*t).*cosh(xx)./cosh(x0).*exp(-0.5*t).*exp(-1./(2*t).*(xx-x0).^2);

    %
    % % Symbolic solution (requires the Symbolic Math Toolbox)
    % syms x;
    % f = matlabFunction(tanh(x));
    % df = matlabFunction(diff(tanh(x),1));
    % d2f = matlabFunction(diff(tanh(x),2));
    % d3f = matlabFunction(diff(tanh(x),3));
    % d4f = matlabFunction(diff(tanh(x),4));
    % d5f = matlabFunction(diff(tanh(x),5));
    %

    f = @(x) tanh(x);
    df = @(x) 1 - tanh(x)^2;
    d2f = @(x) 2*tanh(x)*(tanh(x)^2 - 1);
    d3f = @(x) -2*(tanh(x)^2 - 1)^2 - 4*tanh(x)^2*(tanh(x)^2 - 1);
    d4f = @(x) 16*tanh(x)*(tanh(x)^2 - 1)^2 + 8*tanh(x)^3*(tanh(x)^2 - 1);
    d5f = @(x) -16*(tanh(x)^2 - 1)^3 - 16*tanh(x)^4*(tanh(x)^2 - 1) - 88*tanh(x)^2*(tanh(x)^2 - 1)^2;

    xx = -15:0.1:15;

    figure(1); clf; hold on

      % Solve at t=2
      t = 2;
      herm_x = herm_exp(f(x0),df(x0),d2f(x0),d3f(x0),d4f(x0),d5f(x0),t,xx,x0);

      % Exact density
      fill(xx,trans_dens(xx,t),1,'FaceColor',[.7 .7 .7],'EdgeColor',[.7 .7 .7])

      % Series approximation
      plot(xx,herm_x,'-k','LineWidth',1)

      ylim([-0.21 0.25]);
      legend('Exact density','Series approximation','Location','south');
      xlabel('$x$');
      ylabel('$p(x)$');

    figure(2); clf; hold on

      % Solve at t=5
      t = 5;
      herm_x = herm_exp(f(x0),df(x0),d2f(x0),d3f(x0),d4f(x0),d5f(x0),t,xx,x0);

      % Exact density
      fill(xx,trans_dens(xx,t),1,'FaceColor',[.7 .7 .7],'EdgeColor',[.7 .7 .7])

      % Series approximation
      plot(xx,herm_x,'-k','LineWidth',1)

      ylim([-0.21 0.25]);
      xlabel('$x$');
      ylabel('$p(x)$');


% EX_ARTICLE_SECTION_512: short example with a non-isoparametric approach, and a non-NURBS geometry.
%
% Example to solve the problem
%
%    - div ( grad (u)) = (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2)  in Omega
%                    u = 0                                                      on Gamma
%
% with                Omega = (1 < x^2+y^2 < 4) & (x > 0) & (y > 0)
% and exact solution      u = (x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x))
%
% This solves the example of Section 5.1.2 in the article
%
% C. De Falco, A. Reali, R. Vazquez
% GeoPDEs: a research tool for IsoGeometric Analysis of PDEs
%
% Copyright (C) 2009, 2010 Carlo de Falco
% Copyright (C) 2011, 2015 Rafael Vazquez
%
%    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/>.

geometry = geo_load ({@ring_polar_map, @ring_polar_map_der});

knots = kntuniform ([9 9], [4 4], [3 3]);
[qn, qw] = msh_set_quad_nodes (knots, msh_gauss_nodes ([5 5]));
msh = msh_cartesian (knots, qn, qw, geometry);

space = sp_bspline (knots, [4 4], msh);

mat = op_gradu_gradv_tp (space, space, msh);
rhs = op_f_v_tp (space, msh, @(x, y) (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2));

drchlt_dofs = [];
for iside = 1:4
  drchlt_dofs = union (drchlt_dofs, space.boundary(iside).dofs);
end
int_dofs = setdiff (1:space.ndof, drchlt_dofs);

u = zeros (space.ndof, 1);
u(int_dofs) = mat(int_dofs, int_dofs) \ rhs(int_dofs);

sp_to_vtk (u, space, geometry, [20 20], 'laplace_solution.vts', 'u')
err = sp_l2_error (space, msh, u, @(x,y)(x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x)))

%!demo
%! ex_article_section_512;

%!test
%! geometry = geo_load ({@ring_polar_map, @ring_polar_map_der});
%! knots = kntuniform ([9 9], [4 4], [3 3]);
%! [qn, qw] = msh_set_quad_nodes (knots, msh_gauss_nodes ([5 5]));
%! msh = msh_cartesian (knots, qn, qw, geometry);
%! space = sp_bspline (knots, [4 4], msh);
%! mat = op_gradu_gradv_tp (space, space, msh, @(x, y) ones (size (x)));
%! rhs = op_f_v_tp (space, msh, @(x, y) (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2));
%! drchlt_dofs = [];
%! for iside = 1:4
%! drchlt_dofs = union (drchlt_dofs, space.boundary(iside).dofs);
%! end
%! int_dofs = setdiff (1:space.ndof, drchlt_dofs);
%! u = zeros (space.ndof, 1);
%! u(int_dofs) = mat(int_dofs, int_dofs) \ rhs(int_dofs);
%! err = sp_l2_error (space, msh, u, @(x,y)(x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x)));
%! assert (msh.nel, 64)
%! assert (space.ndof, 144)
%! assert (err, 2.82510645627626e-07, 1e-16)


function S = eliminator(n, ROWS)
%
%ELIMINATOR
%
% Returns a matrix S that is called eliminator.
% S is a matrix such that S*A (assuming that this product
% exists) will not contain rows listed in row vector ROWS.
% Numbers of rows in ROWS can be unsorted.
%
% Example:
%     A = hilb(6);
%     S = eliminator(6, [4 6 2]);
%     B = S * A;
% Matrix B will contain rows 1, 3, 5 from the matrix A,
% matrix B will not contain rows 2, 4, 6 from matrix A.
%
% (C) 2000 Igor Podlubny, Blas Vinagre, Tomas Skovranek
%
% See:
% [1] 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
% [2] R.G. Cooke, Infinite Matrices and Sequence Spaces,
%     MacMillan and Co., London, 1950. 347 pp.

S = eye(n);
r = sort(ROWS);
m = size(r,2);

for k = m:(-1):1
   if r(k)-1 == 0
        S = S((r(k)+1):(size(S,1)-k+1),:);
   elseif r(k) == size(S,1)
        S = S(1:(r(k)-1),:);
   else
        S = [S(1:(r(k)-1),:);  S((r(k)+1):(size(S,1)),:)];
   end
end


function pdf = bernoulli_pdf ( x, a )

%*****************************************************************************80
%
%% BERNOULLI_PDF evaluates the Bernoulli PDF.
%
%  Discussion:
%
%    PDF(X)(A) = A**X * ( 1.0D+00 - A )**( X - 1 )
%
%    X = 0 or 1.
%
%    The Bernoulli PDF describes the simple case in which a single trial
%    is carried out, with two possible outcomes, called "success" and
%    "failure"; the probability of success is A.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer X, the number of successes on a single trial.
%    X = 0 or 1.
%
%    Input, real A, the probability of success on one trial.
%    0.0D+00 <= A <= 1.0.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < 0 )
    pdf = 0.0;
  elseif ( x == 0 )
    pdf = 1.0 - a;
  elseif ( x == 1 )
    pdf = a;
  else
    pdf = 0.0;
  end

  return
end


function pp = sphere_imp_point_project_3d ( r, center, p )

%*****************************************************************************80
%
%% SPHERE_IMP_POINT_PROJECT_3D projects a point onto an implicit sphere in 3D.
%
%  Discussion:
%
%    An implicit sphere in 3D satisfies the equation:
%
%      sum ( ( P(1:DIM_NUM) - CENTER(1:DIM_NUM) )**2 ) = R**2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real CENTER(3), the center of the sphere.
%
%    Input, real P(3), a point.
%
%    Output, real PP(3), the projected point.
%
  dim_num = 3;

  if ( r == 0.0 )

    pp(1:dim_num) = center(1:dim_num);

  elseif ( p(1:dim_num) == center(1:dim_num) )

    pp(1:dim_num) = center(1:dim_num) + r / sqrt ( dim_num );

  else

    norm = sqrt ( sum ( ( p(1:dim_num) - center(1:dim_num) ).^2 ) );

    pp(1:dim_num) = center(1:dim_num) + r * ( p(1:dim_num) - center(1:dim_num) ) / norm;

  end

  return
end


function w = w0_func(z,N)
% Based on:
% FADDEEVA   Faddeeva function
%   W = FADDEEVA(Z) is the Faddeeva function, aka the plasma dispersion
%   function, for each element of Z. The Faddeeva function is defined as:
%
%     w(z) = exp(-z^2) * erfc(-j*z)
%
%   where erfc(x) is the complex complementary error function.
%
%   W = FADDEEVA(Z,N) can be used to explicitly specify the number of terms
%   to truncate the expansion (see (13) in [1]). N = 16 is used as default.
%
%   Example:
%       x = linspace(-10,10,1001); [X,Y] = meshgrid(x,x);
%       W = faddeeva(complex(X,Y));
%       figure;
%       subplot(121); imagesc(x,x,real(W)); axis xy square; caxis([-1 1]);
%       title('re(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%       subplot(122); imagesc(x,x,imag(W)); axis xy square; caxis([-1 1]);
%       title('im(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%
%   Reference:
%   [1] J.A.C. Weideman, "Computation of the Complex Error Function," SIAM
%       J. Numerical Analysis, pp. 1497-1518, No. 5, Vol. 31, Oct., 1994
%       Available Online: http://www.jstor.org/stable/2158232

% Called by: crbs6.m, crbs7.m

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

w = zeros(size(z)); % initialize output

%%%%%
% for purely imaginary-valued inputs, use erf as is if z is real
idx = real(z)==0; %
w(idx) = exp(-z(idx).^2).*erfc(imag(z(idx)));

if all(idx), return; end
idx = ~idx;

%%%%%
% for complex-valued inputs

% make sure all points are in the upper half-plane (positive imag. values)
idx1 = idx & imag(z)<0;
z(idx1) = conj(z(idx1));

M = 2*N;
M2 = 2*M;
k = (-M+1:1:M-1)'; % M2 = no. of sampling points.
L = sqrt(N/sqrt(2)); % Optimal choice of L.

theta = k*pi/M;
t = L*tan(theta/2); % Variables theta and t.
f = exp(-t.^2).*(L^2+t.^2);
f = [0; f]; % Function to be transformed.
a = real(fft(fftshift(f)))/M2; % Coefficients of transform.
a = flipud(a(2:N+1)); % Reorder coefficients.

Z = (L+1i*z(idx))./(L-1i*z(idx));
p = polyval(a,Z); % Polynomial evaluation.
w(idx) = 2*p./(L-1i*z(idx)).^2 + (1/sqrt(pi))./(L-1i*z(idx)); % Evaluate w(z).

% convert the upper half-plane results to the lower half-plane if necesary
w(idx1) = conj(2*exp(-z(idx1).^2) - w(idx1));

w=-w*sqrt(-1)*pi; % converts to 'w0_func' used in crbs_molecular.m


% Mathematics Q561696
% https://math.stackexchange.com/questions/561696
% Solving Non Negative Least Squares by Analogy with Least Squares (MATLAB)
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     05/08/2017
%   *   First release.

%% General Parameters

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = OFF;

%% Simulation Parameters

numRows = 4;
numCols = 3; %<! Number of Vectors - i (K in the question)

numIterations   = 10000;
stepSize        = 0.075;

%% Generate Data

mA = randn([numRows, numCols]);
vB = randn([numRows, 1]);

%% Solution by CVX

cvx_begin('quiet')
    cvx_precision('best');
    variable vX(numCols)
    minimize( square_pos(  norm(mA * vX - vB, 2) ) );
    subject to
        vX >= 0;
cvx_end

disp([' ']);
disp(['CVX Solution Summary']);
disp(['The CVX Solver Status - ', cvx_status]);
disp(['The Optimal Value Is Given By - ', num2str(cvx_optval)]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Solution by Projected Gradient Descent

vX = zeros([numCols, 1]);

for ii = 1:numIterations
    vX = vX - ((stepSize / sqrt(ii)) * mA.' * (mA * vX - vB));
    vX = max(vX, 0);
end

objVal = sum((mA * vX - vB) .^ 2);

disp([' ']);
disp(['Projected Gradient Solution Summary']);
disp(['The Optimal Value Is Given By - ', num2str(objVal)]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);


function [ w, seed ] = direction_uniform_nd ( dim_num, seed )

%*****************************************************************************80
%
%% DIRECTION_UNIFORM_ND generates a random direction vector in ND.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the space.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real W(DIM_NUM), a random direction vector,
%    with unit norm.
%
%    Output, integer SEED, a seed for the random number generator.
%

%
%  Get N values from a standard normal distribution.
%
  [ w, seed ] = r8vec_normal_01 ( dim_num, seed );
%
%  Compute the length of the vector.
%
  norm = sqrt ( sum ( w(1:dim_num).^2 ) );
%
%  Normalize the vector.
%
  w(1:dim_num) = w(1:dim_num) / norm;

  return
end


function Cn = correlation_image(Y,sz,d1,d2,flag_norm, K)

% construct correlation image based on neighboing pixels
% Y: raw data
% sz: define the relative location of neighbours. it can be scalar, 2
%       element vector or a binary matrix
%       scalar: number of nearest neighbours, either 4 or 8, default 4
%       2 element vector: [rmin, rmax], the range of neighbours. the
%           distance between the neighbour and the pixel is d, dmin <= r <
%           dmax.
%       matrix: a squared matrix (2k+1)*(2k+1)indicating the location of neighbours
% d1,d2: spatial dimensions
% flag_norm: indicate whether Y has been normalized and centered ( 1 is
%   yes, 0 is no)
% K:  scalar, the rank of the random matrix for projection

% Author: Eftychios A. Pnevmatikakis, Simons Foundation, 2015
% with modifications from Pengcheng Zhou, Carnegie Mellon University, 2015.
% It uses convolution and random projection for speeding up the
% computation.

%% preprocess the raw data
if ~exist('flag_norm', 'var') || isempty(flag_norm)
    flag_norm = false;
end

if ~exist('sz', 'var') || isempty(sz)
    sz = [0,1,0; 1,0,1; 0,1,0];
end

% center data
Y = bsxfun(@minus, double(Y), mean(Y, ndims(Y)));
if ~ismatrix(Y)
    [d1, d2, T] = size(Y);
else
    T = size(Y, 2);
end

if exist('K', 'var') && (~isempty(K))
    Y = double(reshape(Y, [], T))*randn(T, K);
    % centering
    mY = mean(Y,2);
    Y = bsxfun(@minus, Y, mY);        % normalizing
    flag_norm = false;
end
if ~flag_norm
    sY = sqrt(mean(Y.*Y, ndims(Y)));
    sY(sY==0) = 1; % avoid nan values
    Y = bsxfun(@times, Y, 1./sY);
end
if ismatrix(Y)
    Y = reshape(Y, d1, d2, []);
end

%% construct a matrix indicating location of the matrix
if  isscalar(sz)
    if sz == 8      % 8 nearest neighbours
        sz = [1,1,1; 1,0,1; 1,1,1];
    elseif sz==4
        sz = [0,1,0; 1,0,1; 0,1,0];
    end
elseif length(sz(:)) == 2
    % the specified neighbours has a distance within the domain [dmin,
    % dmax)
    sz = ceil(sz);
    dmin = min(sz); dmax = max(sz);
    rsub = (-dmax+1):(dmax-1);      % row subscript
    csub = rsub;      % column subscript
    [cind, rind] = meshgrid(csub, rsub);
    R = sqrt(cind.^2+rind.^2);
    sz = (R>=dmin) .* (R<dmax);
end

%% compute the correlation
Yconv = imfilter(Y, sz);        % sum over the neighbouring pixels
MASK = imfilter(ones(d1,d2), sz);   % count the number of neighbouring pixels
Cn = mean(Yconv.*Y, 3)./MASK;   % compute correlation and normalize


function [ n_data, a, b, n, fx ] = cos_power_int_values ( n_data )

%*****************************************************************************80
%
%% COS_POWER_INT_VALUES returns some values of the cosine power integral.
%
%  Discussion:
%
%    The function has the form
%
%      COS_POWER_INT(A,B,N) = Integral ( A <= T <= B ) ( cos(T) )^N dt
%
%    In Mathematica, the function can be evaluated by:
%
%      Integrate [ ( Cos[x] )^n, { x, a, b } ]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 March 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Cambridge University Press, 1999,
%    ISBN: 0-521-64314-7,
%    LC: QA76.95.W65.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0
%    before the first call.  On each call, the routine increments N_DATA by 1,
%    and returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real A, B, the limits of integration.
%
%    Output, integer N, the power.
%
%    Output, real FX, the function value.
%
  n_max = 11;

  a_vec = [ ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00 ];
  b_vec = [ ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793 ];
  fx_vec = [ ...
     3.141592653589793, ...
     0.0, ...
     1.570796326794897, ...
     0.0, ...
     1.178097245096172, ...
     0.0, ...
     0.9817477042468104, ...
     0.0, ...
     0.8590292412159591, ...
     0.0, ...
     0.7731263170943632 ];
  n_vec = [ ...
     0, ...
     1, ...
     2, ...
     3, ...
     4, ...
     5, ...
     6, ...
     7, ...
     8, ...
     9, ...
    10 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    a = 0.0;
    b = 0.0;
    n = 0;
    fx = 0.0;
  else
    a = a_vec(n_data);
    b = b_vec(n_data);
    n = n_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end