function y=mvaveragec(x,N)

%MVAVERAGEC   signal smoothing through the moving average method.
%   Y = MVAVERAGEC(X,N) Quickly smooths the signal X via averaging each
%   sampling with the previous and afterwards N samples.
%
%   Example:
%      t = 2*pi*linspace(-1,1);
%      xn = cos(x) + 0.25 - 0.5*rand(size(x));
%      xs = mvaveragec(xn,4);
%      plot(t,xn,t,xs), legend('noisy','smooth'), axis tight
%
%   See also MVAVERAGE2 and MVAVERAGEC

%   by Yi Cao
%   Cranfield University
%   11-09-2007
%   y.cao@cranfield.ac.uk
%

y0=filter(ones(1,2*N+1)/(2*N+1),1,x);
y=x;
y(N+1:end-N)=y0(2*N+1:end);


function [Ax,Ay,b,K] = convexhullConvex(varargin)
% Two lower bounds from tangents
% y > f(xL) + (x-xL)*df(xL)
% y > f(xU) + (x-xL)*df(xU)
% Upper bound from connecting extreme points
% y < f(xU)(x-xL)/(xU-xL) +  f(xL)(xU-x)/(xU-xL)
% can be written as
% Ax*x + Ay*y <= b

if rem(nargin,3)
    error('The convex hull generator assumes n triplets (x,f,df).')
end
m = nargin/3;
x = [varargin{(1:m)}]';
f = [varargin{(1:m)+m}]';
df = [varargin{(1:m)+2*m}]';

if df(1) == df(end)
    % This is a linear function
    % return y = f(1) + df*(x-x(1))
    Ax = df(1);
    Ay = -1;
    b = df(1)*x(1)-f(1);
    K.f = 1;
    K.l = 0;
    return
end

if all(diff(x)>=0) | all(diff(x(~isinf(x))))>=0 % Support [0 inf inf]
    Ay = [-ones(m,1);1];
    b  = [-f + x.*df; -f(end)*x(1)/(x(end)-x(1)) +  f(1)*x(end)/(x(end)-x(1))];
    Ax  = [df;-f(end)/(x(end)-x(1)) + f(1)/(x(end)-x(1))];

     % Don't use ill-conditioned cuts
    if df(1)<-1000
        Ax(1)=[];
        Ay(1) = [];
        b(1) = [];
    end
    if df(end-1)>1000
        Ax(end-1)=[];
        Ay(end-1) = [];
        b(end-1) = [];
    end
else
    Ax = [];
    Ay = [];
    b = [];
end
j = find(any(isnan([Ax Ay b]),2));
if ~isempty(j)
    b(j)=[];
    Ax(j,:)=[];
    Ay(j,:)=[];
end
K.f = 0;
K.l = length(b);
if 0
  sdpvar x y;plot(Ax*x+Ay*y <= b);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  In this script, we perform phase transition analysis
%  of Orthogonal matching pursuit.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all;
clear all;
clc;
rng('default');
% Create the directory for storing results
[status_code,message,message_id] = mkdir('bin');
target_file_path = 'bin/smv_phase_transition_noiseless.mat';
N = 256;
pta = spx.pursuit.PhaseTransitionAnalysis(N);
% pta.NumTrials = 100;
dict_model = @(M, N) spx.dict.simple.gaussian_dict(M, N);
data_model = @(N, K) spx.data.synthetic.SparseSignalGenerator(N, K).gaussian;
recovery_solver = @(Phi, K, y) spx.pursuit.joint.CoSaMP(Phi, K).solve(y).Z;
pta.run(dict_model, data_model, recovery_solver);
pta.save_results(target_file_path);


% Combined wire sizing and spacing
% Section 5.5,  L. Vandenberghe, S. Boyd, and A. El Gamal
% "Optimizing dominant time constant in RC circuits"
% Original by Lieven Vandenberghe
% Adapted for CVX by Joelle Skaf - 11/27/05
% Modified by Michael Grant - 3/8/06
%
% The problem is to determine the optimal sizes of interconnect wires and
% the optimal distances between them. We will consider an example with 3
% wires, each consisting of 5 segments (see paper, fig.21). The variables
% are the widths wij , and the distances s1 and s2 between the wires.
% The difference with the models used in other scripts is that we include a
% parasitic capacitance between the wires.
% The objective is to minimize the total width s1+s2.
% The problem can be formulated with the following SDP:
%               mimimize    s1 + s2
%                    s.t.   Tmax*G(w11,..,w35)-C(w11,..,w35,t11,..,t23) >=0
%                           1/t1j <= s1 - w1j - 0.5*w2j     , j = 1,..,5
%                           1/t2j <= s2 - w3j - 0.5*w2j     , j = 1,..,5
%                           0 <= tij <= 1         , i = 1,2 , j = 1,..,5
%                           t1 >=0, t2 >= 0, s1 >=smin, s2>=smin
%                           0 <= wij <= wmax
% the 2nd and 3rd constraints are nonlinear convex constraints that can be
% cast as 3 x 3-LMIs (Please refer to the paper for more details).

%
% Circuit parameters
%

n = 6;           % number of nodes per wire
N = 3*n;         % total number of nodes
m = n-1;         % number of segments per wire
alpha = 1;       % conductance per segment is is alpha*size
beta = 0.5;      % capacitance per segment is twice beta*size
gamma = 2;       % coupling capacitance is twice gamma*distance
G0 = 100;        % source conductance
C0 = [10,20,30]; % loads of first, second, third wires
wmin = 0.1;      % minimum width
wmax = 2.0;      % maximum width
smin = 1.0;      % minimum distance between wires
smax = 50;       % upper bound on s1 and s2  (meant to be inactive)

%
% Construct the capacitance and conductance matrices
%   C(x) = C0 + w11 * C1 + w21 * C2 + ...
%   G(x) = G0 + w11 * G1 + w21 * G2 + ...
% and we assemble the coefficient matrices together as follows:
%   CC = [ C0(:) C1(:) C2(:) ... ]
%   GG = [ G0(:) G1(:) G2(:) ... ]
%

CC = zeros(N,N,5*m+1);
GG = zeros(N,N,3*m+1);
for w = 0 : 2,
    % Constant terms
    CC(w*n+n,w*n+n,1) = C0(w+1);
    GG(w*n+1,w*n+1,1) = G0;
    for i = 1 : m,
        % capacitances to ground
        CC(w*n+[i,i+1],w*n+[i,i+1],w*m+i+1) = beta*[1,0;0,1];
        if w < 2,
            % coupling capacitors
            CC(w*n+[i,  n+i  ],w*n+[i,  n+i  ],(w+3)*m+i+1) = gamma*[1,-1;-1,1];
            CC(w*n+[i+1,n+i+1],w*n+[i+1,n+i+1],(w+3)*m+i+1) = gamma*[1,-1;-1,1];
        end
        % segment conductances
        GG(w*n+[i,i+1],w*n+[i,i+1],w*m+i+1) = alpha*[1,-1;-1,1];
    end
end
% Reshape for Matlab use
CC = reshape(CC,N*N,5*m+1);
GG = reshape(GG,N*N,3*m+1);

%
% Compute points the tradeoff curve and the two desired points
%

npts    = 50;
delays  = linspace( 85, 200, npts );
xdelays = [ 130, 90 ];
xnpts   = length(xdelays);
areas   = zeros(1,npts);
xareas  = zeros(1,xnpts);
for j = 1 : npts + xnpts,

    if j > npts,
        xj = j - npts;
        delay = xdelays(xj);
        disp( sprintf( 'Particular solution %d of %d (Tmax = %g)', xj, xnpts, delay ) );
    else,
        delay = delays(j);
        disp( sprintf( 'Point %d of %d on the tradeoff curve (Tmax = %g)', j, npts, delay ) );
    end

    %
    % Construct and solve the convex model
    %

    cvx_begin sdp quiet
        variables w(m,3) t(m,2) s(1,2)
        variable G(N,N) symmetric
        variable C(N,N) symmetric
        minimize( sum(s) )
        subject to
            G == reshape( GG * [ 1 ; w(:) ], N, N );
            C == reshape( CC * [ 1 ; w(:) ; t(:) ], N, N );
            delay * G - C >= 0;
            wmin <= w(:) <= wmax;
            t( : ) <= 1 / smin;
            s( : ) <= smax;
            inv_pos( t(:,1) ) <= s(1) - w(:,1) - 0.5 * w(:,2);
            inv_pos( t(:,2) ) <= s(2) - w(:,3) - 0.5 * w(:,2);
    cvx_end
    ss = cvx_optval;

    if j <= npts,
        areas(j) = ss;
    else,
        xareas(xj) = ss;

        %
        % Draw the wires
        %

        figure(4*xj-2);
        m2 = 2 * m;
        x1 = reshape( [ 1 : m ; 1 : m ], 1, m2 );
        x2 = x1( 1, end : -1 : 1 );
        y  = [ ss*ones(m2,1), s(2) + 0.5*w(x1,2), zeros(m2,1) ; ...
               ss-w(x2,1),    s(2) - 0.5*w(x2,2), w(x2,3)     ; ...
               ss,            s(2) + 0.5*w(1,2),  0           ];
        x1 = reshape( [ 0 : m - 1 ; 1 : m ], m2, 1 );
        x2 = x1( end : -1 : 1, 1 );
        x  = [ x1 ; x2 ; 0 ];
        hold off;
        fill( x, y, 0.9 * ones(size(y)) );
        hold on
        plot( x, y, '-' );
        axis( [-0.1, m+0.1,-0.1, ss+0.1]);
        colormap(gray);
        caxis([-1,1])
        title(sprintf('Solution (%d), Tmax = %g',xj,delay));

        %
        % Build the state space models and plot step responses
        %

        A = -inv(C)*G;
        T = linspace(0,2*delay,1000);
        B = -A * kron( eye(3), ones(n,1) );
        for inp = 1 : 3,
            figure(4*xj-2+inp);
            Y1 = simple_step(A,B(:,inp),T(2),length(T));
            hold off;
            plot(T,Y1([n,2*n,3*n],:),'-');
            hold on;
            text(T(1000),Y1(  n,1000),'v1');
            text(T(1000),Y1(2*n,1000),'v2');
            text(T(1000),Y1(3*n,1000),'v3');
            axis([0 2*delay -0.1 1.1]);
            % show dominant time constant
            plot(delay*[1;1], [-0.1;1.1], '--');
            title(sprintf('Solution (%d), Tmax = %g, step applied to wire %d',xj,delay,inp));
        end

    end

end

%
% Plot the tradeoff curve
%

figure(1);
ind = isfinite(areas);
plot(areas(ind), delays(ind));
xlabel('total width s_1 + s_2');
ylabel('dominant time constant');
title('Width-delay tradeoff curve')
hold on;
for k = 1 : xnpts,
    text( xareas(k), xdelays(k), sprintf( '(%d)', k ) );
end


function K = covMaternard(d, hyp, x, z, i)

% Matern covariance function with nu = d/2 and with Automatic Relevance
% Determination (ARD) distance measure. For d=1 the function is also known as
% the exponential covariance function or the Ornstein-Uhlenbeck covariance
% in 1d. The covariance function is:
%
%   k(x^p,x^q) = sf^2 * f( sqrt(d)*r ) * exp(-sqrt(d)*r)
%
% with f(t)=1 for d=1, f(t)=1+t for d=3 and f(t)=1+t+t²/3 for d=5.
% Here r is the distance sqrt((x^p-x^q)'*inv(P)*(x^p-x^q)), where the P matrix
% is diagonal with ARD parameters ell_1^2,...,ell_D^2, where D is the dimension
% of the input space and sf2 is the signal variance. The hyperparameters are:
%
% hyp = [ log(ell_1)
%         log(ell_2)
%          ..
%         log(ell_D)
%         log(sf) ]
%
% Copyright (c) by Hannes Nickisch, 2013-10-13.
%
% See also COVFUNCTIONS.M.

if nargin<3, K = '(D+1)'; return; end              % report number of parameters
if nargin<4, z = []; end                                   % make sure, z exists
xeqz = isempty(z); dg = strcmp(z,'diag');                       % determine mode

[n,D] = size(x);
ell = exp(hyp(1:D));
sf2 = exp(2*hyp(D+1));
if all(d~=[1,3,5]), error('only 1, 3 and 5 allowed for d'), end         % degree

switch d
  case 1, f = @(t) 1;               df = @(t) 1./t;     % df(t) = (f(t)-f'(t))/t
  case 3, f = @(t) 1 + t;           df = @(t) 1;
  case 5, f = @(t) 1 + t.*(1+t/3);  df = @(t) (1+t)/3;
end
          m = @(t,f) f(t).*exp(-t); dm = @(t,f) df(t).*exp(-t);

% precompute distances
if dg                                                               % vector kxx
  K = zeros(size(x,1),1);
else
  if xeqz                                                 % symmetric matrix Kxx
    K = sq_dist(diag(sqrt(d)./ell)*x');
  else                                                   % cross covariances Kxz
    K = sq_dist(diag(sqrt(d)./ell)*x',diag(sqrt(d)./ell)*z');
  end
end

if nargin<5                                                        % covariances
  K = sf2*m(sqrt(K),f);
else                                                               % derivatives
  if i<=D                                               % length scale parameter
    if dg
      Ki = zeros(size(x,1),1);
    else
      if xeqz
        Ki = sq_dist(sqrt(d)/ell(i)*x(:,i)');
      else
        Ki = sq_dist(sqrt(d)/ell(i)*x(:,i)',sqrt(d)/ell(i)*z(:,i)');
      end
    end
    K = sf2*dm(sqrt(K),f).*Ki;
    K(Ki<1e-12) = 0;                                    % fix limit case for d=1
  elseif i==D+1                                            % magnitude parameter
    K = 2*sf2*m(sqrt(K),f);
  else
    error('Unknown hyperparameter')
  end
end


%EX_TUMBLE Generate synthetic sensor data for a tumbling body
%
% Sets a number of workspace variables:
% t         time vector (1xN)
% w         angular velocity (3xN)
% truth     actual orientation as a unit quaternion (1xN)
% wm        simulated gyro output with bias (3xN)
% am        simulated accelerometer output with bias (3xN)
% mm        simulated magnetometer output with bias (3xN)
%
% Used on pages 81 and 89 of Robotics, Vision & Control, 2nd ed.

% Copyright (C) 1993-2017, 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

%% parameters (user adjustable)

dt = 0.05;          % sample interval

% make an asymmetric mass
J = diag([2 4 3]);
J(1,2) = -1;
J(2,1) = -1;
J(1,3) = -2;
J(3,1) = -2;
%eig(J)

% accelerometer
g0 = unit( [0, 0, 9.8]' );
gbias = 0.02*[2 -2 2]';  % bias 2% of norm

% magnetometer, use N E U data in nT  for Brisbane
m0 = unit( [28067.5, -5439.4, 44800.5]'*1e-9 );
mbias = 0.02*[-1 -1 2]';   % bias 2% of norm

% gyro
w0 = 0.2*[1 2 2]';
wbias = 0.1*[-1 2 -1]'; % bias 10% of max

%% simulation

% Solve Euler's rotational dynamic equation to get omega
[t,w] = ode45( @(t,w) -inv(J)*(cross(w, J*w)), [0:dt:20], w0);
w = w';  % one column per timestep

% Compute simulated sensor readings and true attitude
gm = zeros(3, numcols(w));
mm = zeros(3, numcols(w));

truth(1) = UnitQuaternion();

for k=1:numcols(w)-1
        iq = inv(truth(k));
        gm(:,k) = iq * g0 + gbias;  % sensor reading in body frame
        mm(:,k) = iq * m0 + mbias;  % sensor reading
        truth(k+1) = truth(k) .* UnitQuaternion.omega( w(:,k)*dt );
end

% add bias to measured angular velocity
wm = bsxfun(@plus, w, wbias);


function [Texp,Lexp]=lyapunov(n,rhs_ext_fcn,fcn_integrator,tstart,stept,tend,ystart,ioutp);
%
%    Lyapunov exponent calcullation for ODE-system.
%
%    The alogrithm employed in this m-file for determining Lyapunov
%    exponents was proposed in
%
%         A. Wolf, J. B. Swift, H. L. Swinney, and J. A. Vastano,
%        "Determining Lyapunov Exponents from a Time Series," Physica D,
%        Vol. 16, pp. 285-317, 1985.
%
%    For integrating ODE system can be used any MATLAB ODE-suite methods.
% This function is a part of MATDS program - toolbox for dynamical system investigation
%    See:    http://www.math.rsu.ru/mexmat/kvm/matds/
%
%    Input parameters:
%      n - number of equation
%      rhs_ext_fcn - handle of function with right hand side of extended ODE-system.
%              This function must include RHS of ODE-system coupled with
%              variational equation (n items of linearized systems, see Example).
%      fcn_integrator - handle of ODE integrator function, for example: @ode45
%      tstart - start values of independent value (time t)
%      stept - step on t-variable for Gram-Schmidt renormalization procedure.
%      tend - finish value of time
%      ystart - start point of trajectory of ODE system.
%      ioutp - step of print to MATLAB main window. ioutp==0 - no print,
%              if ioutp>0 then each ioutp-th point will be print.
%
%    Output parameters:
%      Texp - time values
%      Lexp - Lyapunov exponents to each time value.
%
%    Users have to write their own ODE functions for their specified
%    systems and use handle of this function as rhs_ext_fcn - parameter.
%
%    Example. Lorenz system:
%               dx/dt = sigma*(y - x)     = f1
%               dy/dt = r*x - y - x*z = f2
%               dz/dt = x*y - b*z     = f3
%
%    The Jacobian of system:
%        | -sigma  sigma  0 |
%    J = |   r-z    -1   -x |
%        |    y      x   -b |
%
%    Then, the variational equation has a form:
%
%    F = J*Y
%    where Y is a square matrix with the same dimension as J.
%    Corresponding m-file:
%        function f=lorenz_ext(t,X)
%         SIGMA = 10; R = 28; BETA = 8/3;
%         x=X(1); y=X(2); z=X(3);
%
%         Y= [X(4), X(7), X(10);
%             X(5), X(8), X(11);
%             X(6), X(9), X(12)];
%         f=zeros(9,1);
%         f(1)=SIGMA*(y-x); f(2)=-x*z+R*x-y; f(3)=x*y-BETA*z;
%
%         Jac=[-SIGMA,SIGMA,0; R-z,-1,-x; y, x,-BETA];
%
%         f(4:12)=Jac*Y;
%
%    Run Lyapunov exponent calculation:
%
%    [T,Res]=lyapunov(3,@lorenz_ext,@ode45,0,0.5,200,[0 1 0],10);
%
%    See files: lorenz_ext, run_lyap.
%
% --------------------------------------------------------------------
% Copyright (C) 2004, Govorukhin V.N.
% This file is intended for use with MATLAB and was produced for MATDS-program
% http://www.math.rsu.ru/mexmat/kvm/matds/
% lyapunov.m is free software. lyapunov.m is distributed in the hope that it
% will be useful, but WITHOUT ANY WARRANTY.
%

%
%       n=number of nonlinear odes
%       n2=n*(n+1)=total number of odes
%

n1=n; n2=n1*(n1+1);

%  Number of steps

nit = round((tend-tstart)/stept);

% Memory allocation

y=zeros(n2,1); cum=zeros(n1,1); y0=y;
gsc=cum; znorm=cum;

% Initial values

y(1:n)=ystart(:);

for i=1:n1 y((n1+1)*i)=1.0; end;

t=tstart;

% Main loop

for ITERLYAP=1:nit

% Solutuion of extended ODE system

  [T,Y] = feval(fcn_integrator,rhs_ext_fcn,[t t+stept],y);

  t=t+stept;
  y=Y(size(Y,1),:);

  for i=1:n1
      for j=1:n1 y0(n1*i+j)=y(n1*j+i); end;
  end;

%
%       construct new orthonormal basis by gram-schmidt
%

  znorm(1)=0.0;
  for j=1:n1 znorm(1)=znorm(1)+y0(n1*j+1)^2; end;

  znorm(1)=sqrt(znorm(1));

  for j=1:n1 y0(n1*j+1)=y0(n1*j+1)/znorm(1); end;

  for j=2:n1
      for k=1:(j-1)
          gsc(k)=0.0;
          for l=1:n1 gsc(k)=gsc(k)+y0(n1*l+j)*y0(n1*l+k); end;
      end;

      for k=1:n1
          for l=1:(j-1)
              y0(n1*k+j)=y0(n1*k+j)-gsc(l)*y0(n1*k+l);
          end;
      end;

      znorm(j)=0.0;
      for k=1:n1 znorm(j)=znorm(j)+y0(n1*k+j)^2; end;
      znorm(j)=sqrt(znorm(j));

      for k=1:n1 y0(n1*k+j)=y0(n1*k+j)/znorm(j); end;
  end;

%
%       update running vector magnitudes
%

  for k=1:n1 cum(k)=cum(k)+log(znorm(k)); end;

%
%       normalize exponent
%

  for k=1:n1
      lp(k)=cum(k)/(t-tstart);
  end;

% Output modification

  if ITERLYAP==1
     Lexp=lp;
     Texp=t;
  else
     Lexp=[Lexp; lp];
     Texp=[Texp; t];
  end;

  if (mod(ITERLYAP,ioutp)==0)
     fprintf('t=%6.4f',t);
     for k=1:n1 fprintf(' %10.6f',lp(k)); end;
     fprintf('\n');
  end;

  for i=1:n1
      for j=1:n1
          y(n1*j+i)=y0(n1*i+j);
      end;
  end;

end;


%% Auto2Fit Test Problems
%http://www.7d-soft.com/en/AF_Examples.htm#5:%20Chart
clear all
clc
load auto2fitData

%% Problem 1.1 - Mount Curve
clc
%Fitting Function
fun = @(m,xdata) m(1)/m(2) * exp(-0.5 * ((xdata-m(3))./m(2)).^2);
%Data
xdata = data11(:,2);
ydata = data11(:,3);

%Problem Setup
opts = optiset('display','iter','solver','nomad');
Opt = opti('fun',fun,'data',xdata,ydata,'x0',[1;3;460],'bounds',[0;0;100],[5;10;1000],'options',opts)

%Solve & Plot
[x,f,e,i] = solve(Opt)
plot(Opt)

%% Problem 1.1 - Mount Curve [multi-solve]
clc
%Fitting Function
fun = @(m,xdata) m(1)/m(2) * exp(-0.5 * ((xdata-m(3))./m(2)).^2);
%Data
xdata = data11(:,2);
ydata = data11(:,3);

%Problem Setup
opts = optiset('display','final','solver','nl2sol');
Opt = opti('fun',fun,'data',xdata,ydata,'bounds',[0;0;100],[5;10;1000],'options',opts)

%Solve & Plot
[x,f,e,i] = multisolve(Opt,[],12)
plot(Opt)

%% Problem 1.2 - Cos Function
clc
%Fitting Function
fun = @(m,xdata) (m(1)./xdata(:,1) - cos(m(2).*xdata(:,2))) .* xdata(:,3)./xdata(:,1) .* m(3);
%Data
xdata = data12(:,2:4);
ydata = data12(:,end);

%Problem Setup
opts = optiset('display','iter','solver','nomad');
Opt = opti('fun',fun,'data',xdata,ydata,'x0',[1;40;1],'bounds',[0;0;0],[5;100;5],'options',opts)

%Solve & Plot
[x,f,e,i] = solve(Opt)
plot(Opt)

%% Problem 1.2 - Cos Function [multi-solve]
clc
%Fitting Function
fun = @(m,xdata) (m(1)./xdata(:,1) - cos(m(2).*xdata(:,2))) .* xdata(:,3)./xdata(:,1) .* m(3);
%Data
xdata = data12(:,2:4);
ydata = data12(:,end);

%Problem Setup
opts = optiset('display','final','solver','nl2sol');
Opt = opti('fun',fun,'data',xdata,ydata,'x0',[1;40;1],'bounds',[0;0;0],[5;100;5],'options',opts)

%Solve & Plot
[x,f,e,i] = multisolve(Opt)
plot(Opt)

%% Problem 1.2 - Cos Function [multi-solve, 2 variable version]
clc
%Fitting Function
fun = @(m,xdata) (2.4923./xdata(:,1) - cos(m(1)*xdata(:,2))) .* xdata(:,3)./xdata(:,1) .* m(2);
%Data
xdata = data12(:,2:4);
ydata = data12(:,end);

%Problem Setup
opts = optiset('display','final','solver','auto');
Opt = opti('fun',fun,'data',xdata,ydata,'bounds',[0;0],[100;5],'options',opts)

%Solve & Plot
[x,f,e,i] = multisolve(Opt,[],[5 3])

figure(1);
plot(Opt)
figure(2);
multiplot(Opt,1,75)

%% Problem 1.3 - SinCos Function (data appears wrong)
% clc
% %Fitting Function
% fun = @(a,xdata) (a(1) + xdata(:,1)./a(2) + cos(a(3) * xdata(:,2)./xdata(:,3)))./(a(4) .* sin(xdata(:,1) + xdata(:,2) + xdata(:,3)));
% %Data
% xdata = data13(:,2:4);
% ydata = data13(:,end);
%
% %Problem Setup
% opts = optiset('display','iter','solver','nomad');
% Opt = opti('fun',fun,'data',xdata,ydata,'x0',[1 1 10 1],'options',opts)
%
% %Solve & Plot
% [x,f,e,i] = solve(Opt)
% plot(Opt)


function lpp_value_test ( )

%*****************************************************************************80
%
%% LPP_VALUE_TEST tests LPP_VALUE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 October 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LPP_VALUE_TEST:\n' );
  fprintf ( 1, '  LPP_VALUE evaluates a Legendre product polynomial.\n' );

  m = 3;
  n = 1;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( m, -1.0, +1.0, seed );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Evaluate at X = ( %g, %g, %g )\n', x(1:3) )
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Rank  I1  I2  I3:  L(I1,X1)*L(I2,X2)*L(I3,X3)  P(X1,X2,X3)\n' );
  fprintf ( 1, '\n' );

  for rank = 1 : 20

    l = comp_unrank_grlex ( m, rank );
%
%  Evaluate the LPP directly.
%
    v1 = lpp_value ( m, n, l, x );
%
%  Convert the LPP to a polynomial, and reevaluate.
%
    o_max = prod ( floor ( ( l(1:m) + 2 ) / 2 ) );

    [ o, c, e ] = lpp_to_polynomial ( m, l, o_max );

    v2 = polynomial_value ( m, o, c, e, n, x );
%
%  Compare results.
%
    fprintf ( 1, '  %4d  %2d  %2d  %2d  %12g  %12g\n', rank, l(1:m), v1, v2 );

  end

  return
end


function [yData,betas,P,errors] = tsne_d(D, parameters)
%TSNE_D Performs symmetric t-SNE on the pairwise Euclidean distance matrix D
%
%   [yData,betas,P,errors] = tsne_d(D, parameters)
%
% The function performs symmetric t-SNE on the NxN pairwise
% distance matrix D to construct an embedding with no_dims dimensions
% (default = 2). An initial solution obtained from an other dimensionality
% reduction technique may be specified in initial_solution.
% The perplexity of the Gaussian kernel that is employed can be specified
% through perplexity.
%
%
%   Input variables:
%
%       D -> NxN distance matrix
%       parameters -> structure containing non-default parameters
%
%
%   Output variables:
%
%       yData -> Nx2 (or Nx3) array of embedded values
%       betas -> list of individual area parameters
%       P -> sparse transition matrix
%       errors -> D_{KL}(P || Q) as a function of iteration
%
%
% (C) Laurens van der Maaten, 2010
% University of California, San Diego
%
%  Modified by Gordon J. Berman, 2014
%  Princeton University

    no_dims = parameters.num_tsne_dim;
    perplexity = parameters.perplexity;
    sigmaTolerance = parameters.sigmaTolerance;
    relTol = parameters.relTol;

    if numel(no_dims) > 1
        initial_solution = true;
        yData = no_dims;
        no_dims = size(ydata, 2);
    else
        initial_solution = false;
    end

    D = D / max(D(:));
    [P,betas] = d2p_sparse(D .^ 2, perplexity, sigmaTolerance);
    P(isnan(P)) = 0;

    clear D

    % Run t-SNE
    if initial_solution
        [yData,errors] = tsne_p_sparse(P, parameters, yData, relTol);
    else
        [yData,errors] = tsne_p_sparse(P, parameters, no_dims, relTol);
    end


function edge_length = tetrahedron_edge_length_3d ( tetra )

%*****************************************************************************80
%
%% TETRAHEDRON_EDGE_LENGTH_3D returns edge lengths of a tetrahedron in 3D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 May 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real TETRA(3,4), the tetrahedron vertices.
%
%    Output, real EDGE_LENGTH(6,1), the length of the edges.
%
  dim_num = 3;
  edge_length = zeros ( 6, 1 );

  k = 0;
  for j1 = 1 : 3
    for j2 = j1+1 : 4
      k = k + 1;
      edge_length(k) = r8vec_length ( dim_num, ...
        tetra(1:dim_num,j2) - tetra(1:dim_num,j1) );
    end
  end

  return
end


% Copyright (c) Technische Universität München, 2012
% All rights reserved.
%
% Author: Clemens Hage
% Contact: hage@tum.de
% Date: 2012-11-12
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.

% This script runs a quick numerical demo on Robust PCA (batch mode with
% incomplete observation)

% Dimension of the data set
m = 400;

% Number of samples
n = 400;

% Dimension of the underlying subspace
k = 40; % i.e. relative rank of 0.1

% Relative density of outliers
rho = 0.1; % i.e. 10% of the matrix entries are corrupted

% Max. magnitude of the outliers
amplitude = 5;

% Create test data
[X,L_0]=testdata(m,n,k,rho,amplitude,0);

support=0.5; % 50% of the entries are observed

% Create support set

% number of observed entries
nentries = ceil(support * m * n);

% random positions
indices = randperm(m*n,nentries);

% convert to indices
[i,j]=ind2sub([m n],indices);

% create sparse matrix
Omega = sparse(i,j,true(nentries,1),m,n,nentries);

% run Robust PCA
L=robustpca_batch(X,k,'atansquare','L_0',L_0,'Omega',Omega);

% Compute relative subspace reconstruction error
err = norm(Omega.*L-Omega.*L_0,'fro') / norm(Omega.*L_0,'fro');
display(['Relative subspace reconstruction error (robust method): ' num2str(err)])

% % Compare to common PCA approach
X_sampled = Omega.*X;
[U,~,~]=svds(X_sampled,k);

L_PCA = U * (U' * X_sampled);

err_PCA = norm(Omega.*L_PCA-Omega.*L_0,'fro') / norm(Omega.*L_0,'fro');
display(['Relative subspace reconstruction error (common PCA): ' num2str(err_PCA)])


%  DemoTV_UP.m
%
%  This is a short script that performs TV minimization recovery
%   from partial Fourier measurements
%
%  min Lambda ||x||_TV +1/2||b - A x||_2
%
%  Here A*A is assumed to be an orthogonal projector
%
%  Parameters to set : 1) n : the size of the image to reconstruct (default: 128)
%                      2) Dyna : the dynamic range of the original image (in dB) (default : 40)
%                      3) Lambda : value of the Lagrange multiplier (default: 0.05)
%
%  Created entities : I : original image
%                     Xnesta : image recovered with Nesta
%                     NA_nesta = number of calls of A or A* for the method
%
% Written by: Jerome Bobin, Caltech
% Email: bobin@acm.caltech.edu
% Created: May 2009
%
% NESTA Version 1.1
%   See also NESTA_UP and Core_Nesterov_UP
clear; clc;
n = 128;   %--- The data are n*n images
Dyna = 40; %--- Dynamic range in dB
Lambda = 0.05;
Setup_Nesta % -- add the solvers to the path
%% Setting up the experiment

N = n*n;
I=MakeRDSquares(n,7,Dyna);
x = reshape(I,n*n,1);
L = floor(55*(n/256)); %--- so as to get a compression ratio ~10
[M,Mh,mi,mhi] = LineMask(L,n);
OMEGA = mhi;
OMEGA = [OMEGA];
K = length(OMEGA);
A = @(z) A_fhp(z,OMEGA);
At = @(z) At_fhp(z,OMEGA,n);
b0 = A(x);
sigma = 0.1;
noise = sigma*randn(size(b0));
b = b0+noise;

fprintf('##############################################\n\n');
fprintf('NESTA: Total Variation minimization experiment\n\n');
fprintf('##############################################\n\n');
fprintf('Image size = %g x %g / Dynamic range : %g / Noise level : %g\n\n',n,n,Dyna,sigma);

%% Setting up the experiment for NESTA

fprintf(' NESTA starts\n\n');
U = @(z) z;
Ut = @(z) z;
mu = 0.2; %--- can be chosen to be small
opts = [];
opts.maxintiter = 5;
opts.TOlVar = 1e-4;
opts.verbose = 25;
opts.maxiter = 5000;
opts.U = U;
opts.Ut = Ut;
opts.stoptest = 1;
opts.typemin = 'tv';
counter();
Ac = @(z) counter(A,z);
Atc = @(z) counter(At,z);
tic;
[x_nesta,niter,resid,err] = NESTA_UP(Ac,Atc,b,Lambda,1,mu,opts);
t.NESTA = toc;
NA_nesta = counter();
tvnesta = calctv(n,n,reshape(x_nesta,n,n));
Xnesta = reshape(x_nesta,n,n);

% -- Print results

fprintf('\nNESTA: TV: %g -- ||b-Ax|| = %g -- # calls : %g\n\n',tvnesta,norm(b - A(Xnesta(:))),NA_nesta);
fprintf('relative l2 error compared to original signal: %.2e\n',norm(Xnesta-I,'fro')/norm(I,'fro') );
%% Plot results
figure(1); clf;

subplot(1,2,1);
image( I );  title('Original image');
map = colormap(hsv);
map(1,:) = [1,1,1];
colormap(map);
% colorbar('westoutside');
axis square; axis off

subplot(1,2,2);
image(Xnesta); title(sprintf(...
    'Reconstruction via NESTA\n%.1f sec',t.NESTA));
axis square; axis off


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

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

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

% ====================== YOUR CODE HERE ======================
% Instructions: Go over every example, find its closest centroid, and store
%               the index inside idx at the appropriate location.
%               Concretely, idx(i) should contain the index of the centroid
%               closest to example i. Hence, it should be a value in the
%               range 1..K
%
% Note: You can use a for-loop over the examples to compute this.
%

for i=1:size(X, 1)
    distances = zeros(size(centroids, 1), 1);
    for k=1:K
        distances(k) = sumsq(X(i,:) - centroids(k, :));
    end;
    [minDistance, minIndex] = min(distances);
    idx(i) = minIndex;
end;

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

end


function sphere_fibonacci_grid_points_test ( )

%*****************************************************************************80
%
%% SPHERE_FIBONACCI_GRID_POINTS_TEST tests SPHERE_FIBONACCI_GRID_POINTS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 April 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPHERE_FIBONACCI_GRID_POINTS_TEST\n' );
  fprintf ( 1, '  SPHERE_FIBONACCI_GRID_POINTS computes points on a sphere\n' );
  fprintf ( 1, '  that lie on a Fibonacci spiral.\n' );

  ng = 1000;
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of points NG = %d\n', ng );

  xg = sphere_fibonacci_grid_points ( ng );

  r8mat_print_some ( ng, 3, xg, 1, 1, 20, 3, '  Part of the grid array:' );
%
%  Display the nodes on a sphere.
%
  filename = sprintf ( 'sphere_fibonacci_grid_n%d.png', ng );

  sphere_fibonacci_grid_display ( ng, xg, filename );
%
%  Write the nodes to a file.
%
  filename = sprintf ( 'sphere_fibonacci_grid_n%d.xyz', ng );

  r8mat_write ( filename, ng, 3, xg )

  return
end


function hermite_rule ( n, a, b, scale, filename )

%*****************************************************************************80
%
%% HERMITE_RULE generates a Gauss-Hermite rule.
%
%  Discussion:
%
%    This program computes a Gauss-Hermite quadrature rule
%    and writes it to a file.
%
%    The integral to be approximated has the form
%
%      C * integral ( -oo < x < +oo ) f(x) rho(x) dx
%
%    where the weight rho(x) is:
%
%      rho(x) = exp ( - b * ( x - a )^2 ) * sqrt ( b / pi ) dx
%
%    and A and B are parameters.
%
%    The user specifies:
%    * N, the number of points in the rule;
%    * A, the center point;
%    * B, the scale factor in the exponential;
%    * SCALE, is 1 if the weights are to be normalized;
%    * FILENAME, the root name of the output files.
%
%    If SCALE = 0, then the factor C in front of the integrand is 1.
%    If SCALE is nonzero, then the factor C is sqrt ( B ) / sqrt ( PI ).
%    which means that the function f(x)=1 will integrate to 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 February 2014
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HERMITE_RULE\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Compute a Gauss-Hermite rule for approximating\n' );
  fprintf ( 1, '    integral ( -oo < x < +oo ) f(x) rho(x) dx\n' );
  fprintf ( 1, '  where the weight rho(x) is:\n' );
  fprintf ( 1, '    exp ( - b * ( x - a )^2 ) * sqrt ( b / pi ) dx\n' );
  fprintf ( 1, '  using N points.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The user specifies N, A, B, SCALE, FILENAME.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  N is the number of points;\n' );
  fprintf ( 1, '  A is the center point (typically 0).\n' );
  fprintf ( 1, '  B is the exponential scale factor (typically 1).\n' );
  fprintf ( 1, '  SCALE is 1 if the weights are to be normalized.\n');
  fprintf ( 1, '  FILENAME is used to generate 3 files:\n' );
  fprintf ( 1, '    filename_w.txt - the weight file\n' );
  fprintf ( 1, '    filename_x.txt - the abscissa file.\n' );
  fprintf ( 1, '    filename_r.txt - the region file.\n' );
%
%  Initialize the parameters.
%
  alpha = 0.0;
  beta = 0.0;
%
%  Get N.
%
  if ( nargin < 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  N is the number of points in the rule, such as 5.\n' );
    n = input ( '  Enter N: ' );
  elseif ( ischar ( n ) )
    n = str2num ( n );
  end
%
%  Get A.
%
  if ( nargin < 2 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  A is the center point, typically 0.\n' );
    fprintf ( 1, '\n' );
    a = input ( '  Enter A: ' );
  elseif ( ischar ( a ) )
    a = str2num ( a );
  end
%
%  Get B.
%
  if ( nargin < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  B is the scale factor, typically 0.5 or 1.0.\n' );
    fprintf ( 1, '\n' );
    b = input ( '  Enter B: ' );
  elseif ( ischar ( b ) )
    b = str2num ( b );
  end
%
%  Get SCALE.
%
  if ( nargin < 4 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  SCALE is 1 to normalize the weights, 0 otherwise.\n' );
    fprintf ( 1, '\n' );
    b = input ( '  Enter SCALE (0/1): ' );
  elseif ( ischar ( scale ) )
    scale = str2num ( scale );
  end
%
%  Get FILENAME.
%
  if ( nargin < 5 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  FILENAME is the ''root name'' of the quadrature files).\n' );
    filename = input ( '  Enter FILENAME as a quoted string:' );
  end
%
%  Input summary.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Input summary:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  N = %d\n', n );
  fprintf ( 1, '  A = %f\n', a );
  fprintf ( 1, '  B = %f\n', b );
  fprintf ( 1, '  SCALE = %d\n', scale );
  fprintf ( 1, '  FILENAME = "%s".\n', filename );
%
%  Construct the rule.
%
  kind = 6;
  [ x, w ] = cgqf ( n, kind, alpha, beta, a, b );
%
%  Normalize the rule.
%  This way, the weights add up to 1.
%
  if ( scale == 1.0 )
    w(1:n) = w(1:n) * sqrt ( b ) / sqrt ( pi );
  end
%
%  Set the R values to suggest an infinite interval.
%
  r = zeros ( 2, 1 );
  r(1) = - r8_huge ( );
  r(2) =   r8_huge ( );
%
%  Write the rule.
%
  rule_write ( n, filename, x, w, r );
%
%  Terminate.
%
  fprintf ( 1,  '\n' );
  fprintf ( 1,  'HERMITE_RULE:\n' );
  fprintf ( 1,  '  Normal end of execution.\n' );
  fprintf ( 1,  '\n' );
  timestamp ( );

  return
end
function [ t, wts ] = cdgqf ( nt, kind, alpha, beta )

%*****************************************************************************80
%
%% CDGQF computes a Gauss quadrature formula with default A, B and simple knots.
%
%  Discussion:
%
%    This routine computes all the knots and weights of a Gauss quadrature
%    formula with a classical weight function with default values for A and B,
%    and only simple knots.
%
%    There are no moments checks and no printing is done.
%
%    Use routine EIQFS to evaluate a quadrature computed by CGQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
%
%    Input, real ALPHA, the value of Alpha, if needed.
%
%    Input, real BETA, the value of Beta, if needed.
%
%    Output, real T(NT), the knots.
%
%    Output, real WTS(NT), the weights.
%
  parchk ( kind, 2 * nt, alpha, beta );
%
%  Get the Jacobi matrix and zero-th moment.
%
  [ aj, bj, zemu ] = class_matrix ( kind, nt, alpha, beta );
%
%  Compute the knots and weights.
%
  [ t, wts ] = sgqf ( nt, aj, bj, zemu );

  return
end
function [ t, wts ] = cgqf ( nt, kind, alpha, beta, a, b )

%*****************************************************************************80
%
%% CGQF computes knots and weights of a Gauss quadrature formula.
%
%  Discussion:
%
%    The user may specify the interval (A,B).
%
%    Only simple knots are produced.
%
%    The user may request that the routine print the knots and weights,
%    and perform a moment check.
%
%    Use routine EIQFS to evaluate this quadrature formula.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 February 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev Type 1,     (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,+oo)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-oo,+oo)   |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,+oo)     (x-a)^alpha*(x+b)^beta
%    9, Chebyshev Type 2,     (a,b)       ((b-x)*(x-a))^(+0.5)
%
%    Input, real ALPHA, the value of Alpha, if needed.
%
%    Input, real BETA, the value of Beta, if needed.
%
%    Input, real A, B, the interval endpoints.
%
%    Output, real T(NT), the knots.
%
%    Output, real WTS(NT), the weights.
%

%
%  Compute the Gauss quadrature formula for default values of A and B.
%
  [ t, wts ] = cdgqf ( nt, kind, alpha, beta );
%
%  All knots have multiplicity = 1.
%
  mlt = zeros(nt,1);
  mlt(1:nt) = 1;
%
%  NDX(I) = I.
%
  ndx = ( 1 : nt );
%
%  Scale the quadrature rule.
%
  [ t, wts ] = scqf ( nt, t, mlt, wts, nt, ndx, kind, alpha, beta, a, b );

  return
end
function [ aj, bj, zemu ] = class_matrix ( kind, m, alpha, beta )

%*****************************************************************************80
%
%% CLASS_MATRIX computes the Jacobi matrix for a quadrature rule.
%
%  Discussion:
%
%    This routine computes the diagonal AJ and subdiagonal BJ
%    elements of the order M tridiagonal symmetric Jacobi matrix
%    associated with the polynomials orthogonal with respect to
%    the weight function specified by KIND.
%
%    For weight functions 1-7, M elements are defined in BJ even
%    though only M-1 are needed.  For weight function 8, BJ(M) is
%    set to zero.
%
%    The zero-th moment of the weight function is returned in ZEMU.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
%
%    Input, integer M, the order of the Jacobi matrix.
%
%    Input, real ALPHA, the value of Alpha, if needed.
%
%    Input, real BETA, the value of Beta, if needed.
%
%    Output, real AJ(M), BJ(M), the diagonal and subdiagonal
%    of the Jacobi matrix.
%
%    Output, real ZEMU, the zero-th moment.
%
  temp = eps;

  parchk ( kind, 2 * m - 1, alpha, beta );

  temp2 = 0.5;

  if ( 500.0 * temp < abs ( ( gamma ( temp2 ) )^2 - pi ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CLASS - Fatal error!\n' );
    fprintf ( 1, '  Gamma function does not match machine parameters.\n' );
    error ( 'CLASS - Fatal error!' );
  end

  bj = zeros(m,1);
  aj = zeros(m,1);

  if ( kind == 1 )

    ab = 0.0;

    zemu = 2.0 / ( ab + 1.0 );

    aj(1:m) = 0.0;

    for i = 1 : m
      abi = i + ab * mod ( i, 2 );
      abj = 2 * i + ab;
      bj(i) = abi * abi / ( abj * abj - 1.0 );
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 2 )

    zemu = pi;

    aj(1:m) = 0.0;

    bj(1) =  sqrt ( 0.5 );
    bj(2:m) = 0.5;

  elseif ( kind == 3 )

    ab = alpha * 2.0;
    zemu = 2.0^( ab + 1.0 ) * gamma ( alpha + 1.0 )^2 ...
      / gamma ( ab + 2.0 );

    aj(1:m) = 0.0;
    bj(1) = 1.0 / ( 2.0 * alpha + 3.0 );
    for i = 2 : m
      bj(i) = i * ( i + ab ) / ( 4.0 * ( i + alpha )^2 - 1.0 );
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 4 )

    ab = alpha + beta;
    abi = 2.0 + ab;
    zemu = 2.0^( ab + 1.0 ) * gamma ( alpha + 1.0 ) ...
      * gamma ( beta + 1.0 ) / gamma ( abi );
    aj(1) = ( beta - alpha ) / abi;
    bj(1) = 4.0 * ( 1.0 + alpha ) * ( 1.0 + beta ) ...
      / ( ( abi + 1.0 ) * abi * abi );
    a2b2 = beta * beta - alpha * alpha;

    for i = 2 : m
      abi = 2.0 * i + ab;
      aj(i) = a2b2 / ( ( abi - 2.0 ) * abi );
      abi = abi^2;
      bj(i) = 4.0 * i * ( i + alpha ) * ( i + beta ) * ( i + ab ) ...
        / ( ( abi - 1.0 ) * abi );
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 5 )

    zemu = gamma ( alpha + 1.0 );

    for i = 1 : m
      aj(i) = 2.0 * i - 1.0 + alpha;
      bj(i) = i * ( i + alpha );
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 6 )

    zemu = gamma ( ( alpha + 1.0 ) / 2.0 );

    aj(1:m) = 0.0;

    for i = 1 : m
      bj(i) = ( i + alpha * mod ( i, 2 ) ) / 2.0;
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 7 )

    ab = alpha;
    zemu = 2.0 / ( ab + 1.0 );

    aj(1:m) = 0.0;

    for i = 1 : m
      abi = i + ab * mod(i,2);
      abj = 2 * i + ab;
      bj(i) = abi * abi / ( abj * abj - 1.0 );
    end
    bj(1:m) =  sqrt ( bj(1:m) );

  elseif ( kind == 8 )

    ab = alpha + beta;
    zemu = gamma ( alpha + 1.0 ) * gamma ( - ( ab + 1.0 ) ) ...
      / gamma ( - beta );
    apone = alpha + 1.0;
    aba = ab * apone;
    aj(1) = - apone / ( ab + 2.0 );
    bj(1) = - aj(1) * ( beta + 1.0 ) / ( ab + 2.0 ) / ( ab + 3.0 );
    for i = 2 : m
      abti = ab + 2.0 * i;
      aj(i) = aba + 2.0 * ( ab + i ) * ( i - 1 );
      aj(i) = - aj(i) / abti / ( abti - 2.0 );
    end

    for i = 2 : m - 1
      abti = ab + 2.0 * i;
      bj(i) = i * ( alpha + i ) / ( abti - 1.0 ) * ( beta + i ) ...
        / ( abti^2 ) * ( ab + i ) / ( abti + 1.0 );
    end

    bj(m) = 0.0;
    bj(1:m) =  sqrt ( bj(1:m) );

  end

  return
end
function [ d, z ] = imtqlx ( n, d, e, z )

%*****************************************************************************80
%
%% IMTQLX diagonalizes a symmetric tridiagonal matrix.
%
%  Discussion:
%
%    This routine is a slightly modified version of the EISPACK routine to
%    perform the implicit QL algorithm on a symmetric tridiagonal matrix.
%
%    The authors thank the authors of EISPACK for permission to use this
%    routine.
%
%    It has been modified to produce the product Q' * Z, where Z is an input
%    vector and Q is the orthogonal matrix diagonalizing the input matrix.
%    The changes consist (essentialy) of applying the orthogonal transformations
%    directly to Z as they are generated.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%    Roger Martin, James Wilkinson,
%    The Implicit QL Algorithm,
%    Numerische Mathematik,
%    Volume 12, Number 5, December 1968, pages 377-383.
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real D(N), the diagonal entries of the matrix.
%
%    Input, real E(N), the subdiagonal entries of the
%    matrix, in entries E(1) through E(N-1).
%
%    Input, real Z(N), a vector to be operated on.
%
%    Output, real D(N), the diagonal entries of the diagonalized matrix.
%
%    Output, real Z(N), the value of Q' * Z, where Q is the matrix that
%    diagonalizes the input symmetric tridiagonal matrix.
%
  itn = 30;

  prec = eps;

  if ( n == 1 )
    return
  end

  e(n) = 0.0;

  for l = 1 : n

    j = 0;

    while ( 1 )

      for m = l : n

        if ( m == n )
          break
        end

        if ( abs ( e(m) ) <= prec * ( abs ( d(m) ) + abs ( d(m+1) ) ) )
          break
        end

      end

      p = d(l);

      if ( m == l )
        break
      end

      if ( j == itn )
        fprintf ( 1, '\n' );
        fprintf ( 1, 'IMTQLX - Fatal error!\n' );
        fprintf ( 1, '  Iteration limit exceeded.\n' );
        error ( 'IMTQLX - Fatal error!' );
      end

      j = j + 1;
      g = ( d(l+1) - p ) / ( 2.0 * e(l) );
      r =  sqrt ( g * g + 1.0 );
      g = d(m) - p + e(l) / ( g + r8_sign ( g ) * abs ( r ) );
      s = 1.0;
      c = 1.0;
      p = 0.0;
      mml = m - l;

      for ii = 1 : mml

        i = m - ii;
        f = s * e(i);
        b = c * e(i);

        if ( abs ( f ) >= abs ( g ) )
          c = g / f;
          r =  sqrt ( c * c + 1.0 );
          e(i+1) = f * r;
          s = 1.0 / r;
          c = c * s;
        else
          s = f / g;
          r =  sqrt ( s * s + 1.0 );
          e(i+1) = g * r;
          c = 1.0 / r;
          s = s * c;
        end

        g = d(i+1) - p;
        r = ( d(i) - g ) * s + 2.0 * c * b;
        p = s * r;
        d(i+1) = g + p;
        g = c * r - b;
        f = z(i+1);
        z(i+1) = s * z(i) + c * f;
        z(i) = c * z(i) - s * f;

      end

      d(l) = d(l) - p;
      e(l) = g;
      e(m) = 0.0;

    end

  end

  for ii = 2 : n

     i = ii - 1;
     k = i;
     p = d(i);

     for j = ii : n
       if ( d(j) < p )
         k = j;
         p = d(j);
       end
     end

     if ( k ~= i )
       d(k) = d(i);
       d(i) = p;
       p = z(i);
       z(i) = z(k);
       z(k) = p;
     end

  end

  return
end
function parchk ( kind, m, alpha, beta )

%*****************************************************************************80
%
%% PARCHK checks parameters ALPHA and BETA for classical weight functions.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
%
%    Input, integer M, the order of the highest moment to
%    be calculated.  This value is only needed when KIND = 8.
%
%    Input, real ALPHA, BETA, the parameters, if required
%    by the value of KIND.
%
  if ( kind <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PARCHK - Fatal error!\n' );
    fprintf ( 1, '  KIND <= 0.\n' );
    error ( 'PARCHK - Fatal error!' );
  end
%
%  Check ALPHA for Gegenbauer, Jacobi, Laguerre, Hermite, Exponential.
%
  if ( 3 <= kind && alpha <= -1.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PARCHK - Fatal error!\n' );
    fprintf ( 1, '  3 <= KIND and ALPHA <= -1.\n' );
    error ( 'PARCHK - Fatal error!' );
  end
%
%  Check BETA for Jacobi.
%
  if ( kind == 4 && beta <= -1.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PARCHK - Fatal error!\n' );
    fprintf ( 1, '  KIND == 4 and BETA <= -1.0.\n' );
    error ( 'PARCHK - Fatal error!' );
  end
%
%  Check ALPHA and BETA for rational.
%
  if ( kind == 8 )
    tmp = alpha + beta + m + 1.0;
    if ( 0.0 <= tmp || tmp <= beta )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'PARCHK - Fatal error!\n' );
      fprintf ( 1, '  KIND == 8 but condition on ALPHA and BETA fails.\n' );
      error ( 'PARCHK - Fatal error!' );
    end
  end

  return
end
function value = r8_huge ( )

%*****************************************************************************80
%
%% R8_HUGE returns a "huge" real number.
%
%  Discussion:
%
%    The value returned by this function is NOT required to be the
%    maximum representable R8.  This value varies from machine to machine,
%    from compiler to compiler, and may cause problems when being printed.
%    We simply want a "very large" but non-infinite number.
%
%    MATLAB provides a built-in symbolic constant "inf" that can be used
%    if a huge number is really what you want!
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real VALUE, a huge number.
%
  value = 1.0E+30;

  return
end
function value = r8_sign ( x )

%*****************************************************************************80
%
%% R8_SIGN returns the sign of an R8.
%
%  Discussion:
%
%    The value is +1 if the number is positive or zero, and it is -1 otherwise.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 March 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the number whose sign is desired.
%
%    Output, real VALUE, the sign of X.
%
  if ( 0 <= x )
    value = +1.0;
  else
    value = -1.0;
  end

  return
end
function r8mat_write ( output_filename, m, n, table )

%*****************************************************************************80
%
%% R8MAT_WRITE writes an R8MAT file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 August 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the output filename.
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input, real TABLE(M,N), the points.
%

%
%  Open the file.
%
  output_unit = fopen ( output_filename, 'wt' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_WRITE - Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'R8MAT_WRITE - Error!' );
  end
%
%  Write the data.
%
%  For smaller data files, and less precision, try:
%
%     fprintf ( output_unit, '  %14.6f', table(i,j) );
%
  for j = 1 : n
    for i = 1 : m
      fprintf ( output_unit, '  %24.16f', table(i,j) );
    end
    fprintf ( output_unit, '\n' );
  end
%
%  Close the file.
%
  fclose ( output_unit );

  return
end
function rule_write ( order, filename, x, w, r )

%*****************************************************************************80
%
%% RULE_WRITE writes a quadrature rule to a file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ORDER, the order of the rule.
%
%    Input, string FILENAME, specifies the output files.
%    write files 'filename_w.txt', 'filename_x.txt', 'filename_r.txt' defining
%    weights, abscissas, and region.
%
%    Input, real X(ORDER), the abscissas.
%
%    Input, real W(ORDER), the weights.
%
%    Input, real R(2), the region.
%
  filename_x = strcat ( filename, '_x.txt' );
  filename_w = strcat ( filename, '_w.txt' );
  filename_r = strcat ( filename, '_r.txt' );

  fprintf ( 1, '\n' );
  fprintf ( 1,'  Creating quadrature files.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  "Root" file name is   "%s".\n', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Weight file will be   "%s".\n', filename_w );
  fprintf ( 1, '  Abscissa file will be "%s".\n', filename_x );
  fprintf ( 1, '  Region file will be   "%s".\n', filename_r );

  r8mat_write ( filename_w, 1, order, w' );
  r8mat_write ( filename_x, 1, order, x' );
  r8mat_write ( filename_r, 1, 2,     r' );

  return
end
function [ t, wts ] = scqf ( nt, t, mlt, wts, nwts, ndx, kind, alpha, ...
  beta, a, b )

%*****************************************************************************80
%
%% SCQF scales a quadrature formula to a nonstandard interval.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 February 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, real T(NT), the original knots.
%
%    Input, integer MLT(NT), the multiplicity of the knots.
%
%    Input, real WTS(NWTS), the weights.
%
%    Input, integer NWTS, the number of weights.
%
%    Input, integer NDX(NT), used to index the array WTS.
%    For more details see the comments in CAWIQ.
%
%    Input, integer KIND, the rule.
%    1, Legendre,             (a,b)       1.0
%    2, Chebyshev Type 1,     (a,b)       ((b-x)*(x-a))^(-0.5)
%    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
%    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
%    5, Generalized Laguerre, (a,+oo)     (x-a)^alpha*exp(-b*(x-a))
%    6, Generalized Hermite,  (-oo,+oo)   |x-a|^alpha*exp(-b*(x-a)^2)
%    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
%    8, Rational,             (a,+oo)     (x-a)^alpha*(x+b)^beta
%    9, Chebyshev Type 2,     (a,b)       ((b-x)*(x-a))^(+0.5)
%
%    Input, real ALPHA, the value of Alpha, if needed.
%
%    Input, real BETA, the value of Beta, if needed.
%
%    Input, real A, B, the interval endpoints.
%
%    Output, real T(NT), the scaled knots.
%
%    Output, real WTS(NWTS), the scaled weights.
%
  temp = eps;

  parchk ( kind, 1, alpha, beta )

  if ( kind == 1 )

    al = 0.0;
    be = 0.0;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  elseif ( kind == 2 )

    al = -0.5;
    be = -0.5;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  elseif ( kind == 3 )

    al = alpha;
    be = alpha;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  elseif ( kind == 4 )

    al = alpha;
    be = beta;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  elseif ( kind == 5 )

    if ( b <= 0.0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  B <= 0.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = a;
    slp = 1.0 / b;
    al = alpha;
    be = 0.0;

  elseif ( kind == 6 )

    if ( b <= 0.0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  B <= 0.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = a;
    slp = 1.0 / sqrt ( b );
    al = alpha;
    be = 0.0;

  elseif ( kind == 7 )

    al = alpha;
    be = 0.0;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  elseif ( kind == 8 )

    if ( a + b <= 0.0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  A + B <= 0.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = a;
    slp = a + b;
    al = alpha;
    be = beta;

  elseif ( kind == 9 )

    al = 0.5;
    be = 0.5;

    if ( abs ( b - a ) <= temp )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'SCQF - Fatal error!\n' );
      fprintf ( 1, '  |B - A| too small.\n' );
      fprintf ( 1, '  A = %f\n', a );
      fprintf ( 1, '  B = %f\n', b );
      error ( 'SCQF - Fatal error!' );
    end

    shft = ( a + b ) / 2.0;
    slp = ( b - a ) / 2.0;

  end

  p = slp^( al + be + 1.0 );

  for k = 1 : nt

    t(k) = shft + slp * t(k);
    l = abs ( ndx(k) );

    if ( l ~= 0 )
      tmp = p;
      for i = l : l + mlt(k) - 1
        wts(i) = wts(i) * tmp;
        tmp = tmp * slp;
      end
    end

  end

  return
end
function [ t, wts ] = sgqf ( nt, aj, bj, zemu )

%*****************************************************************************80
%
%% SGQF computes knots and weights of a Gauss Quadrature formula.
%
%  Discussion:
%
%    This routine computes all the knots and weights of a Gauss quadrature
%    formula with simple knots from the Jacobi matrix and the zero-th
%    moment of the weight function, using the Golub-Welsch technique.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Sylvan Elhay, Jaroslav Kautsky,
%    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of
%    Interpolatory Quadrature,
%    ACM Transactions on Mathematical Software,
%    Volume 13, Number 4, December 1987, pages 399-415.
%
%  Parameters:
%
%    Input, integer NT, the number of knots.
%
%    Input, real AJ(NT), the diagonal of the Jacobi matrix.
%
%    Input, real BJ(NT), the subdiagonal of the Jacobi
%    matrix, in entries 1 through NT-1.  On output, BJ has been overwritten.
%
%    Input, real ZEMU, the zero-th moment of the weight function.
%
%    Output, real T(NT), the knots.
%
%    Output, real WTS(NT), the weights.
%

%
%  Exit if the zero-th moment is not positive.
%
  if ( zemu <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'SGQF - Fatal error!\n' );
    fprintf ( 1, '  ZEMU <= 0.\n' );
    error ( 'SGQF - Fatal error!' );
  end
%
%  Set up vectors for IMTQLX.
%
  wts = zeros ( nt, 1 );

  wts(1) = sqrt ( zemu );
  wts(2:nt) = 0.0;
%
%  Diagonalize the Jacobi matrix.
%
  [ t, wts ] = imtqlx ( nt, aj, bj, wts );

  wts(1:nt) = wts(1:nt).^2;

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


%% Machine Learning Online Class - Exercise 2: Logistic Regression
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the second part
%  of the exercise which covers regularization with logistic regression.
%
%  You will need to complete the following functions in this exericse:
%
%     sigmoid.m
%     costFunction.m
%     predict.m
%     costFunctionReg.m
%
%  For this exercise, you will not need to change any code in this file,
%  or any other files other than those mentioned above.
%

%% Initialization
clear ; close all; clc

%% Load Data
%  The first two columns contains the X values and the third column
%  contains the label (y).

data = load('ex2data2.txt');
X = data(:, [1, 2]); y = data(:, 3);

plotData(X, y);

% Put some labels
hold on;

% Labels and Legend
xlabel('Microchip Test 1')
ylabel('Microchip Test 2')

% Specified in plot order
legend('y = 1', 'y = 0')
hold off;

%% =========== Part 1: Regularized Logistic Regression ============
%  In this part, you are given a dataset with data points that are not
%  linearly separable. However, you would still like to use logistic
%  regression to classify the data points.
%
%  To do so, you introduce more features to use -- in particular, you add
%  polynomial features to our data matrix (similar to polynomial
%  regression).
%

% Add Polynomial Features

% Note that mapFeature also adds a column of ones for us, so the intercept
% term is handled
X = mapFeature(X(:,1), X(:,2));

% Initialize fitting parameters
initial_theta = zeros(size(X, 2), 1);

% Set regularization parameter lambda to 1
lambda = 100;

% Compute and display initial cost and gradient for regularized logistic
% regression
[cost, grad] = costFunctionReg(initial_theta, X, y, lambda);

fprintf('Cost at initial theta (zeros): %f\n', cost);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============= Part 2: Regularization and Accuracies =============
%  Optional Exercise:
%  In this part, you will get to try different values of lambda and
%  see how regularization affects the decision coundart
%
%  Try the following values of lambda (0, 1, 10, 100).
%
%  How does the decision boundary change when you vary lambda? How does
%  the training set accuracy vary?
%

% Initialize fitting parameters
initial_theta = zeros(size(X, 2), 1);

% Set regularization parameter lambda to 1 (you should vary this)
lambda = 100;

% Set Options
options = optimset('GradObj', 'on', 'MaxIter', 400);

% Optimize
[theta, J, exit_flag] = ...
	fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options);

% Plot Boundary
plotDecisionBoundary(theta, X, y);
hold on;
title(sprintf('lambda = %g', lambda))

% Labels and Legend
xlabel('Microchip Test 1')
ylabel('Microchip Test 2')

legend('y = 1', 'y = 0', 'Decision boundary')
hold off;

% Compute accuracy on our training set
p = predict(theta, X);

fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);


function [X, K, cluster_sizes, true_labels] = prepare_data(noise)
    if nargin < 1
        noise = false;
    end
% Ambient space dimension
M = 4000;
% Number of subspaces
K = 4;
% common dimension for each subspace
D = 10;
% dimensions of each subspace
Ds = D * ones(1, K);
% Noise level
sigma = 0.8;
fprintf('Generating synthetic data.\n');
bases = spx.data.synthetic.subspaces.random_subspaces(M, K, Ds);
% Number of points on each subspace
Sk = 16 * D;
cluster_sizes = Sk * ones(1, K);
% total number of points
S = sum(cluster_sizes);
% Let us generate uniformly distributed points in each subspace
points_result = spx.data.synthetic.subspaces.uniform_points_on_subspaces(bases, cluster_sizes);
X0 = points_result.X;
start_indices = points_result.start_indices;
end_indices = points_result.end_indices;
if noise
    Noise = sigma * spx.data.synthetic.uniform(M, S);
    % Add noise to signal
    X = X0 + Noise;
else
    X = X0;
end
% Normalize noisy signals.
X = spx.norm.normalize_l2(X);
% true labels for each of the data samples
true_labels = spx.cluster.labels_from_cluster_sizes(cluster_sizes);
fprintf('Size of the data matrix: %d x %d\n', M, S);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % Simple Low Rank Tensor Completion (SiLRTC)
% Time: 03/11/2012
% Reference: "Tensor Completion for Estimating Missing Values
% in Visual Data", PAMI, 2012.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [X, errList] = SiLRTC(T, Omega, alpha, gamma, maxIter, epsilon, X)
%%%%%%%%%%%%%%%%%%%%%%%%%%
% min(X, M1, M2, M3,... Mn): (\gamma1||X_(1)-M1||^2 + \gamma2||X_(2)-T2||^2 + \gamma3||X_(3)-T3||^2 + ...)/2 +
%               \alpha1||M1||_* + \alpha2||M2||_* + \alpha3||M3||_* + ....
%         s.t.  X_\Omega = T_\Omega
%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin < 7
    X = T;
    X(logical(1-Omega)) = mean(T(Omega));
end

errList = zeros(maxIter, 1);
normT = norm(T(:));
%L = errList;
dim = size(T);
M = cell(ndims(T), 1);
gammasum = sum(gamma);
tau = alpha./ gamma;

%normT = norm(T(:));
for k = 1:maxIter
    if mod(k, 20) == 0
        fprintf('SiLRTC: iterations = %d   difference=%f\n', k, errList(k-1));
    end
    Xsum = 0;
    for i = 1:ndims(T)
        M{i} = Fold(Pro2TraceNorm(Unfold(X, dim, i), tau(i)), dim, i);
        Xsum = Xsum + gamma(i) * M{i};
    end
    Xlast = X;
    X = Xsum / gammasum;
    X(Omega) = T(Omega);
    errList(k) = norm(X(:)-Xlast(:)) / normT;
    if (errList(k) < epsilon)
        errList = errList(1:k);
        break;
    end
    %L(k) = norm(X(:)-T(:)) / normT;
end
fprintf('SiLRTC ends: total iterations = %d   difference=%f\n\n', k, errList(k));


function [ xstar, seed ] = rk2_ti_step ( x, t, h, q, fi, gi, seed )

%*****************************************************************************80
%
%% RK2_TI_STEP takes one step of a stochastic Runge Kutta scheme.
%
%  Discussion:
%
%    The Runge-Kutta scheme is second-order, and suitable for time-invariant
%    systems.
%
%    d/dx X(t,xsi) = F ( X(t,xsi) ) + G ( X(t,xsi) ) * w(t,xsi)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 June 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Jeremy Kasdin,
%    Runge-Kutta algorithm for the numerical integration of
%    stochastic differential equations,
%    Journal of Guidance, Control, and Dynamics,
%    Volume 18, Number 1, January-February 1995, pages 114-120.
%
%    Jeremy Kasdin,
%    Discrete Simulation of Colored Noise and Stochastic Processes
%    and 1/f^a Power Law Noise Generation,
%    Proceedings of the IEEE,
%    Volume 83, Number 5, 1995, pages 802-827.
%
%  Parameters:
%
%    Input, real X, the value at the current time.
%
%    Input, real T, the current time.
%
%    Input, real H, the time step.
%
%    Input, real Q, the spectral density of the input white noise.
%
%    Input, external real FI, the name of the deterministic
%    right hand side function.
%
%    Input, external real GI, the name of the stochastic
%    right hand side function.
%
%    Input/output, integer SEED, a seed for the random
%    number generator.
%
%    Output, real XSTAR, the value at time T+H.
%
  a21 = 1.0;
  a31 = 0.5;
  a32 = 0.5;

  q1 = 2.0;
  q2 = 2.0;

  t1 = t;
  x1 = x;
  [ n1, seed ] = r8_normal_01 ( seed );
  w1 = n1 * sqrt ( q1 * q / h );
  k1 = h * fi ( x1 ) + h * gi ( x1 ) * w1;

  t2 = t1 + a21 * h;
  x2 = x1 + a21 * k1;
  [ n2, seed ] = r8_normal_01 ( seed );
  w2 = n2 * sqrt ( q2 * q / h );
  k2 = h * fi ( x2 ) + h * gi ( x2 ) * w2;

  xstar = x1 + a31 * k1 + a32 * k2;

  return
end


%
% This code creates the plot of the D-value versus the b-value.
% The code is called from view_Dv.
%
%
[bvg5, ord] = sort(bvg(:,5));
bvg1 = bvg(ord,1);
bx = [bvg5(3):0.05: bvg5(end-1)]';
Dy = 2*bx;
clear ord;

figure_w_normalized_uicontrolunits('Numbertitle','off','Name','D versus b');
plot(bvg(:,5),bvg(:,1),'o');
hold on;
plot(bx, Dy, 'k-');
xlabel('b-value');
ylabel('D-value');
title('D-value versus b-value');

reg = [ones(size(bvg,1),1), bvg(:,5)];
[sl, cint, res, resint, stat] = regress(bvg(:,1), reg, 0.25);

sl
stat

rsl = [sl(2,1) sl(1,1)];
coef1 = [cint(2,1), cint(1,1)];
coef2 = [cint(2,2), cint(1,2)];
deltar = sl(2,1) - cint(2,1);
[line] = polyval(rsl,bx);
[line1] = polyval(coef1, bx);
[line2] = polyval(coef2, bx);

hold on;
plot(bx, line, 'r');
plot(bx, line1, 'g');
plot(bx, line2, 'g');

str2 = ['Correlation factor (D=xb): x =  ' sprintf('%.2f',sl(2,1)) '  +/- ' sprintf('%.2f', deltar)];
axes('pos',[0 0 1 1]); axis off; hold on;
te1 = text(0.15, 0.85, str2,'Fontweight','bold');


function x = blend_ij_w_1d1 ( x, r, s, m1, m2 )

%*****************************************************************************80
%
%% BLEND_IJ_W_1D1 extends weighted indexed scalar data along edges into a table.
%
%  Diagram:
%
%    Instead of assuming that the data in the table is equally spaced,
%    the arrays R and S are supplied, which should behave as
%    "coordinates" for the data.
%
%            S(1)  S(2)  S(3)  S(4)  S(5)  S(6)  S(M2)
%
%    R(1)  ( X11,  X12,  X13,  X14,  X15,  X16,  X1M2  )
%    R(2)  ( X21,  ...,  ...,  ...,  ...,  ...,  X2M2  )
%    R(3)  ( X31,  ...,  ...,  ...,  ...,  ...,  X3M2  )
%    R(4)  ( X41,  ...,  ...,  ...,  ...,  ...,  X4M2  )
%    R(M1) ( XM11, XM12, XM13, XM14, XM15, XM16, XM1M2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    William Gordon,
%    Blending-Function Methods of Bivariate and Multivariate Interpolation
%    and Approximation,
%    SIAM Journal on Numerical Analysis,
%    Volume 8, Number 1, March 1971, pages 158-177.
%
%    William Gordon and Charles Hall,
%    Transfinite Element Methods: Blending-Function Interpolation over
%    Arbitrary Curved Element Domains,
%    Numerische Mathematik,
%    Volume 21, Number 1, 1973, pages 109-129.
%
%    William Gordon and Charles Hall,
%    Construction of Curvilinear Coordinate Systems and Application to
%    Mesh Generation,
%    International Journal of Numerical Methods in Engineering,
%    Volume 7, 1973, pages 461-477.
%
%    Joe Thompson, Bharat Soni, Nigel Weatherill,
%    Handbook of Grid Generation,
%    CRC Press, 1999.
%
%  Parameters:
%
%    Input, real X(M1,M2).
%    On input, data is contained in the "edge entries" X(1,J), X(I,1),
%    X(M1,J) and X(I,M2), for I = 1 to M1, and J = 1 to M2.
%
%    Input, real R(M1), S(M2), are "coordinates" for the rows and
%    columns of the array.  The values in R, and the values in S, should
%    be strictly increasing or decreasing.
%
%    Input, integer M1, M2, the number of rows and columns in X.
%
%    Output, real X(M1,M2), all entries in X have been assigned a value.
%

%
%  Interpolate values in the interior.
%
  for i = 2 : m1 - 1

    rr = ( r(i) - r(1) ) / ( r(m1) - r(1) );

    for j = 2 : m2 - 1

      ss = ( s(j) - s(1) ) / ( s(m2) - s(1) );

      x(i,j) = blend_112 ( rr, ss, x(1,1), x(1,m2), x(m1,1), x(m1,m2), ...
        x(i,1), x(i,m2), x(1,j), x(m1,j) );

    end

  end

  return
end


function value = square_volume ( a, b )

%*****************************************************************************80
%
%% SQUARE_VOLUME: volume of a square in 2D.
%
%  Discussion:
%
%    The integration region is defined as:
%      A(1) <= X <= B(1)
%      A(2) <= Y <= B(2)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 September 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A(2), B(2), the lower and upper limits.
%
%    Output, real VALUE, the volume.
%
  value = ( b(1) - a(1) ) * ( b(2) - a(2) );

  return
end


function c = l1pp_cholesky ( n, h )

%*****************************************************************************80
%
%% L1PP_CHOLESKY computes the Cholesky factor of the 1D PP Laplacian.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 October 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of points.
%    N must be at least 3.
%
%    Input, real H, the spacing between points.
%
%    Output, real C(N,N), the Cholesky factor.
%
  if ( n < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'L1PP_CHOLESKY - Fatal error!\n' );
    fprintf ( 1, '  N < 3.\n' );
    error ( 'L1PP_CHOLESKY - Fatal error!' );
  end

  c = zeros ( n, n );

  for i = 1 : n - 1
    c(i,i) = sqrt ( i + 1.0 ) / sqrt ( i );
  end

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

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

  i = n - 1;
  c(i,n) = - n / ( i + 1.0 ) * sqrt ( i + 1.0 ) / sqrt ( i );

  c(1:n,1:n) = c(1:n,1:n) / h;

  return
end


%% To plot Basin of Attraction for a given set of equations using Newton
% Raphson Method
% Governing Equations are:
% x^3-y = 0 ; y^3 - x = 0
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Warning : On running this the workspace memory will be deleted. Save if
% any data present before running the code !!
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%--------------------------------------------------------------------------
% Code written by : Siva Srinivas Kolukula, PhD                           |
%                   Structural Mechanics Laboratory                       |
%                   Indira Gandhi Center for Atomic Research              |
%                   India                                                 |
% E-mail : allwayzitzme@gmail.com                                         |
% web-link: https://sites.google.com/site/kolukulasivasrinivas/           |
%--------------------------------------------------------------------------
% Version 1 : 19 September 2013

clc ; clear all
warning('off') % To off the warning which shows "Matrix is close to singular
               % badly scaled" when algorithm passes through a point where the Jacobian
               % matrix is singular

% The roots of the given governing equations
r1 = [-1 ;-1] ;
r2 = [0 ;0] ;
r3 = [1 ;1] ;
% Initial conditions
x = linspace(-2,2,200) ;
y = linspace(-2,2,200) ;
% Initialize the required matrices
Xr1 = [] ; Xr2 = [] ; Xr3 = [] ; Xr4 = [] ;
tic
for i = 1:length(x)
     for j = 1:length(y)
          X0 = [x(i);y(j)] ;
          % Solve the system of Equations using Newton's Method
          X = NewtonRaphson(X0) ;
          % Locating the initial conditions according to error
          if norm(X-r1)<1e-8
             Xr1 = [X0 Xr1]  ;
          elseif norm(X-r2)<1e-8
             Xr2 = [X0 Xr2] ;
          elseif norm(X-r3)<1e-8
             Xr3 = [X0 Xr3] ;
          else               % if not close to any of the roots
             Xr4 = [X0 Xr4] ;
          end

     end
end
toc
warning('on') % Remove the warning off constraint

% Initialize figure
figure
set(gcf,'color','w')
hold on
plot(Xr1(1,:),Xr1(2,:),'.','color','r') ;
plot(Xr2(1,:),Xr2(2,:),'.','color','b') ;
plot(Xr3(1,:),Xr3(2,:),'.','color','g') ;
plot(Xr4(1,:),Xr4(2,:),'.','color','k') ;
title('Basin of attraction for f(x,y) = x^3-y = 0 and y^3-x=0')


function atanh_test ( )

%*****************************************************************************80
%
%% ATANH_TEST tests R4_ATANH and R8_ATANH.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 September 2011
%
%  Author:
%
%    John Burkardt
%
  addpath ( '../test_values' );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'ATANH_TEST:\n' );
  fprintf ( 1, '  Test ARCTANH_VALUES, R4_ATANH, R8_ATANH\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '             X     ARCTANH(X)\n' );
  fprintf ( 1, '                  R4_ATANH(X)         Diff\n' );
  fprintf ( 1, '                  R8_ATANH(X)         Diff\n' );

  n_data = 0;

  while ( 1 )

    [ n_data, x, fx1 ] = arctanh_values ( n_data );

    if ( n_data == 0 )
      break
    end

    fx2 = r4_atanh ( single ( x ) );
    fx3 = r8_atanh ( x );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  %14f  %14g\n', x, fx1 );
    fprintf ( 1, '                  %14g  %14g\n', fx2, abs ( fx1 - fx2 ) );
    fprintf ( 1, '                  %14g  %14g\n', fx3, abs ( fx1 - fx3 ) );

  end

  rmpath ( '../test_values' );

  return
end


function value = r8_scinvchi_sample ( df, s )

%*****************************************************************************80
%
%% R8_SCINVCHI_SAMPLE: sample a scaled inverse chi-squared distribution.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real DF, the degrees of freedom.
%    0.0 < DF.
%
%    Input, real S, the scale factor.
%    0.0 < S.
%
%    Input, real VALUE, a sample value.
%
  a = 0.5 * df * s;
  b = 0.5 * df;

  value = r8_gamma_sample ( a, b );

  if ( value ~= 0.0 )
    value = 1.0 / value;
  end

  return
end


% Stability domain of Adams-Bashforth_Euler scheme

% Copyright 2001 P. Wesseling
% This program and its subprograms may be freely used, modified and distributed
% under the GNU General Public License: http://www.gnu.org/copyleft/gpl.html

% Theory is given in Section 5.8 of
% 	P. Wesseling: Principles of Computational Fluid Dynamics
% 	Springer, Heidelberg, 2000 ISBN 3-5453-0. XII, 642 pp.
% See http://ta.twi.tudelft.nl/nw/users/wesseling/cfdbook.html

% This program generates Fig. 5.5  in the book

figure(1), clf, hold on

		% Plot of stability domain
theta = 0:0.01:1; theta = theta*pi;
z = - 2*(1-cos(theta)).^2./(3-cos(theta)) + i*2*sin(theta)./(3-cos(theta));
plot(z)

		% Stability domain of second order Adams-Bashforth scheme
z = exp(2*i*theta) - exp(i*theta); z = z./(1.5*exp(i*theta) - 0.5); plot(z,'-.')

		% Plot of oval
b = 1; a = 1; z =  - a*(1-cos(theta)) + i*b*(sin(theta)).^0.5; plot(z,'--')

		% Plot of half ellipse
a = 2.0; b = sqrt(1/3); theta = -pi/2 +0.5*theta;
z = - a*cos(theta) - i*b*sin(theta); plot(z,'.')


%
% Smooth point-set registration method using neighboring constraints
% -------------------------------------------------------------------
%
% Authors: Gerard Sanromà, René Alquézar and Francesc Serratosa
%
% Contact: gsanorma@gmail.com
% Date: 15/02/2012
%
% Computes the Euclidean distance between two n-dimensional point-sets
%
% Input:
%   g1,g2: input point sets
%
% Output:
%   Dist: output distance matrix
%

function Dist = dist_matrix(g1,g2)

l1 = size(g1,1);
l2 = size(g2,1);

Dist = zeros(l1,l2);
for it_dim = 1:size(g1,2)
    Dist = Dist + ...
        ((g1(:,it_dim)*ones(1,l2) - ones(l1,1)*g2(:,it_dim)').^2);
end
Dist = sqrt(Dist);


function pass = test_jumps_manual(pref)

if ( nargin == 0 )
    pref = cheboppref();
end

% BVP with nonhomogeneous jump condition
% Toby Driscoll, June 2014
% Based on issue #665

tol = 1e1*pref.bvpTol;

%%
N = chebop(@(s, V) diff(V, 2), [-1, 1]);
N.lbc = @(V) V + 1;
N.rbc = @(V) V - 1;
N.bc = @(s,V) [jump(V, 0) - 1 ; jump(diff(V),0)];
y = N\0;

%%
err(1) = norm(N(y), inf);
jump1  = feval(y, 0, 'right') - feval(y, 0, 'left');
err(2) = abs(jump1 - 1);
jump2  = feval(diff(y), 0, 'right') - feval(diff(y), 0, 'left');
err(3) = abs(jump2);
err(4) = abs(y(-1) + 1);
err(5) = abs(y(1) - 1);

%%
pass = err < tol;

end


function [Y, R, E] = IsomapII(D, n_fcn, n_size, options)
% ISOMAPII   Computes Isomap embedding using an advanced version of
%             the algorithm in Tenenbaum, de Silva, and Langford (2000),
%             which can take advantage of sparsity in the graph and
%             redundancy in the distances.
%
% [Y, R, E] = isomapII(D, n_fcn, n_size, options);
%
% Input:
%    D = input-space distances between pairs of N points, which can
%     take 1 of 3 forms:
%      (1) a full N x N matrix (as in isomap.m)
%      (2) a sparse N x N matrix (missing entries are treated as INF)
%      (3) the name of a function (e.g. 'd_fun') that takes
%            one argument, i, and returns a row vector containng the
%            distances from all N points to point i.
%
%    n_fcn = neighborhood function ('epsilon' or 'k')
%    n_size = neighborhood size (value for epsilon or k)
%
%    options = optional structure of options:
%      options.dims = (row) vector of embedding dimensionalities to use
%                        (1:10 = default)
%      options.comp = which connected component to embed, if more than one.
%                        (1 = largest (default), 2 = second largest, ...)
%      options.display = plot residual variance and 2-D embedding?
%                        (1 = yes (default), 0 = no)
%      options.overlay = overlay graph on 2-D embedding?
%                        (1 = yes (default), 0 = no)
%      options.verbose = display progress reports?
%                        (1 = yes (default), 0 = no)
%      options.dijkstra = use dijkstra's algorithm for shortest paths with
%                         full N x N distance matrix.
%                         (1 = yes (default), 0 = use Floyd; Floyd should
%                          be used only if you are unable to MEX dijkstra.cpp)
%      options.Kmax = maximum number of neighbors (used for sparse versions
%                        of epsilon; by default, estimated by random sample)
%      options.landmarks = (row) vector of landmark points to use in MDS.
%                 (MDS finds the configuration that best approximates
%                  the distances from all points to the landmark points.
%                  The default landmark points are 1:N (i.e. all the points),
%                  which is equivalent to classical MDS.  Good
%                  results may often be obtained using a number of
%                  landmarks that is much smaller than N, but much
%                  larger than the data's intrinsic dimensionality.
%                  Note that this extension is experimental!  For
%                  discussion, see Steyvers, de Silva, and Tenenbaum
%                  (in preparation).)
%
% Output:
%    Y = Y.coords is a cell array, with coordinates for d-dimensional embeddings
%         in Y.coords{d}.  Y.index contains the indices of the points embedded.
%    R = residual variances for embeddings in Y
%    E = edge matrix for neighborhood graph
%

%    BEGIN COPYRIGHT NOTICE
%
%    Isomap II code -- (c) 1998-2000 Josh Tenenbaum
%
%    This code is provided as is, with no guarantees except that
%    bugs are almost surely present.  Published reports of research
%    using this code (or a modified version) should cite the
%    article that describes the algorithm:
%
%      J. B. Tenenbaum, V. de Silva, J. C. Langford (2000).  A global
%      geometric framework for nonlinear dimensionality reduction.
%      Science 290 (5500): 2319-2323, 22 December 2000.
%
%    Comments and bug reports are welcome.  Email to jbt@psych.stanford.edu.
%    I would also appreciate hearing about how you used this code,
%    improvements that you have made to it, or translations into other
%    languages.
%
%    You are free to modify, extend or distribute this code, as long
%    as this copyright notice is included whole and unchanged.
%
%    END COPYRIGHT NOTICE
%
% Modified by Ramon Casero <rcasero@gmail.com>, University of Oxford.
%
% Version: 0.1.1
%
% This file is distributed as a derivative work of a third-party function
% with project Gerardus.
%
% http://code.google.com/p/gerardus/
%
% Original code downloaded from the Isomap Homepage
%
% http://isomap.stanford.edu/

%%%%% Step 0: Initialization and Parameters %%%%%

if nargin < 3
     error('Too few input arguments');
elseif nargin < 4
     options = struct('dims',1:10,'overlay',1,'comp',1,'display',1,'dijkstra',1,'verbose',1);
end

if isa(D, 'function_handle')
     mode = 3;
     d_func = D;
     N = length(d_func(1));
elseif issparse(D)
     mode = 2;
     N = size(D,1);
     if ~(N==size(D,2))
          error('D must be a square matrix');
     end;
else
     mode = 1;
     N = size(D,1);
     if ~(N==size(D,2))
         error('D must be a square matrix');
     end;
end

if strcmp(n_fcn, 'k')
     K = n_size;
     if ~(K==round(K))
         error('Number of neighbors for k method must be an integer');
     end
     if ((mode==2) && ~(min(sum(D'>0))>=K))
         error('Sparse D matrix must contain at least K nonzero entries in each row');
     end
elseif strcmp(n_fcn, 'epsilon')
     epsilon = n_size;
     if isfield(options,'Kmax')
         K = options.Kmax;
     elseif (mode==3)    %% estimate maximum equivalent K %%
         tmp = zeros(10,N);
         for i=1:10
             tmp(i,:) = d_func(ceil(N*rand));
         end
         K = 2*max(sum(tmp'<epsilon));    % just to be safe
     end
else
     error('Neighborhood function must be either epsilon or k');
end

if (mode == 3)
     INF = inf;
else
     INF =  1000*max(max(D))*N;  %% effectively infinite distance
end

if ~isfield(options,'dims')
     options.dims = 1:10;
end
if ~isfield(options,'overlay')
     options.overlay = 1;
end
if ~isfield(options,'comp')
     options.comp = 1;
end
if ~isfield(options,'display')
     options.display = 1;
end
if ~isfield(options,'verbose')
     options.verbose = 1;
end
if ~isfield(options,'landmarks')
     options.landmarks = 1:N;
end
if ~isfield(options,'dijkstra')
     options.dijkstra = 1;
end
dims = options.dims;
comp = options.comp;
overlay = options.overlay;
displ = options.display;
verbose = options.verbose;
landmarks = options.landmarks;
use_dijk = options.dijkstra;

Y.coords = cell(length(dims),1);
R = zeros(1,length(dims));

%%%%% Step 1: Construct neighborhood graph %%%%%
disp('Constructing neighborhood graph...');

if ((mode == 1) && (use_dijk == 0))
     if strcmp(n_fcn, 'k')
         [tmp, ind] = sort(D);
         tic;
         for i=1:N
             D(i,ind((2+K):end,i)) = INF;
             if ((verbose == 1) && (rem(i,50) == 0))
                 disp([' Iteration: ' num2str(i) '     Estimated time to completion: ' num2str((N-i)*toc/60/50) ' minutes']); tic;
             end
         end
     elseif strcmp(n_fcn, 'epsilon')
         warning off    %% Next line causes an unnecessary warning, so turn it off
         D =  D./(D<=epsilon);
         D = min(D,INF);
         warning on
     end
     D = min(D,D');    %% Make sure distance matrix is symmetric
elseif ((mode == 1) && (use_dijk == 1))
     if n_fcn == 'k'
         [tmp, ind] = sort(D);
         tic;
         for i=1:N
             D(i,ind((2+K):end,i)) = 0;
             if ((verbose == 1) && (rem(i,50) == 0))
                 disp([' Iteration: ' num2str(i) '     Estimated time to completion: ' num2str((N-i)*toc/60/50) ' minutes']); tic;
             end
         end
     elseif strcmp(n_fcn, 'epsilon')
         D =  D.*(D<=epsilon);
     end
     D = sparse(D);
     D = max(D,D');    %% Make sure distance matrix is symmetric
elseif (mode == 2)
     if n_fcn == 'k'
         Di = zeros(N*K,1);      Dj = zeros(N*K,1);       Ds = zeros(N*K,1);
         counter = 0;
         [a,b,c] = find(D);
         tic;
         for i=1:N
             l = find(a==i);
             [g,f] = sort(c(l));
             Di(counter+(1:K)) = i;
             Dj(counter+(1:K)) = b(l(f(1:K)));
             Ds(counter+(1:K)) = g(1:K);
             counter = counter+K;
             if ((verbose == 1) && (rem(i,50) == 0))
                  disp([' Iteration: ' num2str(i) '     Estimated time to completion: ' num2str((N-i)*toc/60/50) ' minutes']); tic;
             end
         end
         D = sparse(Di(1:counter), Dj(1:counter), Ds(1:counter));
         clear Di Dj Ds counter;
     elseif strcmp(n_fcn, 'epsilon')
         D =  D.*(D<=epsilon);
     end
     D = max(D,D');    %% Make sure distance matrix is symmetric
elseif (mode == 3)
     Di = zeros(N*(K+1),1);      Dj = zeros(N*(K+1),1);       Ds = zeros(N*(K+1),1);
     counter = 0;
     tic;
     for i=1:N
         d = d_func(i);
         if n_fcn == 'k'
             [c,b] = sort(d);
             Di(counter+(1:(K+1))) = i;
             Dj(counter+(1:(K+1))) = b(1:(K+1));
             Ds(counter+(1:(K+1))) = c(1:(K+1));
             counter = counter+(K+1);
         elseif strcmp(n_fcn, 'epsilon')
             [a,b,c] = find(d.*(d<=epsilon));
             l = length(a);
             Di(counter+(1:l)) = i;
             Dj(counter+(1:l)) = b;
             Ds(counter+(1:l)) = c;
             counter = counter+l;
         end
         if ((verbose == 1) && (rem(i,50) == 0))
              disp([' Iteration: ' num2str(i) '     Estimated time to completion: ' num2str((N-i)*toc/60/50) ' minutes']); tic;
         end
     end
     D = sparse(Di(1:counter), Dj(1:counter), Ds(1:counter));
     clear Di Dj Ds counter;
     D = max(D,D');    %% Make sure distance matrix is symmetric
end

if (overlay == 1)
     if ((mode == 1) && (use_dijk == 0))
         E = int8(1-(D==INF));  %%  Edge information for subsequent graph overlay
     else
         [a,b,c] = find(D);
         E = sparse(a,b,ones(size(a)));
     end
end

%%%%% Step 2: Compute shortest paths %%%%%
disp('Computing shortest paths...');

if ((mode==1) && (use_dijk == 0))
     tic;
     for k=1:N
         D = min(D,repmat(D(:,k),[1 N])+repmat(D(k,:),[N 1]));
         if ((verbose == 1) && (rem(k,20) == 0))
              disp([' Iteration: ' num2str(k) '     Estimated time to completion: ' num2str((N-i)*toc/i/60) ' minutes']);
         end
     end
else
     D = dijkstra(D, landmarks);
end

%%%%% Step 3: Construct low-dimensional embeddings (Classical MDS) %%%%%
disp('Constructing low-dimensional embeddings (Classical MDS)...');

%%%%% Remove outliers from graph %%%%%
disp('  Checking for outliers...');

if ((mode == 1) && (use_dijk == 0))
     [tmp, firsts] = min(D==INF);     % first point each point connects to
else
     [tmp, firsts] = min(D==inf);     % first point each point connects to
end
[comps, I, J] = unique(firsts);    % first point in each connected component
n_comps = length(comps);           % number of connected components
size_comps = sum((repmat(firsts,n_comps,1)==((1:n_comps)'*ones(1,N)))');
                                   % size of each connected component
[tmp, comp_order] = sort(size_comps);  %% sort connected components by size
comps = comps(comp_order(end:-1:1));
size_comps = size_comps(comp_order(end:-1:1));
if (comp>n_comps)
     comp=1;                              %% default: use largest component
end
Y.index = find(firsts==comps(comp)); %% list of points in relevant component
Y.index = setdiff(Y.index,find(isinf(min(D)))); % prune points that don't connect
                                                % to any landmarks
N = length(Y.index);
[tmp, landmarks, land_ind] = intersect(landmarks,Y.index);
                                       % list of landmarks in component
nl = length(landmarks);
D = full(D(landmarks,Y.index))';
disp(['    Number of connected components in graph: ' num2str(n_comps)]);
disp(['    Embedding component ' num2str(comp) ' with ' num2str(length(Y.index)) ' points.']);

dims = unique(min(dims,nl-1));    % don't embed in more dimensions than landmarks-1
if (nl==N)
     opt.disp = 0;
     [vec, val] = eigs(-.5*(D.^2 - sum(D.^2)'*ones(1,N)/N - ones(N,1)*sum(D.^2)/N + sum(sum(D.^2))/(N^2)), max(dims), 'LR', opt);
else
     subB = -.5*(D.^2 - sum(D'.^2)'*ones(1,nl)/nl - ones(N,1)*sum(D.^2)/N+sum(sum(D.^2))/(N*nl));
     opt.disp = 0;
     [alpha,beta] = eigs(subB'*subB, max(dims), 'LR', opt);
     val = beta.^(1/2);
     vec = subB*alpha*inv(val);
     clear subB alpha beta;
end
h = real(diag(val));
[foo,sorth] = sort(h);  sorth = sorth(end:-1:1);
val = real(diag(val(sorth,sorth)));
vec = vec(:,sorth);

D = reshape(D,N*nl,1);
for di = 1:length(dims)
     Y.coords{di} = real(vec(:,1:dims(di)).*(ones(N,1)*sqrt(val(1:dims(di)))'))';
     r2 = 1-corrcoef(reshape(real(L2_distance(Y.coords{di}, Y.coords{di}(:,land_ind))),N*nl,1),D).^2;
     R(di) = r2(2,1);
     if (verbose == 1)
         disp(['  Isomap on ' num2str(N) ' points with dimensionality ' num2str(dims(di)) '  --> residual variance = ' num2str(R(di))]);
     end
end

clear D;

%%%%%%%%%%%%%%%%%% Graphics %%%%%%%%%%%%%%%%%%

if (displ==1)
     %%%%% Plot fall-off of residual variance with dimensionality %%%%%
     figure;
     hold on
     plot(dims, R, 'bo');
     plot(dims, R, 'b-');
     hold off
     ylabel('Residual variance');
     xlabel('Isomap dimensionality');

     %%%%% Plot two-dimensional configuration %%%%%
     twod = find(dims==2);
     if ~isempty(twod)
         figure;
         hold on;
         plot(Y.coords{twod}(1,:), Y.coords{twod}(2,:), 'ro');
         if (overlay == 1)
             gplot(E(Y.index, Y.index), [Y.coords{twod}(1,:); Y.coords{twod}(2,:)]');
             title('Two-dimensional Isomap embedding (with neighborhood graph).');
         else
             title('Two-dimensional Isomap.');
         end
         hold off;
     end
end

return;


%otyp==0->cont, otyp==1->disc
function [A N]=sys_ned_dcm(llh, vel_n, Cbn, acc, otyp, dt)
% position   (1-3)
% velocity   (4-6)
% attitude   (7-9)

%system disturbance coefs
N=zeros(9,6);
N(7:9,4:6)=-Cbn; %attitude
N(4:6,1:3)=Cbn; %velocity

%system matrix
A=zeros(9);
[Rn, Re, g, sL, cL, WIE_E]=geoparam_v000(llh);
tL=sL/cL;
Rn_h=Rn+llh(3);
Re_h=Re+llh(3);
acc_n=Cbn*acc;

A(1,3)=-vel_n(1)/(Rn_h)^2;
A(1,4)=1/(Rn_h);

A(2,1)=vel_n(2)*tL/(Re_h)/cL;
A(2,3)=-vel_n(2)/(Re_h)/(Re_h)/cL;
A(2,5)=1/(Re_h)/cL;

A(3,6)=-1;

A(4,1)=-(2*WIE_E*cL*vel_n(2)+vel_n(2)*vel_n(2)/(Re_h)/cL/cL);
A(4,3)=(-vel_n(1)*vel_n(3)/(Rn_h)/(Rn_h)+vel_n(2)*vel_n(2)*tL/(Re_h)/(Re_h));
A(4,4)=vel_n(3)/(Rn_h);
A(4,5)=-(2*WIE_E*sL+2*vel_n(2)*tL/(Re_h));
A(4,6)=vel_n(1)/(Rn_h);
A(4,8)=-acc_n(3);
A(4,9)=acc_n(2);

A(5,1)=(2*WIE_E*cL*vel_n(1)-2*WIE_E*sL*vel_n(3)+vel_n(2)*vel_n(1)/(Re_h)/cL/cL);
A(5,3)=-(vel_n(2)*vel_n(3)+vel_n(2)*vel_n(1)*tL)/(Re_h)/(Re_h);
A(5,4)=(2*WIE_E*sL+vel_n(2)*tL/(Re_h));
A(5,5)=(vel_n(3)+vel_n(1)*tL)/(Re_h);
A(5,6)=(2*WIE_E*cL+vel_n(2)/(Re_h));
A(5,7)=acc_n(3);
A(5,9)=-acc_n(1);

A(6,1)=2*WIE_E*sL*vel_n(2);
A(6,3)=(vel_n(1)*vel_n(1)/(Rn_h)/(Rn_h)+vel_n(2)*vel_n(2)/(Re_h)/(Re_h));
A(6,4)=-2*vel_n(1)/(Rn_h);
A(6,5)=-2*(WIE_E*cL+vel_n(2)/(Re_h));
A(6,7)=-acc_n(2);
A(6,8)=acc_n(1);

A(7,1)=-WIE_E*sL;
A(7,3)=-vel_n(2)/(Re_h)/(Re_h);
A(7,5)=1/(Re_h);
A(7,8)=-(WIE_E*sL+vel_n(2)*tL/(Re_h));
A(7,9)=vel_n(1)/(Rn_h);

A(8,3)=vel_n(1)/(Rn_h)/(Rn_h);
A(8,4)=-1/(Rn_h);
A(8,7)=(WIE_E*sL+vel_n(2)*tL/(Re_h));
A(8,9)=(WIE_E*cL+vel_n(2)/(Re_h));

A(9,1)=-(WIE_E*cL+vel_n(2)/(Re_h)/cL/cL);
A(9,3)=vel_n(2)*tL/(Re_h)/(Re_h);
A(9,5)=-tL/(Re_h);
A(9,7)=-vel_n(1)/(Rn_h);
A(9,8)=-(WIE_E*cL+vel_n(2)/(Re_h));

%discretize A;
if (otyp==0)
    A=A;
elseif(otyp==1)
    A=expm(A*dt);
end