% DeInterleaver function
function [data_out]=deinterleav_d(data_in,rate_id)

switch (rate_id)
    case 0
       Ncbps=192;  % In BPSK no.of bits allocated to subcarrier in a OFDM symbol
       Ncpc=1;     % In cash of BPSK No. of coded bit per carrier.
    case {1,2}
      Ncbps=384;
      Ncpc=2;
    case {3,4}     %% note: no. of coded bit Ncpc=1,2,4,6 for bpsk,qpsk,16qam,64qam respectivly%%
       Ncbps=768;
       Ncpc=4;
    case {5,6}
       Ncbps=1152;
       Ncpc=6;
    otherwise
       display('error in interleaver give proper rate_id')
end

s=ceil(Ncpc/2);

data=data_in';
%%% Deinterleaving
  % j-->index of the bit encoded BEFORE the first permutation
  % mj-->index of this bit BEFORE the second permutation and AFTER the first one
  % kj-->index after the SECOND permutation, just before the mapping of the sign.

  j = 0:Ncbps-1;
  mj = s*floor(j/s) + mod((j + floor(12*j/Ncbps)),s);          % First permutation
  kj = 12*mj-(Ncbps-1)*floor(12*mj/Ncbps);                     % Second permutation

  % The indices are ordered to know what must be taken.
  [c d]= sort(kj);

% finally the bits are rearranged.

 i = 1:Ncbps;
 data_out = zeros(1,Ncbps);
 data_out(i) = data(d(i));
 data_out=data_out';


function coeff = reg_als(basis_cr, y, r, n)
%REG_ALS Summary of this function goes here
%   d - dimension of the regression function
%   N - number of regression points
%   y - 1 x N array of values of the function to approximate
%   n - d x 1 array, stores number of basis functions in each dimension
%   r - d+1 x 1 array, stores TT-ranks of the tensor of coefficients of the
%       regression function
%   basis_cr - array that stores values of basis functions at regression
%   points
%   fixed - d x 1 cell of aggregated fixed dimensions of the regression
%   function at k-th step of the ALS algorithm
%   coeff - TT-tensor of coefficient of the regression function

N = size(y, 2);
d = numel(n);
coeff = tt_rand(n, d, r);
coeff_ps = coeff.ps;
coeff_cr = coeff.core;
basis_ps = cumsum([1 ; n*N]);

% assemble fixed part of the TT-function
fixed_ps = cumsum([1 ; N ; r(2:d)*N ; N]);
fixed_cr = zeros(fixed_ps(d+2) - fixed_ps(1), 1);
fixed_cr(fixed_ps(d+1): fixed_ps(d+2)-1) = ones(N, r(d+1));
for dim = d: -1: 2
    c = reshape(coeff_cr(coeff_ps(dim): coeff_ps(dim+1)-1), [r(dim) n(dim) r(dim+1)]);
    c = permute(c, [1 3 2]);
    b = reshape(basis_cr(basis_ps(dim): basis_ps(dim+1)-1), [n(dim) N]);
    t1 = ten_conv(c, 3, b); % r(dim) x r(dim+1) x N
    t2 = reshape(fixed_cr(fixed_ps(dim+1): fixed_ps(dim+2)-1), [r(dim+1), N]);
    t1 = reshape(t1, [r(dim), r(dim+1)*N]);
    t2 = kron(ones(r(dim),1), reshape(t2, [1, r(dim+1)*N]));
    t3 = t1.*t2;
    t3 = reshape(t3, [r(dim) r(dim+1) N]);
	t3 = sum(t3, 2);
    fixed_cr(fixed_ps(dim): fixed_ps(dim+1)-1) = reshape(t3, [r(dim)*N, 1]);
end
fixed_cr(fixed_ps(1): fixed_ps(2)-1) = ones(N, r(1));

% initial sum of squares
VAR = var(y);

n_swp = 0;
R2 = 0;
swp_tp = 'f';
dim = 1;
while R2 < 0.9999 && n_swp < 10
    n1 = r(dim);
    n2 = n(dim);
    n3 = r(dim+1);

    u1 = reshape(fixed_cr(fixed_ps(dim): fixed_ps(dim+1)-1), [N n1]);
    u2 = reshape(basis_cr(basis_ps(dim): basis_ps(dim+1)-1), [n2 N]);
    u3 = reshape(fixed_cr(fixed_ps(dim+1): fixed_ps(dim+2)-1), [n3 N]);

    t1 = kron(kron(ones(n3,1), ones(n2,1)), u1');
    t2 = kron(kron(ones(n3,1), u2), ones(n1,1));
    t3 = kron(kron(u3, ones(n2,1)), ones(n1,1));
    t = t1.*t2.*t3;

    A = t*t';
    b = t*y';
    c = A\b;
    coeff_cr(coeff_ps(dim):coeff_ps(dim+1)-1) = c;

    if (swp_tp == 'f' && dim < d) || (swp_tp == 'b' && dim == 1)
        c = permute(reshape(c, [n1 n2 n3]), [1 3 2]);
        t1 = ten_conv(c, 3, u2);
        t1 = reshape(t1, [n1*n3, N]);
        u1 = kron(ones(1,n3), u1);
        t2 = u1.*t1';
        t2 = reshape(t2, [N n1 n3]);
        t2 = sum(t2, 2);
        t2 = reshape(t2, [N, n3]);
        fixed_cr(fixed_ps(dim+1): fixed_ps(dim+2)-1) = reshape(t2, [N*n3, 1]);

        %R^2
        if swp_tp == 'b'
            MSE = sum((sum(t2'.*u3,1) - y).^2)/N;
            R2 = 1 - MSE/VAR;
        end
    elseif (swp_tp == 'b' && dim > 1) || (swp_tp == 'f' && dim == d)
        c = permute(reshape(c, [n1 n2 n3]), [1 3 2]);
        t1 = ten_conv(c, 3, u2);
        t1 = reshape(t1, [n1, n3*N]);
        u3 = kron(ones(n1,1), reshape(u3, [1, n3*N]));
        t2 = t1.*u3;
        t2 = reshape(t2, [n1 n3 N]);
        t2 = sum(t2, 2);
        t2 = reshape(t2, [n1 N]);
        fixed_cr(fixed_ps(dim): fixed_ps(dim+1)-1) = reshape(t2, [n1*N, 1]);

        %R^2
        if swp_tp == 'f'
            MSE = sum((sum(u1'.*t2,1) - y).^2)/N;
            R2 = 1 - MSE/VAR;
        end
    end

    if swp_tp == 'f'
        if dim < d
            dim = dim + 1;
        elseif dim == d
            swp_tp = 'b';
            dim = dim - 1;
            n_swp = n_swp + 1;
            fprintf('=tt_reg_als= Sweep %d, R^2: %.2f%%, MSE: %1.2e\n', n_swp, 100*R2, MSE);
        end
    elseif swp_tp == 'b'
        if dim > 1
            dim = dim - 1;
        elseif dim == 1
            swp_tp = 'f';
            dim = dim + 1;
            n_swp = n_swp + 1;
            fprintf('=tt_reg_als= Sweep %d, R^2: %.2f%%, MSE: %1.2e\n', n_swp, 100*R2, MSE);
        end
    end
end

coeff.core = coeff_cr;

end


%% Total Variation Denoising
% Test for Rudin-Osher-Fatemi denoising (ROF) using FB-like method.

addpath('../');
addpath('../toolbox/');

%%
% Load image.

n = 256;
y = load_image('lena',n*2);
y = rescale(crop(y,n));
y = y + randn(n)*.06;

%%
% Display it.

clf;
imageplot(clamp(y));

%%
% We aim at minimising:

%%
% |min_x 1/2*norm(y-x,'fro')^2 + lambda*norm(K(x),1)|

%%
% Regularization parameter.

lambda = .2;

%%
% where |K| is a vectorial gradient and |norm(u,1)| is a vectorial L1
% norme.

K = @(x)grad(x);
KS = @(x)-div(x);

%%
% It can be put as the minimization of |F(K*x) + G(x)|

Amplitude = @(u)sqrt(sum(u.^2,3));
F = @(u)lambda*sum(sum(Amplitude(u)));
G = @(x)1/2*norm(y-x,'fro')^2;

%%
% The proximity operator of |F| is the vectorial soft thresholding.

Normalize = @(u)u./repmat( max(Amplitude(u),1e-10), [1 1 2] );
ProxF = @(u,tau)repmat( perform_soft_thresholding(Amplitude(u),lambda*tau), [1 1 2]).*Normalize(u);
ProxFS = compute_dual_prox(ProxF);

%%
% The proximity operator of G.

ProxG = @(x,tau)(x+tau*y)/(1+tau);

%%
% Function to record progression of the functional.

options.report = @(x)G(x) + F(K(x));

%%
% Run the ADMM algorihtm.

options.niter = 300;
[xAdmm,EAdmm] = perform_admm(y, K,  KS, ProxFS, ProxG, options);

%%
% Display image.

clf;
imageplot(xAdmm);

%%
% Since the functional to mimize is stricly convex, we can use a FB scheme
% on the dual problem.

GradGS = @(x)x+y;
L = 8;
options.method = 'fista';
[xFista,EFista] = perform_fb_strongly(y, K, KS, GradGS, ProxFS, L, options);

%%
% Compare the energy decays.

clf;
plot([EAdmm(:) EFista(:)]);
axis tight;
legend('ADMM', 'FISTA');
axis([1 length(EAdmm) EFista(end)*.9 2000]);


%% Classic Monte Carlo simualtion
% Vincent Leclercq, The MathWorks, 2007, vincent.leclercq@mathworks.fr
%

clear all;
close all;

NbTrials = 10000;

%RunMode = 'LogNomrality';

RunMode = 'OptionPricing';
%% Load Data (retrieved originally from Thomson Datastream)

load Equities.mat
PastDate = today()-1 * 365;

%% Retrieve the dates in a numeric format

Dates   = cellfun(@(x)(datenum(x,'yyyy-mm-ddTHH:MM:SS')),Equities.DATE);
AssetPrices = cellfun(@(x) (str2double(x)),Equities.P );

%% Plot the Series

plot(Dates,AssetPrices);set(gcf,'WindowStyle','Docked');
legend(Equities.DISPNAME);
datetick('x','mmmyy');
xlim([PastDate, today()]);
grid on;

%% Compute the returns
% We can compute the returns for one or many stocks at the same time using
% matrix computation and matlab easy syntax

Suez_Returns = tick2ret(AssetPrices);
DailyVol = std(Suez_Returns);
AnnualVol = DailyVol * sqrt(252);

SpotPrice = AssetPrices(end);

InterestRate = 0.0375;

%% Portfolio simulation (Monte Carlo) using the Financial toolbox function
% For help, one can use the doc portsim function
% We call the portfolio simulation using Financial toolbox to
% simulate 10000 scenarios. Of course, correlation are preserved
% We assume an horizon of 6 * 22 trading days, ie 6 month maturity

%% Using Annual statistics

SimulatedRetsAnnual = portsim(InterestRate,AnnualVol^2, 12, 1/12, NbTrials,'Expected'); % NbStep * TimeStep = 1 (in years !!!)

%% Using Daily statistics
NumberOfSimulationSteps = 12;
SimulatedRetsDaily = portsim(InterestRate./252, DailyVol^2, 12, 252./12, NbTrials,'Expected');% NbStep * TimeStep = 252 (in days!!!)

%% Generate the Prices and plot them

SimulatedPricesAnnual = ret2tick(squeeze(SimulatedRetsAnnual) ,SpotPrice);
SimulatedPricesDaily  = ret2tick(squeeze(SimulatedRetsDaily)  ,SpotPrice );

figure;hist(SimulatedPricesAnnual(end,:),40);title('Prices, annual timestep used');set(gcf,'WindowStyle','Docked');
figure;hist(SimulatedPricesDaily(end,:),40);title('Prices, daily timestep used');set(gcf,'WindowStyle','Docked');

%% Check For LogNormality of the Price series

ExpectedVariance = (SpotPrice^2)  * (exp(AnnualVol^2) - 1)* exp(2*InterestRate);

disp(['Mean Price (Annual Parameters) -> ', num2str(mean(SimulatedPricesAnnual(end,:))) ' , Theoric value (Hull) :' num2str(SpotPrice * exp(InterestRate))]);
disp(['Mean Price (Daily Parameters) -> ', num2str(mean(SimulatedPricesDaily(end,:))) ' , Theoric value (Hull) :' num2str(SpotPrice * exp(InterestRate))]);

disp(['Expected Variance (Annual Parameters) -> ', num2str(var(SimulatedPricesAnnual(end,:))) ' , Theoric value (Hull) :' num2str(ExpectedVariance)]);
disp(['Expected Variance (Daily Parameters) -> ', num2str(var(SimulatedPricesDaily(end,:))) ' , Theoric value (Hull) :' num2str(ExpectedVariance)]);

%% Parameter sweep
% Now that we have done this, we can ccompute the same thing for different
% Exercise prices
if strcmp(RunMode,'OptionPricing')
    k = 1;
    NumberOfSteps = 400;
    ExercisePrices= linspace(0.8 * SpotPrice,1.2 * SpotPrice,NumberOfSteps);

    VanillaPriceAnnual    = zeros(NumberOfSteps,1);
    VanillaPriceDaily    = zeros(NumberOfSteps,1);

    ProbabilityITMAnnual  = zeros(NumberOfSteps,1);
    ProbabilityITMDaily  = zeros(NumberOfSteps,1);
    CIAnnual    =     zeros(NumberOfSteps,2);
    CIDaily     =     zeros(NumberOfSteps,2);
    BLSPrices       = zeros(NumberOfSteps,1);

    %%
    TimeInYear = 1;
    for i = 1 : NumberOfSteps
        [BLSPrices(i),dummy]   = blsprice(SpotPrice, ExercisePrices(i), InterestRate, TimeInYear, AnnualVol, 0);
        [VanillaPriceAnnual(i), ProbabilityITMAnnual(i) ,CIAnnual(i,:)] = GetOptionPrice(SimulatedPricesAnnual,ExercisePrices(i),TimeInYear,InterestRate,'Vanilla');
        [VanillaPriceDaily(i), ProbabilityITMDaily(i) ,  CIDaily(i,:)] = GetOptionPrice(SimulatedPricesDaily,ExercisePrices(i),TimeInYear,InterestRate,'Vanilla');

    end;

%%

    h =    figure;
    [AX,H1,H2] = plotyy(ExercisePrices,[VanillaPriceAnnual BLSPrices CIAnnual] , ExercisePrices,ProbabilityITMAnnual);

    xlabel('Exercise Price');
    title('Option prices for a Vanilla option using a 1 year - Annual volatility');
    Axes_YLabels = get(AX,'Ylabel');
    set(Axes_YLabels{1},'String','Option Price') ;

    set(H1(1),'LineStyle','-');
    set(H1(1),'Color','r');
    set(H1(1),'LineWidth',2);

    set(H1(2),'LineStyle','-');
    set(H1(2),'Color','b');
    set(H1(2),'LineWidth',2);

    set(H1(3),'LineStyle','--');
    set(H1(3),'Color','r');
    set(H1(3),'LineWidth',1);

    set(H1(4),'LineStyle',':');
    set(H1(4),'Color','r');
    set(H1(4),'LineWidth',1);

    set(H2,'LineStyle','-');
    set(H2,'Color','g');
    set(H2,'LineWidth',2);

    set(get(AX(2),'Ylabel'),'String','Probability of being In the Money');
    legend(H1,{['Option Price (Monte Carlo)'], ['Option Price (Black Scholes)'], ['99% Confidence interval (Lower)'],['99% Confidence interval (Upper)']},'Location','NorthEast');
    legend(H1(2),{'Option Price (Black Shcoles)'},'Location','NorthEast');
    legend(H2,{'Probability'},'Location','SouthWest');
    grid on;
set(h,'WindowStyle','Docked');

%%
h=     figure;
    [AX,H1,H2] = plotyy(ExercisePrices,[VanillaPriceDaily BLSPrices CIDaily] , ExercisePrices,ProbabilityITMDaily);

    xlabel('Exercise Price');
    title('Option prices for a Vanilla option using a 1 year - Daily volatility');
    Axes_YLabels = get(AX,'Ylabel');
    set(Axes_YLabels{1},'String','Option Price') ;

    set(H1(1),'LineStyle','-');
    set(H1(1),'Color','r');
    set(H1(1),'LineWidth',2);

    set(H1(2),'LineStyle','-');
    set(H1(2),'Color','b');
    set(H1(2),'LineWidth',2);

    set(H1(3),'LineStyle','--');
    set(H1(3),'Color','r');
    set(H1(3),'LineWidth',1);

    set(H1(4),'LineStyle',':');
    set(H1(4),'Color','r');
    set(H1(4),'LineWidth',1);

    set(H2,'LineStyle','-');
    set(H2,'Color','g');
    set(H2,'LineWidth',2);

    set(get(AX(2),'Ylabel'),'String','Probability of being In the Money');
    legend(H1,{['Option Price (Monte Carlo)'], ['Option Price (Black Scholes)'], ['99% Confidence interval (Lower)'],['99% Confidence interval (Upper)']},'Location','NorthEast');
    legend(H2,{'Probability'},'Location','SouthWest');
    grid on;
    set(h,'WindowStyle','Docked');
 end;


function f = cumsum(f, m, dim)
%CUMSUM   Indefinite integral of a TRIGTECH.
%   CUMSUM(F) is the indefinite integral of the TRIGTECH F, whose mean
%   is zero, with the constant of integration chosen so that F(-1) = 0.
%   If the mean of F is not zero then an error is thrown since the indefinite
%   integral would no longer be periodic.
%
%   CUMSUM(F, M) will compute the Mth definite integral with the constant of
%   integration chosen so that each intermediary integral evaluates to 0 at
%   -1.
%   Thus, CUMSUM(F, 2) is equivalent to CUMSUM(CUMSUM(F)).
%
%   CUMSUM(F, M, 2) will take the Mth cumulative sum over the columns F an
%   array-valued TRIGTECH.
%
% See also DIFF, SUM.

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% If the TRIGTECH G of length n is represented as
%       \sum_{k=-(n-1)/2}^{(n-1)/2} c_k exp(i*pi*kx)
% its integral is represented with a TRIGTECH of length n given by
%       \sum_{k=-(n-1)/2}^{(n-1)/2} b_k exp(i*pi*kx)
% where b_0 is determined from the constant of integration as
%       b_0 = \sum_{k=-(n-1)/2}^{(n-1)/2} (-1)^k/(i*pi*k) c_k;
% with c_0 := 0. The other coefficients are given by
%       b_k = c_k/(i*pi*k).
%
% If the TRIGTECH G of length n is represented as
%       \sum_{k=-n/2+1}^{n/2-1} c_k exp(i*pi*kx) + c(n/2)cos(n*pi/2x)
% then first set c(n) = 0.5*c(n) and define a = [0.5*c(n/2) c] so that we
% have the equivalent expansion:
%       \sum_{k=-n/2}^{n/2} a_k exp(i*pi*kx)
% The integral of this is represented with a TRIGTECH of length n+1 given by
%       \sum_{k=-n/2}^{n/2} b_k exp(i*pi*kx)
% where b_0 is determined from the constant of integration as
%       b_0 = \sum_{k=-n/2}^{n/2} (-1)^k/(i*pi*k) a_k;
% with a_0 := 0. The other coefficients are given by
%       b_k = a_k/(ik).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Trivial case of an empty TRIGTECH:
if ( isempty(f) )
    return
end

if ( nargin < 2 || isempty(m) )
    % Order of integration not passed in. Assume 1 by default:
    m = 1;
elseif ( m == 0 )
    % Nothing to do here!
    return
end

% Sum with respect to the continuous variable by default:
if ( nargin < 3 )
    dim = 1;
end

if ( dim == 1 )
    % Take difference across 1st dimension:
    f = cumsumContinuousDim(f, m);
else
    % Take difference across 2nd dimension:
    f = cumsumFiniteDim(f, m);
end

end

function f = cumsumContinuousDim(f, m)
% CUMSUM over the continuous dimension.

    % Initialize storage:
    c = f.coeffs; % Obtain Fourier coefficients {c_k}
    numCoeffs = size(c,1);

    fIsEven = mod(numCoeffs, 2) == 0;

    % index of constant coefficient
    if fIsEven
       ind = numCoeffs/2 + 1;
    else
       ind = (numCoeffs + 1)/2;
    end

    % Check that the mean of the TRIGtech is zero.  If it is not, then
    % throw an error.
    if ( any(abs(c(ind,:)) > 1e1*vscale(f)*eps) )
        error('CHEBFUN:TRIGTECH:cumsum:meanNotZero', ...
            ['Indefinite integrals are only possible for TRIGTECH objects '...
            'with zero mean.']);
    end

    % Force the mean to be exactly zero.
    if ( fIsEven )
        % Set coeff corresponding to the constant mode to zero:
        c(numCoeffs/2+1,:) = 0;
        % Expand the coefficients to be symmetric (see above discussion).
        c(1,:) = 0.5*c(1,:);
        c = [c; c(1,:)];
        highestDegree = numCoeffs/2;
    else
        c((numCoeffs+1)/2,:) = 0;
        highestDegree = (numCoeffs-1)/2;
    end

    % Loop for integration factor for each coefficient:
    sumIndicies = (-highestDegree:highestDegree).';
    integrationFactor = (-1i./sumIndicies/pi).^m;
    % Zero out the one corresponding to the constant term.
    integrationFactor(highestDegree+1) = 0;
    c = bsxfun(@times,c,integrationFactor);
    % If this is an odd order cumsum and there are an even number of
    % coefficients then zero out the cofficient corresponding to sin(N/2x)
    % term, since this will be zero on the Fourier grid.
    if ( (mod(m, 2) == 1) && fIsEven )
        c(1,:) = 0;
        c(numCoeffs+1,:) = 0;
    end

    % Fix the constant term.
    c(highestDegree+1,:) = -sum(bsxfun(@times,c,(-1).^sumIndicies));

    % If the original TRIGTECH had an even number of coefficients then
    % shrink the coefficent vector corresponding to its indefinite integral
    % back to its original size since it was increased by one above to make
    % the integration code slicker.
    if ( fIsEven )
        c = c(1:end-1,:);
    end

    % Recover values and attach to output:
    f.values = f.coeffs2vals(c);
    f.values(:,f.isReal) = real(f.values(:,f.isReal));

    f.coeffs = c;

    % Simplify (as suggested in Chebfun ticket #128)
    f = simplify(f);

    % Ensure f(-1) = 0:
    lval = get(f, 'lval');
    f.coeffs(1,:) = f.coeffs(1,:) - lval;
    f.values = bsxfun(@minus, f.values, lval);

end

function f = cumsumFiniteDim(f, m)
% CUMSUM over the finite dimension.

    for k = 1:m
        f.values = cumsum(f.values, 2);
        f.coeffs = cumsum(f.coeffs, 2);
    end

end


function f = projectOntoBMCIII( f )
% PROJECTONTOBMCI  Projection onto BMC-III symmetry.
%
% f = projectOntoBMCIII(f) is the orthogonal projection of f onto BMC-III
% symmetry, i.e., a function that is
% 1. even in theta for every even wave number in lambda;
% 2. odd in theta for every odd wave number in lambda;
% Additionally, for all but k=0 wavenumber lambda the resulting projection
% enforces the ballfun is zero at the poles.
%
% The projection is orthogonal, i.e., the correction matrix to fix up the
% structure has the smallest possible Frobenius norm.

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

if isempty( f )
   return
end

% Get the tensor of coefficients
F = f.coeffs;

% Permute F
F = permute(F,[1,3,2]);

% Loop over lambda
for l = 1:size(F,3)
    % Update the matrix
    F(:,:,l) = projectOntoRTheta(F(:,:,l));
end

% Permute back
F = permute(F,[1,3,2]);
f = ballfun(F, 'coeffs');
end

function X = projectOntoRTheta( X )
% Project the matrix of Chebyshev--Fourier coefficients onto a BMC-II
% function. The projection is orthogonal, i.e., the correction matrix to
% fix up the structure has the smallest possible Frobenius norm.

% Get the discretization
[m,n] = size(X);

zeroMode = floor(n/2)+1;
evenModes = [fliplr(zeroMode-2:-2:1) zeroMode+2:2:n];  % Not including the zero mode
oddModes = [fliplr(zeroMode-1:-2:1) zeroMode+1:2:n];

% First do the zero-periodic mode in theta.
% Enforce the expansion is even in r.
I = eye( m ); A = I(2:2:end,:);
C = A \ ( A * X(:,zeroMode) );
C = I \ C;

% Update coeff matrix:
X(:,zeroMode) = X(:,zeroMode) - C;

% Second do the even-periodic, non-zero modes in theta.
% Enforce these are zero at the pole and that the expansion is even in
% theta
% Vectors [ T_k(0) ]:
A = real( (-1i).^(0:m-1) );   % A * X should be the zero vector.

% Solution to underdetermined system A*(X + Y) = 0 with smallest Frobenius
% norm:
C = A \ ( A * X(:,evenModes) );
C = I \ C;
X(:,evenModes) = X(:,evenModes) - C;

% Now project onto odd-anti-periodic.  Nothing special has to be done at
% the poles since enforcing the expansion is odd in r guarantees that it
% sums to zero.
A = I(1:2:end,:);
C = A \ ( A * X(:,oddModes) );
C = I \ C;
X(:,oddModes) = X(:,oddModes) - C;
end


% WSUM - Weighted sum of a matrix along one dimension.
%
% Y = WSUM(X,W,DIM)
%
% X   : matrix
% W   : vector of weights
% DIM : dimension to sum along (default: first non-singleton dimension)
%
% When X is a 2D-matrix, one can simply use W'*X or X*W for more
% efficient performace.

% Last modified 2010-06-09
% Copyright (c) Jaakko Luttinen (jaakko.luttinen@tkk.fi)

function y = wsum(X,w,dim)

% warning('This function seems to be inefficient..')

if ~isvector(w)
  error('Weights must be given as a vector.');
end

if nargin < 3
  % Default dimension: first non-singleton dimension
  dim = find(size(X)>1, 1);
  if isempty(dim)
    dim = 1;
  end
end

if size(X,dim) ~= length(w)
  error(['The length of the weight vector does not match with the size ' ...
         'of the matrix.']);
end

s = ones(1,max(dim,2));
s(dim) = length(w);
y = sum(bsxfun(@times, X, reshape(w,s)), dim);


function [Phi,S,Lambda,M] = extract_eigen_functions_new(shape,k)

    [M,S]=laplacian([shape.X shape.Y shape.Z],shape.TRIV);
    M = diag(sum(M,2));
    [Phi,Lambda] = eigs(-S,M,k,1e-5);
    Lambda = diag(Lambda);
    [Lambda,idx] = sort(Lambda,'descend');
    Phi = Phi(:,idx);
%     PhiI = Phi'*M;
    Lambda = abs(Lambda); %added this to return positive eigen values.

end


function C=clustering_coef_bu(G)
%CLUSTERING_COEF_BU     Clustering coefficient
%
%   C = clustering_coef_bu(A);
%
%   The clustering coefficient is the fraction of triangles around a node
%   (equiv. the fraction of node's neighbors that are neighbors of each other).
%
%   Input:      A,      binary undirected connection matrix
%
%   Output:     C,      clustering coefficient vector
%
%   Reference: Watts and Strogatz (1998) Nature 393:440-442.
%
%
%   Mika Rubinov, UNSW, 2007-2010

n=length(G);
C=zeros(n,1);

for u=1:n
    V=find(G(u,:));
    k=length(V);
    if k>=2                 %degree must be at least 2
        S=G(V,V);
        C(u)=sum(S(:))/(k^2-k);
    end
end


%% IPOPT PARFOR testing
clc
clear all

%Objective
fun = @(x) 20 + x(1)^2 + x(2)^2 - 10*(cos(2*pi*x(1)) + cos(2*pi*x(2)));
%Constraints
lb = [5*pi;-20*pi];
ub = [20*pi;-4*pi];
%Setup Options
opts = optiset('solver','ipopt');
Opt = opti('fun',fun,'bounds',lb,ub,'opts',opts);

%Generate a series of starting points
n = 1000;
X0 = [linspace(lb(1),lb(end),n); linspace(ub(1),ub(end),n)];

%Preallocate solution vector
sols = zeros(2,n);
solp = zeros(2,n);

%% run serial (8.17s)
tic
for i = 1:n
    sols(:,i) = solve(Opt,X0(:,i));
end
toc

%%
matlabpool(4);

%% run parfor (2.6s)
tic
parfor i = 1:n
    solp(:,i) = solve(Opt,X0(:,i));
end
toc

%% check results
err = norm(sols-solp)


function W = randInitializeWeights(L_in, L_out)
%RANDINITIALIZEWEIGHTS Randomly initialize the weights of a layer with L_in
%incoming connections and L_out outgoing connections
%   W = RANDINITIALIZEWEIGHTS(L_in, L_out) randomly initializes the weights
%   of a layer with L_in incoming connections and L_out outgoing
%   connections.
%
%   Note that W should be set to a matrix of size(L_out, 1 + L_in) as
%   the column row of W handles the "bias" terms
%

% You need to return the following variables correctly
W = zeros(L_out, 1 + L_in);

% ====================== YOUR CODE HERE ======================
% Instructions: Initialize W randomly so that we break the symmetry while
%               training the neural network.
%
% Note: The first row of W corresponds to the parameters for the bias units
%

epsilon = 0.12;
W = rand(L_out, 1 + L_in) * 2 * epsilon - epsilon;

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

end


function pinv = perm_inverse ( n, p )

%*****************************************************************************80
%
%% PERM_INVERSE computes the inverse of a permutation.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer N, the number of values being permuted.
%    N must be positive.
%
%    Input, integer P(N), describes the permutation.
%    P(I) is the item which is permuted into the I-th place
%    by the permutation.
%
%    Output, integer PINV(N), the inverse permutation.
%

%
%  Check.
%
  perm_check ( n, p );

  pinv(p(1:n)) = 1:n;

  return
end


function prob_test135 ( )

%*****************************************************************************80
%
%% TEST135 tests SECH_CDF, SECH_CDF_INV, SECH_PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST135\n' );
  fprintf ( 1, '  For the Hyperbolic Secant PDF:\n' );
  fprintf ( 1, '  SECH_CDF evaluates the CDF.\n' );
  fprintf ( 1, '  SECH_CDF_INV inverts the CDF.\n' );
  fprintf ( 1, '  SECH_PDF evaluates the PDF.\n' );

  a = 3.0;
  b = 2.0;

  check = sech_check ( a, b );

  if ( ~check );
    fprintf ( 1, '\n' );
    fprintf ( 1, 'TEST135 - Fatal error!\n' );
    fprintf ( 1, '  The parameters are not legal.\n' );
    return
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PDF parameter A =         %14f\n', a );
  fprintf ( 1, '  PDF parameter B =         %14f\n', b );

  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, '       X            PDF           CDF            CDF_INV\n' );
  fprintf ( 1, '\n' );

  for i = 1 : 10

    [ x, seed ] = sech_sample ( a, b, seed );

    pdf = sech_pdf ( x, a, b );

    cdf = sech_cdf ( x, a, b );

    x2 = sech_cdf_inv ( cdf, a, b );

    fprintf ( 1, ' %14f  %14f  %14f  %14f\n', x, pdf, cdf, x2 );

  end

  return
end


function a = rutis1 ( )

%*****************************************************************************80
%
%% RUTIS1 returns the RUTIS1 matrix.
%
%  Example:
%
%    6 4 4 1
%    4 6 1 4
%    4 1 6 4
%    1 4 4 6
%
%  Properties:
%
%    A is symmetric: A' = A.
%
%    A is integral, therefore det ( A ) is integral, and
%    det ( A ) * inverse ( A ) is integral.
%
%    A has constant row sums.
%
%    Because it has a constant row sum of 15,
%    A has an eigenvalue of 15, and
%    a (right) eigenvector of ( 1, 1, 1, 1 ).
%
%    A has constant column sums.
%
%    Because it has a constant column sum of 15,
%    A has an eigenvalue of 15, and
%    a (left) eigenvector of ( 1, 1, 1, ..., 1 ).
%
%    A has a repeated eigenvalue.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Joan Westlake,
%    A Handbook of Numerical Matrix Inversion and Solution of
%    Linear Equations,
%    John Wiley, 1968,
%    ISBN13: 978-0471936756,
%    LC: QA263.W47.
%
%  Parameters:
%
%    Output, real A(4,4), the matrix.
%

%
%  Note that the matrix entries are listed by row.
%
  a(1:4,1:4) = [ ...
    6.0,  4.0,  4.0,  1.0; ...
    4.0,  6.0,  1.0,  4.0; ...
    4.0,  1.0,  6.0,  4.0; ...
    1.0,  4.0,  4.0,  6.0 ];

  return
end


function res = smoothPolyline(poly, M)
%SMOOTHPOLYLINE Smooth a polyline using local averaging.
%
%   RES = smoothPolygon(POLY, M)
%   POLY contains the polyline vertices, and M is the size of smoothing
%   (given as the length of the convolution window).
%   Extremities of the polyline are smoothed with reduced window (last and
%   first vertices are kept identical, second and penultimate vertices are
%   smoothed with 3 values, etc.).
%
%   Example
%     img = imread('circles.png');
%     img = imfill(img, 'holes');
%     contours = bwboundaries(img');
%     poly = contours{1}(201:500,:);
%     figure; drawPolyline(poly, 'b'); hold on;
%     poly2 = smoothPolyline(poly, 21);
%     drawPolygon(poly2, 'm');
%
%   See also
%     polygons2d, smoothPolygon, simplifyPolyline, resamplePolyline

% ------
% Author: David Legland
% E-mail: david.legland@grignon.inra.fr
% Created: 2015-02-17, using Matlab 8.4.0.150421 (R2014b)
% Copyright 2015-2022 INRA - Cepia Software Platform

% compute the number of elements before and after
M1 = floor((M - 1) / 2);
M2 = ceil((M - 1) / 2);

% create convolution vector
v2 = ones(M, 1) / M;

% apply filtering on central part of the polyline
res(:,1) = conv(poly(:,1), v2, 'same');
res(:,2) = conv(poly(:,2), v2, 'same');

% need to recompute the extremities
for i = 1:M1
    i2 = 2 * i - 1;
    res(i, 1) = mean(poly(1:i2, 1));
    res(i, 2) = mean(poly(1:i2, 2));
end
for i = 1:M2
    i2 = 2 * i - 1;
    res(end - i + 1, 1) = mean(poly(end-i2+1:end, 1));
    res(end - i + 1, 2) = mean(poly(end-i2+1:end, 2));
end


% Computes the probability density function of the multivariate gaussian distribution.
function probabilities = multivariate_gaussian(X, mu, sigma2)
    % Get number of training sets and features.
    [m n] = size(X);

    % Init probabilities matrix.
    probabilities = ones(m, 1);

    % Go through all training examples and through all features.
    for i=1:m
        for j=1:n
            p = (1 / sqrt(2 * pi * sigma2(j))) * exp(-(X(i, j) - mu(j)) .^ 2 / (2 * sigma2(j)));
            probabilities(i) = probabilities(i) * p;
        end
    end
end


function value = c8_le_l2 ( x, y )

%*****************************************************************************80
%
%% C8_LE_L2 := X <= Y for complex values, and the L2 norm.
%
%  Definition:
%
%    The L2 norm can be defined here as:
%
%      C8_NORM_L2(X) = sqrt ( ( real (X) )**2 + ( imag (X) )**2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, complex X, Y, the values to be compared.
%
%    Output, logical VALUE, is TRUE if X <= Y.
%
  if ( ( real ( x ) )^2 + ( imag ( x ) )^2 ...
    <= ( real ( y ) )^2 + ( imag ( y ) )^2 )
    value = 1;
  else
    value = 0;
  end

  return
end


function x = discrete_sample(p, n)
% Samples from a discrete distribution
%
%   x = discretesample(p, n)
%       independently draws n samples (with replacement) from the
%       distribution specified by p, where p is a probability array
%       whose elements sum to 1.
%
%       Suppose the sample space comprises K distinct objects, then
%       p should be an array with K elements. In the output, x(i) = k
%       means that the k-th object is drawn at the i-th trial.
%
%   Remarks
%   -------
%       - This function is mainly for efficient sampling in non-uniform
%         distribution, which can be either parametric or non-parametric.
%
%       - The function is implemented based on histc, which has been
%         highly optimized by mathworks. The basic idea is to divide
%         the range [0, 1] into K bins, with the length of each bin
%         proportional to the probability mass. And then, n values are
%         drawn from a uniform distribution in [0, 1], and the bins that
%         these values fall into are picked as results.
%
%       - This function can also be employed for continuous distribution
%         in 1D/2D dimensional space, where the distribution can be
%         effectively discretized.
%
%       - This function can also be useful for sampling from distributions
%         which can be considered as weighted sum of "modes".
%         In this type of applications, you can first randomly choose
%         a mode, and then sample from that mode. The process of choosing
%         a mode according to the weights can be accomplished with this
%         function.
%
%   Examples
%   --------
%       % sample from a uniform distribution for K objects.
%       p = ones(1, K) / K;
%       x = discretesample(p, n);
%
%       % sample from a non-uniform distribution given by user
%       x = discretesample([0.6 0.3 0.1], n);
%
%       % sample from a parametric discrete distribution with
%       % probability mass function given by f.
%       p = f(1:K);
%       x = discretesample(p, n);
%

%   Created by Dahua Lin, On Oct 27, 2008
%

%% parse and verify input arguments

assert(isfloat(p), 'discretesample:invalidarg', ...
    'p should be an array with floating-point value type.');

assert(isnumeric(n) && isscalar(n) && n >= 0 && n == fix(n), ...
    'discretesample:invalidarg', ...
    'n should be a nonnegative integer scalar.');

%% main

% process p if necessary

K = numel(p);
if ~isequal(size(p), [1, K])
    p = reshape(p, [1, K]);
end

% construct the bins

edges = [0, cumsum(p)];
s = edges(end);
if abs(s - 1) > eps
    edges = edges * (1 / s);
end

% draw bins

rv = rand(1, n);
c = histc(rv, edges);
ce = c(end);
c = c(1:end-1);
c(end) = c(end) + ce;

% extract samples

xv = find(c);

if numel(xv) == n  % each value is sampled at most once
    x = xv;
else                % some values are sampled more than once
    xc = c(xv);
    d = zeros(1, n);
    dv = [xv(1), diff(xv)];
    dp = [1, 1 + cumsum(xc(1:end-1))];
    d(dp) = dv;
    x = cumsum(d);
end

% randomly permute the sample's order
x = x(randperm(n));


function R=estExpDecayReliability(t,T,method)
%%ESTEXPDECAYRELIABILITY Determine the probability that a particular
%       example of something will be functional after time T given
%       independent the failure times of n other examples under the
%       assumption that the time of failure given something is functional
%       at time zero is exponentially distributed, so the probability of
%       success (it lasting longer than T) given that it works at time zero
%       is Pr{T>t}=exp(-t/theta) for some parameter theta.
%
%INPUTS: t A 1Xn or nX1 vector of the times when something failed. All
%          elements should be >=0.
%        T The desired time after which a failure is acceptable. T>=0.
%   method The estimation approach. Possible values are:
%          0 (The default if omitted or an empty matrix is passed) Use the
%            expected value estimate.
%          1 Use the maximum likelihood estimate. This estimate is biased.
%
%OUTPUTS: R The probability that  the system will still be operational at
%           some point after time T.
%
%This implements the methods of [1]. The basic reliability model is
%R=p*P
%where p is the probability of a failure at time 0 and P is the probability
%of a failure between time 0 and T. THe exponential decay model applies to
%P.
%
%EXAMPLE:
%We demonstrate here that the value of R at time T is more reliable when
%computing using method 0 than method 1 given n=30 samples of the data.
% p=0.9;
% T=2;
% theta=3;
% lambda=1/theta;
% RTrue=p*(1-ExponentialD.CDF(T,lambda))
%
% numRuns=1e4;
% R0=0;
% R1=0;
% for curRun=1:numRuns
%     n=30;
%     t=zeros(n,1);
%     for k=1:n
%         if(rand()<p)%If working at time 0.
%            t(k)=ExponentialD.rand(1,lambda);
%         else
%            t(k)=0;
%         end
%     end
%     R0=R0+estExpDecayReliability(t,T,0);
%     R1=R1+estExpDecayReliability(t,T,1);
% end
% R0=R0/numRuns
% R1=R1/numRuns
%Typically, R0 will be closet to RTrue than R1.
%
%REFERENCES:
%[1] E. L. Pugh, "The best estimate of reliability in the exponential
%    case," Operations Research, vol. 11, no. 1, pp. 57-61, Jan.-Feb. 1963.
%
%June 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

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

n=length(t);
sel=(t~=0);
p=sum(sel)/n;

%Keep only failure times that are >0.
t=t(sel);
n=length(t);

if(n==0)
   R=0;
   return;
end

theta=sum(t)/n;%Equation 7.
switch(method)
    case 0%The expected value solution.
        R=p*(1-T/(n*theta))^(n-1);%Equation 17 (with p inserted).
    case 1%The ML solution.
        R=p*exp(-T/theta);%Equation 6 (with p inserted).
    otherwise
        error('Unknown method specified.')
end
end

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


% BOX_INTERSECT Given sets of axis-aligne boxes determine which pairs overlap.
%
% I = box_intersect(A1,A2)
%
% Inputs:
%   A1  #A by dim list of minimum corners
%   A2  #A by dim list of maximum corners
% Outputs:
%   I  #I by 2 list of indices into A such that box I(i,1) of set A intersects
%     with box I(i,2) of set A.
%
% I = box_intersect(A1,A2,B1,B2)
%
% Inputs:
%   A1  #A by dim list of minimum corners
%   A2  #A by dim list of maximum corners
%   B1  #B by dim list of minimum corners
%   B2  #B by dim list of maximum corners
% Outputs:
%   I  #I by 2 list of indices into A such that box I(i,1) of set A intersects
%     with box I(i,2) of set B.


function [px, py, gx, gy] = position_5_link(z,P)
%[px,py,gx,gy] = POSITION_5_LINK(Z,P)
%
%FUNCTION:  This function computes the cartesian positions
%    of the CoM and tip of each link
%INPUTS:
%
%
%OUTPUTS:
%    px = [nLink X nTime] position of the end of each link
%    py = [nLink X nTime] position of the end of each link
%    gx = [nLink X nTime] position of the CoM of each link
%    gy = [nLink X nTime] position of the CoM of each link
%
%NOTES:
%    This file was automatically generated by writePosition.m

g  = P.g ; %gravity
m1 = P.m(1); % Link 1 mass
m2 = P.m(2); % Link 2 mass
m3 = P.m(3); % Link 3 mass
m4 = P.m(4); % Link 4 mass
m5 = P.m(5); % Link 5 mass
l1 = P.l(1); % Link 1 length
l2 = P.l(2); % Link 2 length
l3 = P.l(3); % Link 3 length
l4 = P.l(4); % Link 4 length
l5 = P.l(5); % Link 5 length
I1 = P.I(1); % Link 1 moment of inertia about its center of mass
I2 = P.I(2); % Link 2 moment of inertia about its center of mass
I3 = P.I(3); % Link 3 moment of inertia about its center of mass
I4 = P.I(4); % Link 4 moment of inertia about its center of mass
I5 = P.I(5); % Link 5 moment of inertia about its center of mass
d1 = P.d(1); % Link 1 distance between center of mass and parent joint
d2 = P.d(2); % Link 2 distance between center of mass and parent joint
d3 = P.d(3); % Link 3 distance between center of mass and parent joint
d4 = P.d(4); % Link 4 distance between center of mass and parent joint
d5 = P.d(5); % Link 5 distance between center of mass and parent joint

th1 = z(1,:);
th2 = z(2,:);
th3 = z(3,:);
th4 = z(4,:);
th5 = z(5,:);

nTime = length(th1);
px = zeros(5,nTime);
py = zeros(5,nTime);
gx = zeros(5,nTime);
gy = zeros(5,nTime);

px(1,:) = l1.*cos(th1);
py(1,:) = l1.*sin(th1);
gx(1,:) = d1.*cos(th1);
gy(1,:) = d1.*sin(th1);

px(2,:) = l1.*cos(th1) + l2.*cos(th2);
py(2,:) = l1.*sin(th1) + l2.*sin(th2);
gx(2,:) = d2.*cos(th2) + l1.*cos(th1);
gy(2,:) = d2.*sin(th2) + l1.*sin(th1);

px(3,:) = l1.*cos(th1) + l2.*cos(th2) + l3.*cos(th3);
py(3,:) = l1.*sin(th1) + l2.*sin(th2) + l3.*sin(th3);
gx(3,:) = d3.*cos(th3) + l1.*cos(th1) + l2.*cos(th2);
gy(3,:) = d3.*sin(th3) + l1.*sin(th1) + l2.*sin(th2);

px(4,:) = l1.*cos(th1) + l2.*cos(th2) + l3.*cos(th3) + l4.*cos(th4);
py(4,:) = l1.*sin(th1) + l2.*sin(th2) + l3.*sin(th3) + l4.*sin(th4);
gx(4,:) = d4.*cos(th4) + l1.*cos(th1) + l2.*cos(th2) + l3.*cos(th3);
gy(4,:) = d4.*sin(th4) + l1.*sin(th1) + l2.*sin(th2) + l3.*sin(th3);

px(5,:) = l1.*cos(th1) + l2.*cos(th2) + l3.*cos(th3) + l4.*cos(th4) + l5.*cos(th5);
py(5,:) = l1.*sin(th1) + l2.*sin(th2) + l3.*sin(th3) + l4.*sin(th4) + l5.*sin(th5);
gx(5,:) = d5.*cos(th5) + l1.*cos(th1) + l2.*cos(th2) + l3.*cos(th3) + l4.*cos(th4);
gy(5,:) = d5.*sin(th5) + l1.*sin(th1) + l2.*sin(th2) + l3.*sin(th3) + l4.*sin(th4);

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Setting up advection-diffusion solver
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function C = please_Update_Adv_Diff_Concentration_Unsplit(C,dt,dx,dy,uX,uY,k)

% C:     concentration
% dt:    time-step
% dx,dy: spatial steps in x and y, respectively
% uX:    x-Component of Velocity
% uY:    y-Component of Velocity
% k:     diffusion coefficient

% Compute Necessary Derivatives (Note: these calculations could be parallalized)
Cx = give_Necessary_Derivative(C,dx,uX,'x');
Cy = give_Necessary_Derivative(C,dy,uY,'y');
Cxx = DD(C,dx,'x');
Cyy = DD(C,dy,'y');

% Update Concentration
%C = C + dt * ( k*(Cxx+Cyy) - uX'.*Cx - uY'.*Cy );

C = C + dt * ( k*(Cxx+Cyy) - uX.*Cx - uY.*Cy );

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Computes derivative based on sign of Velocity, u, using UPWIND
% approach
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function C_z = give_Necessary_Derivative(C,dz,uZ,string)

C_z = zeros(size(C));
len = length(uZ(:,1));
signs = sign(uZ);

if strcmp(string,'x')

    %For periodicity on ends w/ UPWIND
    for i=1:len

        %left side of grid
        if signs(i,1) <= 0
            C_z(i,1) =  ( C(i,2) - C(i,1) ) / (dz);
        else
            C_z(i,1) =  ( C(i,1) - C(i,len) ) / (dz);
        end

        %right side of grid
        if signs(i,len) <= 0
            C_z(i,len) =  ( C(i,1) - C(i,len) ) / (dz);
        else
            C_z(i,len) =  ( C(i,len) - C(i,len-1) ) / (dz);
        end

    end

    %Standard Upwind
    for i=1:len
        for j=2:len-1
            if signs(i,j) <= 0
                C_z(i,j) = ( C(i,j+1) - C(i,j) ) / (dz);
            else
                C_z(i,j) = ( C(i,j) - C(i,j-1) ) / (dz);
            end
        end
    end

    % Ends x-Direction calculation %

elseif strcmp(string,'y')

    %For periodicity on ends w/ UPWIND
    for i=1:len

        %bottom of grid
        if signs(1,i) <= 0
            C_z(1,i) =  ( C(2,i) - C(1,i) ) / (dz);
        else
            C_z(1,i) =  ( C(1,i) - C(len,i) ) / (dz);
        end

        %top of grid
        if signs(len,i) <= 0
            C_z(len,i) =  ( C(1,i) - C(len,i) ) / (dz);
        else
            C_z(len,i) =  ( C(len,i) - C(len-1,i) ) / (dz);
        end

    end

    %Standard Upwind
    for i=2:len-1
        for j=1:len
            if signs(i,j) <= 0
                C_z(i,j) = ( C(i+1,j) - C(i,j) ) / (dz);
            else
                C_z(i,j) = ( C(i,j) - C(i-1,j) ) / (dz);
            end
        end
    end

    % Ends y-Direction calculation %

else

    fprintf('\n\n\n ERROR IN FUNCTION D FOR COMPUTING 1ST DERIVATIVE\n');
    fprintf('Need to specify which desired derivative, x or y.\n\n\n');

end

clear signs; clear len;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Finds CENTERED finite difference approximation to 2ND
% DERIVATIVE in z direction, specified by input and 'string'
% Note: It automatically accounts for periodicity of the domain.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function u_zz = DD(u,dz,string)

% u:      velocity
% dz:     spatial step in "z"-direction
% string: specifies which 2ND derivative to take (to enforce periodicity)

len = length(u(:,1));

if strcmp(string,'x')

    %For periodicity on ends
    u_zz(:,1) =  ( u(:,2) - 2*u(:,1)   + u(:,len) )   / (dz^2);
    u_zz(:,len)= ( u(:,1) - 2*u(:,len) + u(:,len-1) ) / (dz^2);

    %Standard Upwind Scheme (Centered Difference)
    for j=2:len-1
        u_zz(:,j) = ( u(:,j+1) - 2*u(:,j) + u(:,j-1) ) / (dz^2);
    end

elseif strcmp(string,'y')

    %For periodicity on ends
    u_zz(1,:) =  ( u(2,:) - 2*u(1,:)   + u(len,:) )   / (dz^2);
    u_zz(len,:)= ( u(1,:) - 2*u(len,:) + u(len-1,:) ) / (dz^2);

    %Standard Upwind Scheme (Centered Difference)
    for j=2:len-1
        u_zz(j,:) = ( u(j+1,:) - 2*u(j,:) + u(j-1,:) ) / (dz^2);
    end

else

    fprintf('\n\n\n ERROR IN FUNCTION DD FOR COMPUTING 2ND DERIVATIVE\n');
    fprintf('Need to specify which desired derivative, x or y.\n\n\n');

end


function [Ex Ey Ez] = MiePECBall(cart, k, R, N)
% The code caculates the time-harmonic scattered field value at point 'cart'
% due to a PEC ball with radius R centered at the origin.
% The incident wave is E=exp(-ikz).
% The formulation is based on H.C. van de Hulst, P123
% 'light scattering by small particles', Dover, 1981
% Input: cart -- cartiesian coordiante (1x3) of the point ouside the ball
%        k    -- wavenumber
%        R    -- radius of the PEC ball
%        N    -- number of terms used in Mie series
% Output: [Ex Ey Ez] -- the scattering electric field
% Author: Jiguang Sun, 02/13/2011, jsun@desu.edu
% Please report bugs to jsun@desu.edu
% Copyright (c) 2011, Jiguang Sun, rights reserved.
% THIS SOFTWARE IS PROVIDED "AS IS".
% Redistribution and use in source and binary forms, with or without
% modification, are permitted.
i = sqrt(-1);
[phi,th,r] = cart2sph(cart(1), cart(2), cart(3)); th = pi/2-th;
if r < R
    % disp('The point is inside the ball!')
    Ex = 0; Ey = 0; Ez = 0;
    return;
end

n = 1:N+2;
x = k*R;
[j(n), ierr(1,n)] = besselj(n - 1 + 1/2, x); j = j*sqrt(pi/(2*x));
[h(n), ierr(1,n)] = besselh(n - 1 + 1/2, 2, x); h = h*sqrt(pi/(2*x));
if any(any(ierr))
    disp('Accuracy error in a Bessel or Hankel function.');
    Ex = 0; Ey = 0; Ez = 0;
    return;
end
% scattering coefficients
an = j(2:N+1)./h(2:N+1);
bn = (j(2:N+1)+k*R*j(1:N)-k*R*j(3:N+2))./(h(2:N+1)+k*R*h(1:N)-k*R*h(3:N+2));
% various terms ralated to Racati-Bessel's functions
n = 1:N+4;
z = k*r; k2r = k^2*r;
[h(n), ierr(2,n)] = besselh(n - 2 + 1/2, 2, z); h = h*sqrt(pi/(2*z));
hn = h(3:N+2);
drh = (h(3:N+2)+k*r*h(2:N+1)-k*r*h(4:N+3))/2;
ddrh=(k2r*h(1:N)+2*k*h(2:N+1)-(1/r+2*k2r)*h(3:N+2)-2*k*h(4:N+3)+k2r*h(5:N+4))/4;
%
if any(any(ierr))
    disp('Accuracy error in a Bessel or Hankel function.')
    Ex = 0; Ey = 0; Ez = 0;
    return;
end
% various terms related to associated Legendre polynomials
Pn(1) = 1;
Pn(2) = cos(th);
for n=2:N-1
    Pn(n+1) = ((2*n-1)*cos(th)*Pn(n)-(n-1)*Pn(n-1))/n;
end
% Pn1 starts from n = 1.
Pn1(1) = -sin(th);
Pn1(2) = -3.0*sin(th)*cos(th);
for n=2:N-1
    Pn1(n+1) = (2.0*n+1)*cos(th)*Pn1(n)/n-(n+1)*Pn1(n-1)/n;
end
% Pn1S starts from n = 1;
Pn1S(1) = -1;
Pn1S(2) = -3.0*cos(th);
for n = 2:N-1
    Pn1S(n+1) = Pn1S(n-1)-(2*n+1)*Pn(n+1);
end

for n = 1:N
    if n == 1
        dPn1(n) = -cos(th);
    elseif n == 2
        dPn1(n) = 3*(2*sin(th)*sin(th)-1);
    else
        dPn1(n) = (2*n-1)/(n-1)*Pn1(n-1)*(-sin(th))+(2*n-1)/(n-1)*cos(th)*dPn1(n-1)-n/(n-1)*dPn1(n-2);
    end
end
% compute M and N
Mrho = 0; Mth = 0; Mphi = 0;
for n = 1:N
    c = (-i)^(n)*(2*n+1)/(n*(n+1));
    Mth = Mth + c*an(n)*hn(n)*Pn1S(n)*cos(phi);
    Mphi = Mphi-c*an(n)*hn(n)*dPn1(n)*sin(phi);
end
Nrho = 0; Nth = 0; Nphi = 0;
for n = 1:N
    c = (-i)^(n)*(2*n+1)/(n*(n+1));
    Nrho = Nrho + bn(n)*c*(ddrh(n)+k^2*r*hn(n))*Pn1(n)*cos(phi)/(k);
    Nth = Nth + bn(n)*c/r*drh(n)*dPn1(n)*cos(phi)/(k);
    Nphi = Nphi + bn(n)*c/r*drh(n)*Pn1S(n)*(-sin(phi))/(k);
end
% compute scattering field in Spherical coordinate
Erho = Mrho + i*Nrho;
Ephi = Mphi + i*Nphi;
Eth = Mth + i*Nth;
% change back to cartisian coordinate
Ex = Erho*sin(th)*cos(phi)+Eth*cos(th)*cos(phi)-Ephi*sin(phi);
Ey = Erho*sin(th)*sin(phi)+Eth*cos(th)*sin(phi)+Ephi*cos(phi);
Ez = Erho*cos(th)-Eth*sin(th);


%% RATE OF CONVERGENCE OF MIXED FINITE ELEMENT METHOD IN 2D
%
% This example is to show the rate of convergence of mixed finite element
% (RT0-P0) approximation of the Poisson equation on the unit square:
%
% $$- \Delta u = f \; \hbox{in } (0,1)^2$$
%
% for the following boundary condition:
%
% # Pure Dirichlet boundary condition. $\Gamma _D = \partial \Omega$.
% # Pure Neumann boundary condition. $\Gamma _N = \partial \Omega$.
% # Mix Dirichlet and Neumann boundary condition. $u=g_D \hbox{ on }\Gamma_D,
% \quad \nabla u\cdot n=g_N \hbox{ on }\Gamma_N. \Gamma _N = \{(x,y): x=0,
% y\in [0,1]\}, \; \Gamma _D = \partial \Omega \backslash \Gamma _N$.
%
% Written by Ming Wang.

%%
clear all; close all;
[node,elem] = squaremesh([0,1,0,1],0.25);
pde = mixBCdata;
option.L0 = 2;
option.maxIt = 4;
option.printlevel = 1;
option.elemType = 'RT0-P0';
% option.solver = 'uzawapcg';
option.solver = 'dmg';

%% Pure Dirichlet boundary condition.
% option.plotflag = 0;
bdFlag = setboundary(node,elem,'Dirichlet');
mfemPoisson3(node,elem,pde,bdFlag,option);

%% Pure Neumann boundary condition.
% option.plotflag = 0;
bdFlag = setboundary(node,elem,'Neumann');
mfemPoisson(node,elem,pde,bdFlag,option);

%% Mix Dirichlet and Neumann boundary condition.
option.plotflag = 1;
option.solver = 'uzawapcg';
bdFlag = setboundary(node,elem,'Dirichlet','~(x==0)','Neumann','x==0');
mfemPoisson(node,elem,pde,bdFlag,option);

%% Conclusion
%
% The optimal rates of convergence for u and sigma are observed, namely,
% 1st order for L2 norm of u, L2 norm of sigma and H(div) norm of sigma.
% The 2nd order convergent rates between two discrete functions ||uI-uh||
% and ||sigmaI-sigmah|| are known as superconvergence.
%
% dmg and uzawapcg converges uniformly in all cases. Distributive MG is two
% times faster than uzawapcg.


function lattice_rule_test07 ( )

%*****************************************************************************80
%
%% LATTICE_RULE_TEST07 tests LATTICE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Ian Sloan, Stephen Joe,
%    Lattice Methods for Multiple Integration,
%    Oxford, 1994, page 18.
%
  dim_num = 2;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'LATTICE_RULE_TEST07\n' );
  fprintf ( 1, '  LATTICE applies a lattice rule to integrate\n' );
  fprintf ( 1, '  a function over the unit hypercube.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The spatial dimension DIM_NUM = %d\n', dim_num );
  fprintf ( 1, '  The lattice rule order M will vary.\n' );

  z(1:dim_num) = [ 1, 2 ];
  a(1:dim_num) = 0.0;
  b(1:dim_num) = 1.0;

  i4vec_print ( dim_num, z, '  The lattice generator vector:' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '         I         M    EXACT       ESTIMATE    ERROR\n' );
  fprintf ( 1, '\n' );

  for i = 1 : 10

    m = prime ( 3 * i );

    quad = lattice ( dim_num, m, z, @f_01_2d );

    exact = e_01_2d ( dim_num, a, b );

    error = abs ( exact - quad );

    fprintf ( 1, '  %8d  %8d  %10.6f  %10.6f  %10.6e\n', i, m, exact, quad, error );

  end

  return
end


% This is a demo for segmentation using local gaussian distribution (LGD)
% fitting energy
%
% Reference: <Li Wang, Lei He, Arabinda Mishra, Chunming Li.
% Active Contours Driven by Local Gaussian Distribution Fitting Energy.
% Signal Processing, 89(12), 2009,p. 2435-2447>
%
% Please DO NOT distribute this code to anybody.
% Copyright (c) by Li Wang
%
% Author:       Li Wang
% E-mail:       li_wang@med.unc.edu
% URL:          http://www.unc.edu/~liwa/
%
% 2010-01-02 PM

clc;clear all;close all;

Img=imread('1.bmp');
Img = double(Img(:,:,1));

NumIter = 300; %iterations
timestep=0.1; %time step
mu=0.1/timestep;% level set regularization term, please refer to "Chunming Li and et al. Level Set Evolution Without Re-initialization: A New Variational Formulation, CVPR 2005"
sigma = 3;%size of kernel
epsilon = 1;
c0 = 2; % the constant value
lambda1=1.0;%outer weight, please refer to "Chunming Li and et al,  Minimization of Region-Scalable Fitting Energy for Image Segmentation, IEEE Trans. Image Processing, vol. 17 (10), pp. 1940-1949, 2008"
lambda2=1.0;%inner weight
%if lambda1>lambda2; tend to inflate
%if lambda1<lambda2; tend to deflate
nu = 0.001*255*255;%length term
alf = 30;%data term weight

figure,imagesc(uint8(Img),[0 255]),colormap(gray),axis off;axis equal
[Height Wide] = size(Img);
[xx yy] = meshgrid(1:Wide,1:Height);
phi = (sqrt(((xx - 65).^2 + (yy - 40).^2 )) - 20);
phi = sign(phi).*c0;

Ksigma=fspecial('gaussian',round(2*sigma)*2 + 1,sigma); %  kernel
ONE=ones(size(Img));
KONE = imfilter(ONE,Ksigma,'replicate');
KI = imfilter(Img,Ksigma,'replicate');
KI2 = imfilter(Img.^2,Ksigma,'replicate');

figure,imagesc(uint8(Img),[0 255]),colormap(gray),axis off;axis equal,
hold on,[c,h] = contour(phi,[0 0],'r','linewidth',1); hold off
pause(0.5)

tic
for iter = 1:NumIter
    phi =evolution_LGD(Img,phi,epsilon,Ksigma,KONE,KI,KI2,mu,nu,lambda1,lambda2,timestep,alf);

    if(mod(iter,25) == 0)
        figure(2),
        imagesc(uint8(Img),[0 255]),colormap(gray),axis off;axis equal,title(num2str(iter))
        hold on,[c,h] = contour(phi,[0 0],'r','linewidth',1); hold off
        pause(0.02);
    end

end
toc


function g = gauss(x, m, P)

% GAUSS Gaussian distribution value
%   GAUSS(X, M, P) gives the probability density at point X, following a
%   Gaussian or Normal distribution with mean M and covariances matrix P.
%
%   For X vector, the evaluation happens at a single point denoted by X,
%   and the result is a positive scalar in the range [0 , 1].
%
%   For X matrix, the evaluation happens at each row of X, and the result
%   is a row-vector of scalars, one for each column of X.

%   Copyright 2013 Joan Sola

d = size(x,1);
n = size(x,2);
MD2 = zeros(1,n);

if (size(m,1) == d) && (size(P,1) == d) && (size(P,2) == d)

    z = x - repmat(m, 1, n);
    for i = 1:n
        MD2(1,i) = z(:,i)' * P^-1 * z(:,i);
    end
    a = sqrt((2*pi)^d * det(P));
    g = exp(-0.5 * MD2) / a;

else
    error ('Input sizes don''t match')
end

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   SLAMTB is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function pde = oscdiffdata3

pde = struct('f',1,'d',@d);

    function K =  d(p)  % Diffusion constant
    x = p(:,1); y = p(:,2); z = p(:,3);
    K = 2*(2+sin(10*pi*x).*cos(10*pi*y)*sin(20*pi*z));
    end
end


function showrateh3(h1,err1,k1,opt1,str1,h2,err2,k2,opt2,str2,h3,err3,k3,opt3,str3)
%% SHOWRATEH3 rate of two error sequences
%
% showrate3(N1,err1,k1,opt1,str1,N2,err2,k2,opt2,str2,N3,err3,k3,opt3,str3)
% plots the err1 vs N1, err2 vs N2, and err3 vs N3 in the loglog scale.
% Additional input
%
%   - k1, k2, k3: specify the starting indices; see showrate
%   - opt1, opt2, opt3: the line color and style
%   - str1, str2, str3: strings used in legend
%
% Example
%
% showrate2(N,energyErr,1,'r-+','||u-u_h||_A',...
%           N,L2Err,1,'b-+','||u-u_h||');
%
% See also showrate, showresult, showmesh, showsolution
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

N1 = 1./h1; N2 = 1./h2; N3 =1./h3;
if (nargin<=2)
    k1 = 1; opt1 = '-*';
end
r1 = showrate(N1,err1,k1,opt1);
hold on
r2 = showrate(N2,err2,k2,opt2);
r3 = showrate(N3,err3,k3,opt3);
h_legend = legend(str1,['C_1h^{' num2str(-r1) '}'],...
                  str2,['C_2h^{' num2str(-r2) '}'],...
                  str3,['C_3h^{' num2str(-r3) '}'],'LOCATION','Best');
set(h_legend,'FontSize',12);
xlabel('log(1/h)');


function [idx, dist]=closestnode(node,p)
%
% [idx, dist]=closestnode(node,p)
%
% Find the closest point in a node list and return its index

% author: Qianqian Fang (q.fang at neu.edu)
%
% input:
%    node: each row is an N-D node coordinate
%    p: a given position in the same space
%
% output:
%    idx: the index of the position in the node list that has the shortest
%         Euclidean distance to the position p
%    dist: the distances between p and each node
%
%
% -- this function is part of brain2mesh toolbox (http://mcx.space/brain2mesh)
%    License: GPL v3 or later, see LICENSE.txt for details
%

dd=node-repmat(p,size(node,1),1);
[dist,idx]=min(sum(dd.*dd,2));


% program demo_tutor.m
%
% P.M.T. Broersen, July 2004
%                  June 2005
% P.M.T. Broersen, November 2007

% see also demo_armasa for extensive example
%          demo_simple for basic example PSD and autocorrelation computation
%
%   Background information can be found in

%   Book:
%   Piet M.T. Broersen
%   Automatic Autocorrelation and Spectral Analysis
%   Springer-Verlag,London, 2006.
%   ISBN 1-84628-328.

%   Journal paper:
%   P. M. T. Broersen, Automatic Spectral Analysis with
%   Time Series Models, IEEE Transactions on Instrumentation
%   and Measurement, Vol. 51, No. 2, April 2002, pp. 211-216.
%
%   and many papers given in ARMASA info.txt

clc,
close all
clear all
echo on

% Generate stationary AR en MA polynomials a and b from reflection coefficients smaller than 1
% By taking reflection coefficients between -1 and +1, stationary invertible
% models are guaranteed with all poles and zeros inside the unit circle
% Reflection coefficients are transformed into parameters with rc2arset:
%

a = rc2arset([1 .3 .3])

b = rc2arset([1 -.9])

% From reflection coefficients to parameters and vice versa
[dum rc] = ar2arset(a)

N = 500;

% Generating data by starting with initial zeros is a poor idea.
% Simuarma generates N stationary data, with the asymptotical properties
% applicable from the first observation

data = simuarma(a,b,N);

% Compute and select time series models,
% with asel and bsel as parameters of the selected model
% Compute the accuracy of the selected model type and the best alternative
% model types and put them in sellog

[asel bsel sellog] = armasel(data)

% Compute the accuracy of the estimated model in comparison with
% the true process with the parameters a and b

ME = moderr(asel,bsel,a,b,N)

% Compute and plot the autocorrelation functions and spectra of the
% generating true model and the ARMAsel selected model.
% gain is the power gain or the ratio between output and input variance of ARMA process
% The length of the correlation function is chosen as 50.
%
[cortrue gain] = arma2cor(a,b,50);
corsel = arma2cor(asel,bsel,50);
[psdtrue fas] = arma2psd(a,b);
psdsel = arma2psd(asel,bsel);

echo off

figure(1),
plot(data),
xlabel('\rightarrow time axis [s]')
title([int2str(N),' ARMA(2,1) observations'])

figure(2),
plot(0:50,cortrue,0:50,corsel,'r')
title('True and estimated autocorrelation function')
xlabel('\rightarrow time lag [s]')
legend('true','estimated')

figure(3),
subplot(121),
plot(fas,psdtrue,fas,psdsel,'r')
title('True and estimated spectrum')
xlabel('\rightarrow normalized frequency \it{f/f_s}'),
legend('true','estimated',2)
ylabel('Lineair scale for PSD'),
axis tight
subplot(122),
semilogy(fas,psdtrue,fas,psdsel,'r')
title('True and estimated spectrum')
xlabel('\rightarrow normalized frequency \it{f/f_s}'),
legend('true','estimated',4)
ylabel('Log scale for PSD'),
axis tight,
subplot,

figure(4),
echo on

% The spectra on a linear scale are hardly to discern for high frequencies.
% That improves with a logaritmic scale.
% The frequency axis is between 0 and fs/2, where fs is the sampling frequency.
% Very often, fs is taken as 1 without mentioning it.
%
% Investigate the accuracy as estimated by ARMAsel for all models
% That accuracy is stored in sellog in pe_est files
% The accuracy of all models can be interpreted as the language of random data
%
% This example demonstrates how axis can be generated automatically for a
% properly scaled plot of the prediction errors
%
plot(sellog.ar.cand_order,sellog.ar.pe_est)
title('Estimated model accuracies as a function of model order and type')
xlabel('\rightarrow model order \itr')
ylabel('\rightarrow normalized model accuracy')
minar=min(sellog.ar.pe_est);
as2=axis;
as2(3)=.9*minar;
as2(4)=sellog.ar.pe_est(end);
axis(as2);
hold on,
plot(sellog.ma.cand_order,sellog.ma.pe_est,'r')
plot(sellog.arma.cand_ar_order,sellog.arma.pe_est,'g')
legend('AR(\itr\rm)','MA(\itr\rm)','ARMA(\itr,r\rm-1)',4),
hold off,

% A similar result in one line can be obtained with plotpe(sellog),
% where sellog is the third output argument of armasel

plotpe(sellog)

% Retrieve the reflection coefficients of the longest AR model that has been used in ARMAsel
% The longest AR model is allways saved as ASAglob_rc!!
%
% Recent versions of ARMASA (after 2008) save that model additionally as sellog.ar.rcarlong
%
rcarlong = ASAglobretr('ASAglob_rc');

% Determine the highest AR order that has been estimated with ARMAsel.
% Transform reflection coefficients rcarlong into a parameter vector.
% Plot spectrum (PSD) and autocorrelation function of selected and of long model.
%
% The correlation function and the PSD of the long model arlong
% are very irregular.
% Selection of the model order and type gives results with only
% statisatically significant details included.
%
maximum_order = length(rcarlong)-1
arlong = rc2arset(rcarlong);
corlang = arma2cor(arlong,1,50);
psdlang = arma2psd(arlong,1); echo off

% In arma2cor and arma2psd, 1 is used as the second parameter vector.
% That is the MA vector for true AR processes.
% The programs expect both an AR and a MA parameter vector.
% The first element of the parameter vector must always be 1.
% That can be the only parameter of the vector.

figure,
plot(0:50,cortrue,0:50,corsel,0:50,corlang)
title('True and estimated autocorrelation function')
xlabel('\rightarrow time lag [s]'),
legend('true','estimated','ARlong')

% Linear and logarithmic spectra of the same data demonstrate a strong
% preference for logarithmic plots of the PSD (power spectral density)

figure,
subplot(121),
plot(fas,psdtrue,fas,psdsel,fas,psdlang)
title('True and estimated spectrum')
xlabel('\rightarrow normalized frequency \it{f/f_s}'),
legend('true','estimated','ARlong',2)
ylabel('Linear scale for PSD'),
axis tight
subplot(122),
semilogy(fas,psdtrue,fas,psdsel,fas,psdlang)
title('True and estimated spectrum')
xlabel('\rightarrow normalized frequency \it{f/f_s}'),
legend('true','estimated','ARlong',4)
ylabel('Log scale for PSD'),
axis tight,
subplot

echo on

% Demo of variation of input variables for candidate orders
% Computation of models with prescribed type and order
%
echo off
disp('AR(10) with ar10 = armasel(data,10,0,0)')
ar10 = armasel(data,10,0,0),           % AR(10)
disp(' ')
disp('AR selected from orders between 2 and 20 with arselect= armasel(data,2:20,0,0)')
arselect = armasel(data,2:20,0,0),    % AR(selected between candidate orders 2 and 20)
disp(' ')
disp('AR(10) with ar10fromarlong = rc2arset(rcarlong,10)')
ar10fromarlong = rc2arset(rcarlong,10) % AR(10) computed with first 10 reflection coefficients
disp(' ')
disp('MA(6) model with ma6 = armasel(data,0,6,0)')
[dummy ma6] = armasel(data,0,6,0),     % MA(6)
disp(' ')
disp('ARMA(2,1) model with  armasel(data,0,0,2)')
[ar2 ma1] = armasel(data,0,0,2),       % ARMA(2,1)
disp(' ')
disp('ARMA(4,3) model with  armasel(data,0,0,4)')
[ar4 ma3] = armasel(data,0,0,4),       % ARMA(4,3)
disp(' ')
disp('Selection between candisdates AR(2), MA(3) and ARMA(5,4) with  armasel(data,2,3,5)')
[arx brx] = armasel(data,2,3,5)        % selects between the candidates AR(2), MA(3) and ARMA(5,4)
disp(' ')

% Accuracy of these models and of the selected model

disp(['ARMAsel selected from all candidates for N = ',int2str(N),' observations: ARMA(', ...
    int2str(length(asel)-1),',',int2str(length(bsel)-1),')'])
ME_selected = moderr(asel,bsel,a,b,N)
ME_ar10 = moderr(ar10,1,a,b,N)
ME_ma6 = moderr(1,ma6,a,b,N)
ME_arma21 = moderr(ar2,ma1,a,b,N)
ME_arma43 = moderr(ar4,ma3,a,b,N)
ME_arlong = moderr(arlong,1,a,b,N)

echo on,

% Prediction of the observations after the data with the selected model with arma2pred
% Lpred is the prediction horizon
% Normalizing the accuracy with the power gain
% Take care because the mean has been subtracted automatically,
% it should be added again for a correct prediction of the future
% pred_acc is the variance of the predictions
% asel and bsel have been found before with armasel in line 35
%
Lpred = 15
[pred pred_acc] = arma2pred(asel,bsel,data,Lpred);
[corsel gainsel]= arma2cor(asel,bsel)
pred_acc = pred_acc*std(data)^2/gainsel; echo off

figure,
plot(0:Lpred,[data(end) pred+mean(data)],'r*',1:Lpred, ...
    pred+1.96*sqrt(pred_acc)+mean(data),1:Lpred,pred-1.96*sqrt(pred_acc)+mean(data))
title('Prediction for \it{t > N} \rmof continuation of data \it{x_n}\rm , with 95 % confidence interval')
xlabel('\rightarrow Prediction starting with the last observation \it{x_N} \rmof the data')

echo on,

%
% Using reduced statistics
%
% REDUCED STATISTICS REDUCED STATISTICS REDUCED STATISTICS REDUCED STATISTICS
%_____________________________________________________________________________
%
% Computes the best model for the data if only a long AR model is available
% and the sample size N of the observations that were used to compute the long AR model
% Generally, there is a only small difference between ARMA models estimated from data and
% ARMA models estimated with reduced statistics.
%
%
% S. de Waele
% Automatic Spectral Analysis,
% This and more extensions of ARMASA can be found under
% spectral analysis at the download address
% http: www.mathworks.com/matlabcentral/fileexchange/

% Also programs for equidistant data where some data are missing can be
% found and programs for irregular data, all at various places in
% http: www.mathworks.com/matlabcentral/fileexchange/
% by the authors Piet Broersen and Stijn de Waele
%
% An error message can be found if the additional software is not down loaded
%
echo off

try
    disp('The model selected from armasel applied to the data was')
    asel
    bsel
    disp(' ')
    disp('    [asel_rs bsel_rs sellog_rs] = armasel_rs(arlong,N)  gives:')
    disp(' ')
    [asel_rs bsel_rs sellog_rs] = armasel_rs(arlong,N)
    disp(' ')
    disp('   The accuracy of the selected reduced statistics model')
    ME_rs = moderr(asel_rs,bsel_rs,a,b,N)
    disp(' ')
    disp('  The difference between the selected data model and the reduced statistics model')
    ME_dif = moderr(asel_rs,bsel_rs,asel,bsel,N)

    disp(' ')
    disp(' Computation of the ARMA(3,2) model with the reduced statistics algorithm')
    disp(' ')
    [a_rs b_rs sellog32_rs] = armasel_rs(arlong,N,0,0:1,3) %ARMA(3,2)
    disp(' ')
    disp('   The accuracy of the ARMA(3,2) model')
    ME_arma32_rs = moderr(a_rs,b_rs,a,b,N)

    % some care is required for giving a fixed MA or ARMA order in armasel_rs
    % using only candidate order 0 might give error messages
    % the example shows how those messages are suppressed
catch
    disp(' The program armasel_rs requires additional software of Stijn de Waele')
    disp(' Automatic Spectral Analysis')
    disp(' This can be found under spectral analysis at the download address')
    disp(' http: www.mathworks.com/matlabcentral/fileexchange/')
end


function point_num = sparse_grid_f2s_size ( dim_num, level_max )

%*****************************************************************************80
%
%% SPARSE_GRID_F2S_SIZE sizes a sparse grid using Fejer Type 2 Slow rules.
%
%  Discussion:
%
%    The grid is defined as the sum of the product rules whose LEVEL
%    satisfies:
%
%      0 <= LEVEL <= LEVEL_MAX.
%
%    This calculation is much faster than a previous method.  It simply
%    computes the number of new points that are added at each level in the
%    1D rule, and then counts the new points at a given DIM_NUM dimensional
%    level vector as the product of the new points added in each dimension.
%
%    This approach will work for nested families, and may be extensible
%    to other families, and to mixed rules.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 December 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Fabio Nobile, Raul Tempone, Clayton Webster,
%    A Sparse Grid Stochastic Collocation Method for Partial Differential
%    Equations with Random Input Data,
%    SIAM Journal on Numerical Analysis,
%    Volume 46, Number 5, 2008, pages 2309-2345.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer LEVEL_MAX, the maximum value of LEVEL.
%
%    Output, integer POINT_NUM, the total number of unique
%    points in the grids.
%

%
%  Special case.
%
  if ( level_max < 0 )
    point_num = 0;
    return
  end

  if ( level_max == 0 )
    point_num = 1;
    return
  end
%
%  Construct the vector that counts the new points in the 1D rule.
%
  new_1d = zeros ( level_max+1, 1 );

  new_1d(0+1) = 1;

  p = 1;
  o = 1;

  for l = 1 : level_max
    p = 2 * l + 1;
    if ( o < p )
      new_1d(l+1) = o + 1;
      o = 2 * o + 1;
    else
      new_1d(l+1) = 0;
    end
  end
%
%  Count the number of points by counting the number of new points
%  associated with each level vector.
%
  level_1d = zeros ( dim_num, 1 );

  point_num = 0;

  for level = 0 : level_max

    more = 0;
    h = 0;
    t = 0;

    while ( 1 )

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

      point_num = point_num + prod ( new_1d(level_1d(1:dim_num)+1) );

      if ( ~more )
        break
      end

    end

  end

  return
end


function himmelblau_test ( )

%*****************************************************************************80
%
%% HIMMELBLAU_TEST works with the Himmelblau function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HIMMELBLAU_TEST:\n' );
  fprintf ( 1, '  Test COMPASS_SEARCH with the Himmelblau function.\n' );
  m = 2;
  delta_tol = 0.00001;
  delta = 0.3;
  k_max = 20000;

  x = [ 1.0, 1.0 ];
  r8vec_print ( m, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', himmelblau ( m, x ) );

  [ x, fx, k ] = compass_search ( @himmelblau, m, x, delta_tol, delta, k_max );
  r8vec_print ( m, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g, number of steps = %d\n', fx, k );

  x = [ -1.0, 1.0 ];
  r8vec_print ( m, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', himmelblau ( m, x ) );

  [ x, fx, k ] = compass_search ( @himmelblau, m, x, delta_tol, delta, k_max );
  r8vec_print ( m, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g, number of steps = %d\n', fx, k );

  x = [ -1.0, -1.0 ];
  r8vec_print ( m, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', himmelblau ( m, x ) );

  [ x, fx, k ] = compass_search ( @himmelblau, m, x, delta_tol, delta, k_max );
  r8vec_print ( m, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g, number of steps = %d\n', fx, k );

  x = [ 1.0, -1.0 ];
  r8vec_print ( m, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', himmelblau ( m, x ) );

  [ x, fx, k ] = compass_search ( @himmelblau, m, x, delta_tol, delta, k_max );
  r8vec_print ( m, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g, number of steps = %d\n', fx, k );
%
%  Demonstrate Himmelblau minimizers.
%
  x = [ 3.0, 2.0 ];
  r8vec_print ( m, x, '  Correct Himmelblau minimizer X1*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', himmelblau ( m, x ) );

  x = [ 3.58439, -1.84813 ];
  r8vec_print ( m, x, '  Correct Himmelblau minimizer X2*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', himmelblau ( m, x ) );

  x = [ -3.77934, -3.28317 ];
  r8vec_print ( m, x, '  Correct Himmelblau minimizer X3*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', himmelblau ( m, x ) );

  x = [ -2.80512,  3.13134 ];
  r8vec_print ( m, x, '  Correct Himmelblau minimizer X4*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', himmelblau ( m, x ) );

  return
end


% QQDIAGRAM - Empirical quantile-quantile diagram.
%
% Description:
%               The quantiles (percentiles) of the input distribution Y are plotted (Y-axis)
%               against the corresponding quantiles of the input distribution X.
%               If only X is given, the corresponding quantiles are plotted (Y-axis)
%               against the quantiles of a Gaussian distribution ('Normal plot').
%               Two black dots indicate the lower and upper quartiles.
%               If the data in X and Y belong the same distribution the plot will be linear.
%               In this case,the red and black reference lines (.-.-.-.-) will overlap.
%               This will be true also if the data in X and Y belong to two distributions with
%               the same shape, one distribution being rescaled and shifted with respect to the
%               other.
%               If only X is given, a line is plotted to indicate the mean of X, and a segment
%               is plotted to indicate the standard deviation of X. If the data in X are normally
%               distributed, the red and black reference lines (.-.-.-.-) will overlap.
%
% Usage:
%   >>  ah  =  qqdiagram( x, y, pk );
%
% Inputs:
%   x       - vector of observations
%
% Optional inputs:
%   y       - second vector of observation to compare the first to
%   pk      - the empirical quantiles will be estimated at the values in pk [0..1]
%
% Author: Luca Finelli, CNL / Salk Institute - SCCN, 20 August 2002
%
% Reference: Stahel W., Statistische Datenanalyse, Vieweg, Braunschweig/Wiesbaden, 1995
%
% See also:
%   QUANTILE, SIGNALSTAT, EEGLAB

% Copyright (C) 2002 Luca Finelli, Salk/SCCN, La Jolla, CA
%
% Reference: Stahel, W. Statistische Datenanalyse, Vieweg, Braunschweig/Wiesbaden 1995
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% 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 HOLDER 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.

function qqdiagram( x , y, pk )

if nargin < 1
	help qqdiagram;
	return;
end;

if (nargin == 3 && (any(pk > 1) || any(pk < 0)))
    error('qqdiagram(): elements in pk must be between 0 and 1');
end

if nargin==1
	y=x;
	nn=max(1000,10*length(y))+1;
	x=randn(1,nn);
end

if nargin < 3
	nx=sum(~isnan(x));
	ny=sum(~isnan(y));
   	k=min(nx,ny);
    pk=((1:k) - 0.5) ./ k;  % values to estimate the empirical quantiles at
else
    k=length(pk);
end

if nx==k
    xx=sort(x(~isnan(x)));
else
    xx=quantile(x(~isnan(x)),pk);
end

if ny==k
    yy=sort(y(~isnan(y)));
else
    yy=quantile(y(~isnan(y)),pk);
end

% QQ diagram
plot(xx,yy,'+')
hold on

% x-axis range
maxx=max(xx);
minx=min(xx);
rangex=maxx-minx;
xmin=minx-rangex/50;
xmax=maxx+rangex/50;

% Quartiles
xqrt1=quantile(x,0.25); xqrt3=quantile(x,0.75);
yqrt1=quantile(y,0.25); yqrt3=quantile(y,0.75);

plot([xqrt1 xqrt3],[yqrt1 yqrt3],'k-','LineWidth',2); % IQR range

% Drawing the line
sigma=(yqrt3-yqrt1)/(xqrt3-xqrt1);
cy=(yqrt1 + yqrt3)/2;

if nargin ==1
    maxy=max(y);
    miny=min(y);
    rangey=maxy-miny;
	ymin=miny-rangey/50;
	ymax=maxy+rangey/50;

	plot([(miny-cy)/sigma (maxy-cy)/sigma],[miny maxy],'r-.') % the line
    % For normally distributed data, the slope of the plot line
    % is equal to the ratio of the standard deviation of the distributions
	plot([0 (maxy-mean(y))/std(y)],[mean(y) maxy],'k-.') % the ideal line

	xlim=get(gca,'XLim');
	plot([1 1],[ymin  mean(y)+std(y)],'k--')
	plot([1 1],[mean(y)  mean(y)+std(y)],'k-','LineWidth',2)
        % textx = 1.0;
        % texty = mean(y)+3.0*rangey/50.0;
	% text(double(textx), double(texty),' St. Dev.','horizontalalignment','center')
    set(gca,'xtick',get(gca,'xtick'));  % show that vertical line is at 1 sd
	plot([0 0],[ymin  mean(y)],'k--')
	plot(xlim,[mean(y) mean(y)],'k--')
	% text(double(xlim(1)), double(mean(y)+rangey/50),'Mean X')
	plot([xqrt1  xqrt3],[yqrt1 yqrt3],'k.','MarkerSize',10)
	set(gca,'XLim',[xmin xmax],'YLim',[ymin ymax])
	xlabel('Standard Normal Quantiles')
	ylabel('X Quantiles')
else
    cx=(xqrt1 + xqrt3)/2;
    maxy=cy+sigma*(max(x)-cx);
	miny=cy-sigma*(cx-min(x));

	plot([min(x) max(x)],[miny maxy],'r-.'); % the line
    xlabel('X Quantiles');
    ylabel('Y Quantiles');
end


function det = r8po_det ( n, a_lu )

%*****************************************************************************80
%
%% R8PO_DET computes the determinant of a matrix factored by R8PO_FA.
%
%  Discussion:
%
%    The R8PO storage format is appropriate for a symmetric positive definite
%    matrix and its inverse.  (The Cholesky factor of a R8PO matrix is an
%    upper triangular matrix, so it will be in R8GE storage format.)
%
%    Only the diagonal and upper triangle of the square array are used.
%    This same storage scheme is used when the matrix is factored by
%    R8PO_FA, or inverted by R8PO_INVERSE.  For clarity, the lower triangle
%    is set to zero.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 March 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A_LU(N,N), the LU factors from R8PO_FA.
%
%    Output, real DET, the determinant of A.
%
  det = 1.0E+00;

  for i = 1 : n
    det = det * a_lu(i,i);
  end

  return
end


function y = quadcc(fun,a,b,tol)
%QUADCC   Numerical integration using Clenshaw-Curtis quadrature.
%   Y = QUADCC(FUN,A,B) estimates the definite integral of the
%   function FUN from A to B, using an adaptive Clenshaw-Curtis
%   quadrature scheme.  FUN is either a MATLAB expression written
%   as a string or inline function, or a function M-file.  A and
%   B are the lower and upper limits of integration, respectively.
%
%   QUADCC computes the integral by recursively dividing the interval
%   (A,B) into finer subintervals, defined by the zero-points of the
%   Type 1 Chebyshev polynomials.  The recursion continues until
%   either (1) the difference between computed estimates of the
%   integral in successive recursion steps falls below a tolerance
%   (default TOL = 1e-6), or (2) the integral domain has been
%   divided into 1024 subintervals.  A warning is returned if the
%   maximum number of subintervals is reached before the tolerance
%   criterion is met.
%   Y = QUADCC(FUN,A,B,TOL) uses the supplied value of TOL instead
%   of the default.
%
%   QUADCC provides limited handling of certain types of improper
%   integral.  If the integrand has a pole at one (or both) of the
%   integration limits, QUADCC returns a warning and attempts to
%   evaluate the integral by shifting the integration limit a
%   distance EPS inside the integration interval.  If QUADCC
%   encounters a pole inside the integration interval, an error is
%   produced.
%
%   Examples:
%
%       1) String expression
%            Y = quadcc('1./(x.^2-5)',-1,2)
%
%       2) Inline function
%            foo = inline('x.*sin(x)')
%            Y = quadcc(foo,0,2*pi)
%
%       3) Function M-file
%            Y = quadcc(@foo,0,1)
%            with foo.m a function M-file:
%
%            function y = foo(x)
%            y = tan(x);
%
%   See also  QUAD, QUADL, DBLQUAD, TRIPLEQUAD, INLINE

%   References
%   ----------
%   "Numerical Recipes in C. The Art of Scientific Computing, 2nd edition".
%   W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery.
%   Cambridge Unversity Press, 2002.

% Paul Fricker  12/09/2002

if a==b
    y = 0;
    return
end

if ~exist('tol')
    tol = 1e-6;
end

% Make sure 'fun' is an inline function
f = fcnchk(fun);

% Initialize by breaking the integration interval into four regions.
N = 4;
p = (b+a)/2;
q = (b-a)/2;
% Write out [ cos((0:4)/4*pi) ] explicitly to avoid cos(pi/2) roundoff
x = p-q*[1 0.7071067811865475 0 -0.7071067811865475 -1];
F = feval(f,x);

% Simple attempt to handle improper integral
if isinf(F(1))
    F(1) = feval(f,x(1)+eps);
    warning('QUADCC:improperLower', ...
            ['Improper integral: Integrand has pole ' ...
             'at lower integration limit.'])
end

if isinf(F(5))
    F(5) = feval(f,x(5)-eps);
    warning('QUADCC:improperUpper', ...
            ['Improper integral: Integrand has pole ' ...
             'at upper integration limit.'])
end

% Modify the first and last terms of 'F'.
F(1) = F(1)/2;
F(end) = F(end)/2;

% Call the integrator function recursively
[y,warn] = intcc(f,x,F,N,p,q,tol,Inf);

if warn==1
    warning('QUADCC:MaxSubDivide', ...
            ['Computation terminated before tolerance criterion (TOL = ' num2str(tol) ') was met.'])
end

% EOF 'quadcc'

function [y,warn] = intcc(f,x,F,N,p,q,tol,yinit)
% INTCC Recursive integrator function for the QUADCC routine.
%
% Input parameters:
% f     : Integrand
% x     : Chebyshev polynomial zero-points between the integration limits (a,b)
% F     : Values of 'f' evaluated at 'x'
% N     : Initial number of zero-points ('discretization')
% p,q   : Endpoint parameters (from integration limits)
% tol   : Integration tolerance (terminates the recursion)
% yinit : Estimated value of the integral from the previous pass

% Terminate recursion if integral has not converged before 1024 points
if size(x,2) > 2^10
    warn = 1;
    y = yinit;
    return
else
    warn = 0;
end

% Double the size of the approximation
N = 2*N;
Nvec = 0:N;

x2 = zeros(1,N+1);
x2(1:2:end) = x;
x2(2:2:end) = p-q*cos((1:2:N)/N*pi);

G = zeros(1,N+1);
G(1:2:end) = F;
G(2:2:end) = feval(f,x2(2:2:end));
G = G(:);

if any(isinf(G))
    error('Improper integral: Integrand has a pole between integration limits.')
end

% Evaluate the Chebyshev polynomial coefficients for
% approximating the input function 'f'
M = cos(Nvec(1:2:end-1)'*Nvec/N*pi);
M(abs(M)<eps) = 0;
C = 4/N*M*G;

% Compute the quadrature coefficients
coeffs = -1./Nvec(2:2:end)./(Nvec(2:2:end)-2);
coeffs(1) = 0.5;

% Compute the integral estimate
y = q*coeffs*C;

% Continue recursion if the difference between the current value
% of the integral and the previous value is still above 'tol'.
if abs(y-yinit) > tol
    [y,warn] = intcc(f,x2,G,N,p,q,tol,y);
end

% EOF 'intcc'


%  演示调用 LU 分解的紧凑方式
clear;
A=[1 2 3; 2 5 2; 3 1 5];
b=[14;18;20];

% LU三角分解法
[L, U, x] = my_lu(A, b)

% 列主元LU三角分解法
%[L, U, x] = my_lu_with_column_pivoting(A, b)

% 直接调用matlab左除运算符
x_ = A\b


function value = f1sd1 ( x )

%*****************************************************************************80
%
%% F1SD1 evaluates the function 1.0D+00/ sqrt ( 1.1 - x**2 ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 January 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the function.
%
%    Output, real VALUE, the value of the function.
%
  f1sd1 = 1.0 / sqrt ( 1.1 - x * x );

  return
end


function [ a_lu, pivot, info ] = r8ge_fa ( n, a )

%*****************************************************************************80
%
%% R8GE_FA performs a LINPACK style PLU factorization of an R8GE matrix.
%
%  Discussion:
%
%    The R8GE storage format is used for a general M by N matrix.  A storage
%    space is made for each logical entry.  The two dimensional logical
%    array is mapped to a vector, in which storage is by columns.
%
%    This is a simplified version of the LINPACK routine DGEFA.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Dongarra, Bunch, Moler, Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%    N must be positive.
%
%    Input, real A(N,N), the matrix to be factored.
%
%    Output, real A_LU(N,N), an upper triangular matrix and
%    the multipliers used to obtain it.  The factorization
%    can be written A = L * U, where L is a product of
%    permutation and unit lower triangular matrices and U
%    is upper triangular.
%
%    Output, integer PIVOT(N), a vector of pivot indices.
%
%    Output, integer INFO, singularity flag.
%    0, no singularity detected.
%    nonzero, the factorization failed on the INFO-th step.
%
  a_lu(1:n,1:n) = a(1:n,1:n);

  info = 0;

  for k = 1 : n-1
%
%  Find L, the index of the pivot row.
%
    l = k;
    for i = k+1 : n
      if ( abs ( a_lu(l,k) ) < abs ( a_lu(i,k) ) )
        l = i;
      end
    end

    pivot(k) = l;
%
%  If the pivot index is zero, the algorithm has failed.
%
    if ( a_lu(l,k) == 0.0 )
      info = k;
      fprintf ( 1, '\n' );
      fprintf ( 1, 'R8GE_FA - Fatal error!\n' );
      fprintf ( 1, '  Zero pivot on step %d\n', info );
      return;
    end
%
%  Interchange rows L and K if necessary.
%
    if ( l ~= k )
      t         = a_lu(l,k);
      a_lu(l,k) = a_lu(k,k);
      a_lu(k,k) = t;
    end
%
%  Normalize the values that lie below the pivot entry A(K,K).
%
    a_lu(k+1:n,k) = -a_lu(k+1:n,k) / a_lu(k,k);
%
%  Row elimination with column indexing.
%
    for j = k+1 : n

      if ( l ~= k )
        t         = a_lu(l,j);
        a_lu(l,j) = a_lu(k,j);
        a_lu(k,j) = t;
      end

      a_lu(k+1:n,j) = a_lu(k+1:n,j) + a_lu(k+1:n,k) * a_lu(k,j);

    end
  end

  pivot(n) = n;

  if ( a_lu(n,n) == 0.0 )
    info = n;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8GE_FA - Fatal error!\n' );
    fprintf ( 1, '  Zero pivot on step %d\n', info );
    return;
  end

  return
end


function  [M,mv,alpha,unA] = ...
           select_taylor_degree(A,b,m_max,p_max,prec,shift,bal,force_estm)
%SELECT_TAYLOR_DEGREE   Select degree of Taylor approximation.
%   [M,MV,alpha,unA] = SELECT_TAYLOR_DEGREE(A,m_max,p_max) forms a matrix M
%   for use in determining the truncated Taylor series degree in EXPMV
%   and EXPMV_TSPAN, based on parameters m_max and p_max.
%   MV is the number of matrix-vector products with A or A^* computed.

%   Reference: A. H. Al-Mohy and N. J. Higham, Computing the action of
%   the matrix exponential, with an application to exponential
%   integrators. MIMS EPrint 2010.30, The University of Manchester, 2010.

%   Awad H. Al-Mohy and Nicholas J. Higham, October 26, 2010.

if nargin < 8, force_estm = false; end
if nargin < 4 || isempty(p_max), p_max = 8; end
if nargin < 3 || isempty(m_max), m_max = 55; end

if p_max < 2 || m_max > 60 || m_max + 1 < p_max*(p_max - 1)
    error('>>> Invalid p_max or m_max.')
end
n = length(A);
if nargin < 7 || isempty(bal), bal = false; end
if bal
    [D B] = balance(A);
    if norm(B,1) < norm(A,1), A = B; end
end
if nargin < 5 || isempty(prec), prec = class(A); end
switch prec
    case 'double'
        load theta_taylor
    case 'single'
        load theta_taylor_single
    case 'half'
        load theta_taylor_half
end
if shift
    mu = trace(A)/n;
    A = A-mu*speye(n);
end
mv = 0;
if ~force_estm, normA = norm(A,1); end

if ~force_estm && normA <= 4*theta(m_max)*p_max*(p_max + 3)/(m_max*size(b,2));
% if true
    % Base choice of m on normA, not the alpha_p.
    unA = 1;
    c = normA;
    alpha = c*ones(p_max-1,1);
else
    unA = 0;
    eta = zeros(p_max,1); alpha = zeros(p_max-1,1);
    for p = 1:p_max
        [c,k] = normAm(A,p+1);
        c = c^(1/(p+1));
        mv = mv + k;
        eta(p) = c;
    end
    for p = 1:p_max-1
        alpha(p) = max(eta(p),eta(p+1));
    end
end
M = zeros(m_max,p_max-1);
for p = 2:p_max
    for m = p*(p-1)-1 : m_max
        M(m,p-1) = alpha(p-1)/theta(m);
    end
end


% This program obtains the analytical step response of a parallel RLC
% circuit. In addition, graphs of the voltage across the parallel
% combination and branch currents are obtained.
% H. Saadat, Copyright 1999

function PresponseIR
warning('off','MATLAB:dispatcher:InexactMatch')
Rhandle=findobj('Tag','Rtext');
R=eval(get(Rhandle,'String'));
KOhandle=findobj('Tag','KOhm');
KO=get(KOhandle,'Value');
if KO==1
   R=1000*R;
else, end
Lhandle=findobj('Tag','Ltext');
L=eval(get(Lhandle,'String'));
mHhandle=findobj('Tag','mHenry');
ml=get(mHhandle,'Value');
if ml==1
   L=L/1000;
else, end
Chandle=findobj('Tag','Ctext');
C=eval(get(Chandle,'String'));
micFhandle=findobj('Tag','micFarad');
micF=get(micFhandle,'Value');
if micF==1
   C=C/1000000;
else, end
Rhandle=findobj('Tag','IStext');
Is=eval(get(Rhandle,'String'));
Rhandle=findobj('Tag','I0text');
I0=eval(get(Rhandle,'String'));
Rhandle=findobj('Tag','V0text');
V0=eval(get(Rhandle,'String'));
% Step Response of a parallel RLC circuit
if L==inf | C==inf
   plot(0, 0)
   text(-0.8, 0.80, 'Parameters must lie in the following ranges:', 'color', [0 0 0.6275])
   text(-0.8, 0.65, '0 < R \leq inf,   0 < L < inf,   &    0 < C < inf', 'color', [0 0 0.6275])
   text(-0.8, 0.5, 'Enter the correct value and press Solve', 'color', [0 0 0.6275])
   axis([-1  1  -1  1]);return,  else
end
if R==0 | L==0 | C == 0
plot(0, 0)
title('Short-circuit across the parallel circuit', 'color', [ 1 0 0])
text(-0.8, 0.80, 'Parameters must lie in the following ranges:', 'color', [0 0 0.6275])
text(-0.8, 0.65, '0 < R \leq inf,   0 < L < inf,   &    0 < C < inf', 'color', [0 0 0.6275])
text(-0.8, 0.5, 'Enter the correct value and press Solve', 'color', [0 0 0.6275])
axis([-1  1  -1  1]);return,  else
alpha =1/(2*R*C);
end
w02 = 1/(L*C); w0 = sqrt(w02);
if alpha~= 0
   err=(alpha-w0)/alpha;
   if abs(err) <1e-4
   w0=alpha;
   else, end
else, end
dv = Is/C-I0/C-V0/(R*C);
di = V0/L;
if alpha > w0
 % Overdamped response
    s(1) = -alpha + sqrt(alpha^2 - w02);
    s(2) = -alpha - sqrt(alpha^2 - w02);
    A1 = (dv-s(2)*V0)/(s(1)-s(2));
    A2 = (dv-s(1)*V0)/(s(2)-s(1));
    A1i =(di-s(2)*(I0-Is))/(s(1)-s(2));
    A2i =(di-s(1)*(I0-Is))/(s(2)-s(1));
    tf = 6*max(abs(1/s(1)), abs(1/s(2)));
    t=0:tf/100:tf;
    v = A1*exp(s(1)*t)+A2*exp(s(2)*t);
    iL=Is + A1i*exp(s(1)*t)+A2i*exp(s(2)*t);
    iR = v/R;
    iC= Is -iR-iL;
    it=iR+iL+iC;
    plot(t,iR,'erasemode','none','color',[0.9 0 0.8]), grid
    title(['i_R(t) =(', num2str(A1/R), ') e^{(', num2str(s(1)), 't)} + (', num2str(A2/R), ') e^{(', num2str(s(2)), 't)}'],'color',[0.9 0 0.8])
    xlabel(['\alpha = ',num2str(alpha), ',  \omega_0 = ',  num2str(w0), '  (O.D.)          t, sec'])
    ylabel('i_R(t), Amps')
    elseif alpha < w0
     if alpha~=0
      % Underdamped response
      tf = 6/alpha;
      t=0:tf/200:tf;
      wd= sqrt(w02 - alpha^2);
      s(1) = -alpha +j*wd;
      s(2) = -alpha -j*wd;
      B1 = V0; B2 = (dv+alpha*B1)/wd;
      B1i = I0 - Is; B2i = (di+alpha*B1i)/wd;
      v = exp(-alpha*t).*(B1*cos(wd*t)+B2*sin(wd*t));
      iL = Is + exp(-alpha*t).*(B1i*cos(wd*t)+B2i*sin(wd*t));
      iR = v/R;
      iC= Is -iR-iL;
      it=iR+iL+iC;
      plot(t,iR,'erasemode','none','color',[.9 0 0.8]), grid
      title(['i_R(t) = e^{(-', num2str(alpha), 't)}[(', num2str(B1/R), ')cos',num2str(wd),'t + (' , num2str(B2/R), ')sin',num2str(wd),'t]'],'color',[0.9 0 0.8])
      xlabel(['\alpha = ',num2str(alpha), ',  \omega_0 = ',  num2str(w0), '  (U.D.)          t, sec'])
      ylabel('i_R(t), Amps')
      else
      % Undamped Response
      tf = 8*pi/w0;
      t=0:tf/200:tf;
      wd= w0;
      B1 = V0; B2 = (dv)/wd;
      B1i = I0 - Is; B2i = (di)/wd;
      iL = Is + B1i*cos(wd*t)+B2i*sin(wd*t);
      v = B1*cos(wd*t)+B2*sin(wd*t);
      iR = v/R;
      iC= Is -iR-iL;
      it=iR+iL+iC;
      plot(t,iR,'erasemode','none','color',[0.9 0 0.80]), grid
      title('i_R(t) =  0')
      xlabel(['\alpha = ',num2str(alpha), ',  \omega_0 = ',  num2str(w0), '  (Undamped)          t, sec'])
      ylabel('i_R(t), Amps')
      end
   elseif alpha ==w0
    % Critically damped response
    s(1)=-alpha;  s(2) = s(1);
    D2 = V0;
    D1 = dv+alpha*D2;
    D2i = I0 - Is; D1i = di+alpha*D2i;
    tf = 8/alpha;
    t=0:tf/100:tf;
    iL=Is + exp(-alpha*t).*(D1i*t+D2i);
    v = exp(-alpha*t).*(D1*t+D2);
    iR = v/R;
    iC= Is -iR-iL;
    it=iR+iL+iC;
    plot(t,iR,'erasemode','none','color',[0.9 0 0.8]), grid
    title(['i_R(t) = e^{(-', num2str(alpha), 't)}[(', num2str(D1/R), ')t + (' , num2str(D2/R), ')]'],'color',[0.9 0 0.8])
    xlabel(['\alpha = ',num2str(alpha), ',  \omega_0 = ',  num2str(w0), '  (C.D.)          t, sec'])
    ylabel('i_R(t), Amps')
    else, end