function gamblers_ruin_simulation ( a_stakes, b_stakes, game_num )

%*****************************************************************************80
%
%% GAMBLERS_RUIN_SIMULATION simulates the game of gambler's ruin.
%
%  Discussion:
%
%    Two players, A and B, repeatedly toss a coin.
%    For heads, A wins one dollar from B;
%    For tails, B wins one dollar from A.
%    Play continues until one player is bankrupt.
%
%    This program "plays" the game GAME_NUM times, always starting from
%    the same initial configuration.
%
%    it keeps track of the number of coin tosses required, the number
%    of times the lead changes, and the number of times each player wins.
%
%    At the end, it prints some statistics, and plots histograms of the
%    length of the game, and the number of lead changes.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer A_STAKES, B_STAKES, the number of dollars that A and
%    B have initially.
%
%    Input, integer GAME_NUM, the number of games to simulate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'GAMBLERS_RUIN_SIMULATION\n' );
  fprintf ( 1, '  MATLAB version\n' );

  if ( nargin < 1 )
    a_stakes = input ( 'Enter A_STAKES: ' );
  else
    a_stakes = str2num ( a_stakes );
  end

  if ( nargin < 2 )
    b_stakes = input ( 'Enter B_STAKES: ' );
  else
    b_stakes = str2num ( b_stakes );
  end

  if ( nargin < 3 )
    game_num = input ( 'Enter GAME_NUM, the number of games to play: ' );
  else
    game_num = str2num ( game_num );
  end

  a_wins = 0;
  b_wins = 0;
%
%  Play GAME_NUM games.
%
  for game = 1 : game_num

    step_num = 0;
    leader = '0';
    flip_num = -1;
    a = a_stakes;
    b = b_stakes;

    while ( 0 < a & 0 < b )

      step_num = step_num + 1;

      r = rand ( );

      if ( r <= 0.5 )
        a = a + 1;
        b = b - 1;
      else
        a = a - 1;
        b = b + 1;
      end

      if ( a_stakes < a & leader ~= 'A' )
        leader = 'A';
        flip_num = flip_num + 1;
      elseif ( a < a_stakes & leader ~= 'B' )
        leader = 'B';
        flip_num = flip_num + 1;
      end

    end

    if ( b == 0 )
      a_wins = a_wins + 1;
    else
      b_wins = b_wins + 1;
    end

    flip(game) = flip_num;
    step(game) = step_num;

  end
%
%  Average over the number of games.
%
  step_ave = sum ( step(1:game_num) ) / game_num;
  prob_a_win = a_wins / game_num;
  prob_b_win = b_wins / game_num;
%
%  Print statistics.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of games in simulation = %d\n', game_num );
  fprintf ( 1, '  A starts game with %d\n', a_stakes );
  fprintf ( 1, '  B starts game with %d\n', b_stakes );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Average number of steps = %f\n', step_ave );
  fprintf ( 1, '  Expected number of steps = %d\n', a_stakes * b_stakes );
  fprintf ( 1, '  Maximum number of steps = %d\n', max ( step ) );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Average chance of A winning = %f\n', prob_a_win );
  fprintf ( 1, '  Expected chance of A winning = %f\n', a_stakes / ( a_stakes + b_stakes ) );
  fprintf ( 1, '  Average chance of B winning = %f\n', prob_b_win );
  fprintf ( 1, '  Expected chance of B winning = %f\n', b_stakes / ( a_stakes + b_stakes ) );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Average number of flips = %f\n', sum ( flip ) / game_num );
  fprintf ( 1, '  Maximum number of flips = %d\n', max ( flip ) );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Initial flip table:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number Freq Prob\n' );
  fprintf ( 1, '\n' );
  for flip_num = 0 : 10
    i = find ( flip == flip_num );
    k = length ( i );
    fprintf ( 1, '  %4d  %6d  %f\n', flip_num, k, k / game_num );
  end
%
%  Plot steps.
%
  figure ( 1 )

  hist ( step, 40 )

  title ( 'Gambler''s ruin, number of steps' )
  xlabel ( 'Steps' )
  ylabel ( 'Frequency' )

  figure ( 2 )

  hist ( flip, 40 )
  title ( 'Gambler''s ruin, number of changes in the lead (flips)' )
  xlabel ( 'Flips' )
  ylabel ( 'Frequency' )

  return
end


function im = IdealLowPass(im0,fc)
% fc is the circular cutoff frequency which is normalized to [0 1], that is,
% the highest radian frequency \pi of digital signals is mapped to 1.

[ir,ic,iz] = size(im0);
hr = (ir-1)/2;
hc = (ic-1)/2;
[x, y] = meshgrid(-hc:hc, -hr:hr);

mg = sqrt((x/hc).^2 + (y/hr).^2);
lp = double(mg <= fc);

IM = fftshift(fft2(double(im0)));
IP = zeros(size(IM));
for z = 1:iz
    IP(:,:,z) = IM(:,:,z) .* lp;
end
im = abs(ifft2(ifftshift(IP)));


function oeprint1(mu, oev)

% print six classical orbital elements
% and orbital period in minutes

% input

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

% Orbital Mechanics with Matlab

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

rtd = 180 / pi;

% unload orbital elements array

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

arglat = mod(tanom + argper, 2.0 * pi);

if (sma > 0.0)
    period = 2.0d0 * pi * sma * sqrt(sma / mu);
else
    period = 99999.9;
end

% print orbital elements

fprintf ('\n        sma (km)              eccentricity          inclination (deg)         argper (deg)');

fprintf ('\n %+16.14e  %+16.14e  %+16.14e  %+16.14e \n', sma, ecc, inc * rtd, argper * rtd);

fprintf ('\n       raan (deg)          true anomaly (deg)         arglat (deg)            period (min)');

fprintf ('\n %+16.14e  %+16.14e  %+16.14e  %+16.14e \n', raan * rtd, tanom * rtd, arglat * rtd, period / 60);


%% fnc_getSobolSetMatlab: give a set of sobol quasi-random
%
% Usage:
%   X = fnc_getSobolSetMatlab(dim, N)
%
% Inputs:
%    dim                number of variables, the MAX number of variables is 40
%    N                  number of samples
%
% Output:
%     X                matrix [N x dim] with the quasti-random samples
%
% ------------------------------------------------------------------------
%
%
% Author : Flavio Cannavo'
% e-mail: flavio(dot)cannavo(at)gmail(dot)com
% Release: 1.0
% Date   : 07-02-2011
%
% History:
% 1.0  07-02-2011  First release.
%
%
%

%%

function X = fnc_getSobolSetMatlab(dim, N)

p = sobolset(dim);
p = scramble(p,'MatousekAffineOwen');
X = net(p,N);


%% WGMGRATE Test convergence of multigrid methods for weak Galerkin method
%
% Reference
%
% An auxiliary space multigrid preconditioner for the weak Galerkin method.
% By Long Chen, Junping Wang, Yanqiu Wang, and Xiu Ye. Computers and
% Mathematics with Applications, 70(4):330?344 2015.
% doi:10.1016/j.camwa.2015.04.016

%% Options
clear variables;
close all;
option.maxIt = 4;
option.elemType = 'WG';
option.solver = 'mg';
option.smoothingstep = 2;
option.plotflag = 1;
option.rateflag = 0;
option.dispflag = 1;
colname = {'#Dof','Steps','Time'};

%% Example: circle mesh and Poisson equation
pde = sincosdata;
[node,elem] = circlemesh(0,0,1,0.25);
% showmesh(node,elem,'Facecolor','w');
bdFlag = setboundary(node,elem,'Dirichlet');
mesh = struct('node',node,'elem',elem,'bdFlag',bdFlag);

option.L0 = 1;
option.maxN = 3e5;
option.reducesystem = 0; % Solve the original system
[err,time,solver] = femPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');

option.reducesystem = 1; % Solve the reduced system
[err,time,solver] = femPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');

%% Example: square mesh and variable Poisson equation
[node,elem] = squaremesh([0,1,0,1],0.25);
% showmesh(node,elem,'Facecolor','w');
bdFlag = setboundary(node,elem,'Dirichlet');
mesh = struct('node',node,'elem',elem,'bdFlag',bdFlag);

option.L0 = 2;
option.dquadorder = 4;
pde = oscdiffdata;

option.reducesystem = 0; % Solve the original system
[err,time,solver] = femPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');

option.reducesystem = 1; % Solve the reduced system
[err,time,solver] = femPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');

%% Example: adaptive mesh and Poisson equation with less regularity
[node,elem] = squaremesh([-1,1,-1,1],1);
[node,elem] = delmesh(node,elem,'x>0 & y<0');
bdFlag = setboundary(node,elem,'Dirichlet');
mesh = struct('node',node,'elem',elem,'bdFlag',bdFlag);

pde = Lshapedata;
option.maxIt = 30;
option.maxN = 1e4;
option.printlevel = 0;
option.rateflag = 1;

option.reducesystem = 0; % Solve the original system
[err,time,solver] = afemPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');

option.reducesystem = 1; % Solve the reduced system
[err,time,solver,eqn,node,elem] = afemPoisson(mesh,pde,option);
disptable(colname,solver.N,[],solver.itStep,[],solver.time,'%4.2g');
% figure; showmesh(node,elem,'Facecolor','w');


function M = centeredmatrixfactory(m, n, rows_or_cols)
% Linear manifold struct. for optimization over matrices with centered cols
%
% function M = centeredmatrixfactory(m, n)
% function M = centeredmatrixfactory(m, n, 'cols')
% function M = centeredmatrixfactory(m, n, 'rows')
%
% Returns M, a structure for Manopt describing the Euclidean space of
% m-by-n matrices whose columns sum to zero (or whose rows sum to zero,
% if 'rows' is passed as last input).
%
% The metric is the standard Frobenius distance and associated trace inner
% product. Matrices on M, denoted by X, have size mxn and obey
% X*ones(n, 1) = 0 (centered columns) or ones(1, m)*X = 0 (centered rows).
%
% See also: euclideanfactory

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, July 3, 2015.
% Contributors:
% Change log:

    if ~exist('rows_or_cols', 'var') || isempty(rows_or_cols)
        rows_or_cols = 'cols';
    end

    % Define a centering operator: it subtracts the mean column or row.
    switch lower(rows_or_cols)
        case 'cols'
            center = @(X) bsxfun(@minus, X, mean(X, 2));
            M.dim = @() m*n - m;
        case 'rows'
            center = @(X) bsxfun(@minus, X, mean(X, 1));
            M.dim = @() m*n - n;
        otherwise
            error('The third input must be either ''rows'' or ''cols''.');
    end

    % This is a non-standard function to have in a Manopt manifold.
    % It is included because it might be helpful in some situations.
    M.center = center;

    M.name = @() sprintf('Space of size %d x %d matrices with centered %s', ...
                         m, n, lower(rows_or_cols));

    M.inner = @(x, d1, d2) d1(:).'*d2(:);

    M.norm = @(x, d) norm(d, 'fro');

    M.dist = @(x, y) norm(x-y, 'fro');

    M.typicaldist = @() sqrt(M.dim());

    M.proj = @(X, U) center(U);

    M.egrad2rgrad = M.proj;

    M.ehess2rhess = @(x, eg, eh, d) center(eh);

    M.tangent = @(x, d) d;

    M.exp = @exp;
    function y = exp(x, d, t)
        if nargin == 3
            y = x + t*d;
        else
            y = x + d;
        end
    end

    M.retr = M.exp;

	M.log = @(x, y) y-x;

    M.hash = @(x) ['z' hashmd5(x(:))];

    M.randvec = @(X) randvec();
    function U = randvec()
        U = center(randn(m, n));
        U = U / norm(U, 'fro');
    end

    M.rand = @() center(randn(m, n));

    M.lincomb = @matrixlincomb;

    M.zerovec = @(x) zeros(m, n);

    M.transp = @(x1, x2, d) d;

    M.pairmean = @(x1, x2) .5*(x1+x2);

    M.vec = @(x, u_mat) u_mat(:);
    M.mat = @(x, u_vec) reshape(u_vec, [m, n]);
    M.vecmatareisometries = @() true;

end


T=1/f;

sl=3*T; % signal length

xl=get(handles.axes1,'Xlim');
yl=get(handles.axes1,'Ylim');
dxl=xl(2)-xl(1);
dyl=yl(2)-yl(1);

xc1=0:dxl/res:sl;
xc=mod(xc1,T); % turn to one period
if iscnt
    yc=interp1([xys(1,:)-dxl xys(1,:) xys(1,:)+dxl],[xys(2,:) xys(2,:) xys(2,:)],xc,mth,'extrap');
else
    yc=interp1(xys(1,:),xys(2,:),xc,mth,'extrap');
end

nf=max(abs(yc)); % normalization factor
yc=yc/nf; % mormalize

figure;
plot(xc1,yc,'b-',xys(1,:),xys(2,:)/nf,'rx',[T T],[-1 1],'k--',[2*T 2*T],[-1 1],'k--');
xlabel('time, s');
ylabel('signal, notmalized');
title('3 periods of the signal');
ylim([-1 1]);


function [sh,pnl,pos] = marisa(x,N,M)
% this is a combo model, MA+RSI
thresh=55;
S=length(x);
e=ema(x,N);
% take the RSI of the *DETRENDED* series
r=rsi2(x-ema(x,15*M),M);
% bid/ask spreads
cost=0.01;     % BUND/BOBL
%cost=0.005;    % SCHATZ
%cost=1/64;     %Treasury futures
%cost = 0.0001;  %US/EUR
%cost = 0.05;   %EUR/JPY
%cost = 0.04;   %US/JPY
%cost = 0.0005;  %AUS/USD
%cost= 0.02;
%cost=1;        % eurostoxx

rpos=zeros(S,1);
% position of the ema
epos=sign(x-e);
% position of the rsi
I= (thresh-r)<0;
IU=[~1;I(1:end-1) & ~I(2:end)];
rpos(IU)=-1;
% crossing the lower threshold
I= ((100-thresh)-r)>0;
IL=[~1;I(1:end-1) & ~I(2:end)];
rpos(IL)=1;
% copy down previous position values
for i=2:S
    if rpos(i)==0;
        rpos(i)=rpos(i-1);
    end
end

% get the combined signal position
pos=(rpos+epos)/2;
pos( abs(pos) < 1)=0;

% pnl calculation
pnl= pos(1:end-1).*diff(x) - abs(diff(pos))*cost/2;
sh= sqrt(250)*mean(pnl)/std(pnl);


clear all; close all;
I=imread('pout.tif');
J=log(im2double(I)+1);
K=fft2(J);
n=5;
D0=0.1*pi;
rh=0.7;
rl=0.4;
[row, column]=size(J);
for i=1:row
    for j=1:column
        D1(i,j)=sqrt(i^2+j^2);
        H(i,j)=rl+(rh/(1+(D0/D1(i,j))^(2*n)));
    end
end
L=K.*H;
M=ifft2(L);
N=exp(M)-1;
figure;
subplot(121);
imshow(I);
subplot(122);
imshow(real(N));


function val=evalBSplinePoly(t,x,k,idx)
%%EVALBSPLINEPOLY Given a set of knots in non-decreasing order (some can be
%                 repeated), evaluate the idx-th order-k B-spline
%                 polynomial. This is B_{idx,k}(x). The first subscript
%                 refers to the knots used in determining the polynomial.
%                 Unlike the function evalBSplinePolys, this function can
%                 handle values of x that are outside of the region
%                 t(idx+-1k)<=x<=t(idx+k).
%
%INPUTS: t A 1XnumKnots or numKnotsX1 vector containing the knots. The
%          knots must be sorted in ascending order. It is possible for the
%          knots to be repeated.
%        x The scalar or matrix set of points at which the polynomials
%          should be evaluated.
%        k Optionally, the order of the B-spline polynomials. If this
%          parameter is omitted, then the default of fix(length(t)/2)+1 is
%          used. This is the highest order that can be used with the given
%          number of knots.
%      idx This input specifies where in terms of the knots the B-spline
%          polynomials are centered. This is an integer value from 1 to
%          numKnots-k.
%
%OUTPUTS: val The value of the b-spline B_{idx,k}(x) evaluated at all of
%             the points in x. This has the same size as x.
%
%This function implements the divided difference formulation of the splines
%from Equation 1 in Chapter IX of [1]. A clearer explanation of the
%notation is given in Chapter 2.4.4 of [2], where Equation 2.4.4.3 is the
%divided difference formula.
%
%EXAMPLE:
%Here, we plot all of the b-spline basis functions from example IX.1 of
%Chapter IX of [1]. The functions only sum to one over the region from 1 to
%6. Thus, the sum is not one over the region plotted before x=1.
% t=[0;1;1;3;4;6;6;6];
% k=3;
% numPoints=500;
% x=linspace(0,6,numPoints);
%
% b1=evalBSplinePoly(t,x,k,1);
% b2=evalBSplinePoly(t,x,k,2);
% b3=evalBSplinePoly(t,x,k,3);
% b4=evalBSplinePoly(t,x,k,4);
% b5=evalBSplinePoly(t,x,k,5);
% figure(1)
% clf
% hold on
% plot(x,b1,'-k','linewidth',2)
% plot(x,b2,'--r','linewidth',2)
% plot(x,b3,'-.g','linewidth',2)
% plot(x,b4,'-b','linewidth',2)
% plot(x,b5,'--c','linewidth',2)
%
%REFERENCES:
%[1] C. de Boor, A Practical Guide to Splines. New York: Springer-Verlag,
%    1978.
%[2] J. Stoer and R. Burlisch, Introduction to Numerical Analysis, 2nd ed.
%    New York: Springer-Verlag, 1991.
%
%April 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

val=zeros(size(x));
numEls=numel(x);
for curIdx=1:numEls
    xCur=x(curIdx);
    tSel=t(idx:(idx+k));
    f=max(tSel-xCur,0).^(k-1);
    fDeriv=@(ti,nd)prod((k-(1:nd)))*max(ti-xCur,0).^(k-1-nd);

    val(curIdx)=(t(idx+k)-t(idx))*evalDividedDiff(tSel,f,fDeriv);
end
end

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


function triangle_symq_rule_test05 ( degree, numnodes, vert1, vert2, vert3 )

%*****************************************************************************80
%
%% TRIANGLE_SYMQ_RULE_TEST05 calls TRIASYMQ for a quadrature rule of given order and region.
%
%  Licensing:
%
%    This code is distributed under the GNU GPL license.
%
%  Modified:
%
%    27 June 2014
%
%  Author:
%
%    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Hong Xiao, Zydrunas Gimbutas,
%    A numerical algorithm for the construction of efficient quadrature
%    rules in two and higher dimensions,
%    Computers and Mathematics with Applications,
%    Volume 59, 2010, pages 663-676.
%
%  Parameters:
%
%    Input, integer DEGREE, the desired total polynomial degree
%    exactness of the quadrature rule.  0 <= DEGREE <= 50.
%
%    Input, integer NUMNODES, the number of nodes to be used by the rule.
%
%    Input, real VERT1(2), VERT2(2), VERT3(2), the
%    vertices of the triangle.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TRIANGLE_SYMQ_RULE_TEST05\n' );
  fprintf ( 1, '  Compute a quadrature rule for a triangle.\n' );
  fprintf ( 1, '  Check it by integrating orthonormal polynomials.\n' );
  fprintf ( 1, '  Polynomial exactness degree DEGREE = %d\n', degree );

  area = triangle_area ( vert1, vert2, vert3 );
%
%  Retrieve a symmetric quadrature rule.
%
  [ rnodes, weights ] = triasymq ( degree, vert1, vert2, vert3,  numnodes );
%
%  Construct the matrix of values of the orthogonal polynomials
%  at the user-provided nodes
%
  npols = ( ( degree + 1 ) * ( degree + 2 ) ) / 2;

  rints = zeros ( npols, 1 );

  for i = 1 : numnodes
    z(1) = rnodes(1,i);
    z(2) = rnodes(2,i);
    r = triangle_to_ref ( vert1, vert2, vert3, z );
    pols = ortho2eva ( degree, r );
    rints(1:npols) = rints(1:npols) + weights(i) * pols(1:npols);
  end

  scale = sqrt ( sqrt ( 3.0 ) ) / sqrt ( area );
  rints(1:npols) = rints(1:npols) * scale;

  d = ( rints(1) - sqrt ( area ) )^2 + sum ( rints(2:npols).^2 );
  d = sqrt ( d ) / npols;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  RMS integration error = %g\n', d );

  return
end


%% AMG TEST I: DIFFERENT MESHES
%
% We consider linear finite element discretization of the Poisson equation
% with homongenous Dirichlet boundary condition on different meshes.

%%
clear all; close all;
%% Uniform mesh
[node,elem] = squaremesh([0,1,0,1],0.1);
[node,elem] = uniformrefine(node,elem);
[node,elem] = uniformrefine(node,elem);
showmesh(node,elem);
snapnow;
[N,itStep,time,err,errHist] = amgtest(node,elem);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
colHeaders = {'Iterations','Approximate Error', 'Residual'};
makeHtmlTable([(0:itStep(end))' errHist],[],[],colHeaders,[],6);
%%
r = showrate(N,time,2);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'] ,'Fontsize', 14);

%% Circle mesh
close all;
[node,elem] = circlemesh(0,0,1,0.2);
[node,elem] = uniformrefine(node,elem);
[node,elem] = uniformrefine(node,elem);
showmesh(node,elem);
snapnow;
[N,itStep,time,err] = amgtest(node,elem);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
r = showrate(N,time,2);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'] ,'Fontsize', 14);

%% Unstructured mesh
close all;
load lakemesh
showmesh(node,elem);
snapnow;
[N,itStep,time,err] = amgtest(node,elem);
%%
colHeaders = {'Unknowns','Iterations','Time (sec)','Error'};
makeHtmlTable([N itStep time err],[],[],colHeaders,[],6);
%%
r = showrate(N,time,2);
xlabel('N'); ylabel('Time');
title(['Complexity is N^{' num2str(r) '}'],'Fontsize', 14);


function y = hmean(x)
% HMEAN   1/mean(1/input)
%
%   Description:
%   Y = HMEAN(X) evaluates y=1./mean(1./x)

% Copyright (c) 1998 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

y=1./mean(1./x);


function [theta] = tapas_sem_sample_gaussian_uniform_priors(ptheta)
%% Sample from a Gaussian prior.
%
% aponteeduardo@gmail.com
% copyright (C) 2016
%

np = size(ptheta.jm, 2);

sample_pars = logical(sum(ptheta.jm, 2));

if size(ptheta.pm, 2) ~= np
    pm = diag(ptheta.pm);
else
    pm = ptheta.pm;
end

lt = chol(pm);
theta = ptheta.mu +  lt \ ptheta.jm * randn(np, 1);

% Beta parameters.
bdist = zeros(size(ptheta.pm));
bdist(ptheta.bdist) = 1;
bdist = logical(bdist .* sample_pars);
vals = betarnd(abs(ptheta.mu), abs(ptheta.pm));
vals = ptheta.jm * ptheta.sm' * vals;
theta(bdist) = log(vals(bdist) ./ ( 1 - vals(bdist)));

theta(~sample_pars) = ptheta.p0(~sample_pars);

end


function state = sample_mdp(prior, trans, act)
% SAMPLE_MDP Sample a sequence of states from a Markov Decision Process.
% state = sample_mdp(prior, trans, act)
%
% Inputs:
% prior(i) = Pr(Q(1)=i)
% trans{a}(i,j) = Pr(Q(t)=j | Q(t-1)=i, A(t)=a)
% act(a) = A(t), so act(1) is ignored
%
% Output:
% state is a vector of length T=length(act)

len = length(act);
state = zeros(1,len);
state(1) = sample_discrete(prior);
for t=2:len
  state(t) = sample_discrete(trans{act(t)}(state(t-1),:));
end


function [suspicious_index abof] = fastABOD(A,n_k)
%
% Angle Based Outlier Detection
% Authors: Hans-Peter, Kriegel Matthias, Schubert Arthur Zimek
% Original paper :
% Angle-Based Outlier Detection in High-dimensional Data In KDD2008
% Website : http://www.dbs.ifi.lmu.de/
% e-mail : {kriegel,schubert,zimek}@dbs.ifi.lmu.de
% Programmer: Yi-Ren Yeh
% modified by: Wei-Chih Lai
%
% Time Complexity : O(n^2 + n * n_k^2)
%
% Inputs
%   A: Represent NxM data
%      N is number of instance
%      M is number of feature
%   n_k: 1x1 integer (0, N]
%      iterator time for approximate abof value
%
% Outputs
%   abof: Nx1 vector
%      suspicious abof value for each instance
%   suspicious_index: Nx1 vector
%      [~,suspicious_index]=sort(abof,'ascend')
% Note
%   1. each value in output abof was normalized to [0, 1]
%   2. if input n_k == N - 1, then the effect is equal to ABOD
%
    [A, ia, ic] = unique(A,'rows');
    instance_number = size(ia, 1);
    origin_instance_number = size(ic, 1);
    var_array = zeros(instance_number, 1);
    n_k = min(n_k, instance_number);

    for i=1:instance_number
        var_front = 0;
        var_back = 0;
        denominator = 0;
        Temp = repmat(A(i, :), instance_number, 1) - A;
        Temp = sum(Temp .^ 2, 2);
        [~, index] = sort(Temp);
        index = index(2:n_k);
        index = index';
        count = 0;
        for j=index
            count = count + 1;
            for k=index(count+1:end)
                vector1 = A(j, :) - A(i, :);
                vector2 = A(k, :) - A(i, :);
                norm_vector1Xnorm_vector2 = norm(vector1) * norm(vector2);
                vector1Xvector2T = vector1 * vector2';
                var_front = var_front + (1 / norm_vector1Xnorm_vector2) * (vector1Xvector2T / (norm_vector1Xnorm_vector2 ^ 2)) ^ 2;
                var_back = var_back + (vector1Xvector2T / norm_vector1Xnorm_vector2 ^ 3);
                denominator = denominator + (1 / norm_vector1Xnorm_vector2);
            end
        end
        var_array(i) = var_front / denominator - (var_back / denominator) ^ 2;
    end

    min_var_array = min(var_array);
    abof = (var_array - min_var_array) / (max(var_array) - min_var_array);
    origin_abof = zeros(origin_instance_number, 1);
    for i=1:origin_instance_number
        origin_abof(i, 1) = abof(ic(i, 1), 1);
    end
    abof = origin_abof;
    [~, suspicious_index] = sort(abof);


function [dat, opt] = proc_pca(dat, varargin)
%PROC_PCA - Principal Component Analysis
% [dat_pca, pca_opt] = proc_pca(dat, <opt>)
%
%Synopsis for training PCA:
% [DAT_PCA_TRAIN, PCA_OPT] = proc_pca(DAT_TRAIN, <OPT>)
%
%Synopsis for applying PCA:
% DAT_PCA_TEST = proc_pca(DAT_TEST, PCA_OPT)
%
%Arguments:
% DAT_TRAIN     - data structure of continuous or epoched data
% OPT           - struct or property/value list of optional properties:
%  .whitening   - if 1, the output dimensions will all have unit variance
%                 (default 0)
% PCA_OPT       - a struct that contains: a bias vector, filters and field
%                 patterns of the sources
%
%Returns
% DAT_PCA_TRAIN,
% DAT_PCA_TEST  - updated data structure
% PCA_OPT       - a struct that contains: a bias vector, filters and field
%                 patterns of the sources
%

% Sven Daehne, 03.2011, sven.daehne@tu-berlin.de
% Matthias Schultze-Kraft, 12.2015, schultze-kraft@tu-berlin.de

props= {'whitening'         0       'BOOL'
        'filters'           []      'DOUBLE'
        'field_patterns'    []      'DOUBLE'
        'bias'              []      'DOUBLE'};

if nargin==0,
  dat = props; return
end

dat = misc_history(dat);
misc_checkType(dat, 'STRUCT(x clab y)');

opt = opt_proplistToStruct(varargin{:});
opt = opt_setDefaults(opt, props);
opt_checkProplist(opt, props);

[T,nChans,nEpos] = size(dat.x);

%% train PCA
if isempty(opt.filters) || isempty(opt.bias)
    % get the data matrix
    if ndims(dat.x)==3
        % since time structure does not matter, we can simply concatenate all
        % epochs to get one big data matrix
        X = permute(dat.x, [1,3,2]); % now channels are the last dimension
        X = reshape(X, [T*nEpos, nChans]);
    else
        X = dat.x;
    end
    % remove the mean here already
    b = mean(X,1);
    B = repmat(b, [T*nEpos, 1]);
    X = X - B;

    % perform PCA and compute whitening matrix
    C = cov(X);
    [V, D] = eig(C);
    [ev_sorted, sort_idx] = sort(diag(D), 'descend');
    V = V(:,sort_idx);
    D = diag(ev_sorted);

    if opt.whitening
        V = V * diag(diag(D).^-0.5);
    end

    opt.filters = V;
    opt.field_patterns = V';
    opt.eigenvalues = ev_sorted;
    opt.bias = b;

end

%% apply PCA
if not(length(opt.bias) == nChans)
    error('Dimension of bias must equal the number of channels!')
end
% make sure opt.bias is a row vector
if size(opt.bias, 1) > size(opt.bias,2)
    opt.bias = opt.bias';
end

% subtract bias, then apply filters
B = squeeze(repmat(opt.bias, [T,1,nEpos]));
dat.x = dat.x - B;
dat = proc_linearDerivation(dat, opt.filters);


load demo.mat
pitch =  -120/180*pi;
yaw = -30/180*pi;
pitchR = [1           0           0           ;...
          0           cos(pitch)  -sin(pitch) ;...
          0           sin(pitch)  cos(pitch)  ];
yawR =   [cos(yaw)    0           sin(yaw)  ;...
          0           1           0           ;...
          -sin(yaw)   0           cos(yaw)  ];

R = pitchR * yawR ;

Rt = [R [0.8;0;12]];

width = 640*1;
height= 480*1;
K = [  1100*1    0  width/2 ;...
         0  1100*1  height/2 ;...
         0    0    1];
[render,depth] = RenderPCcameraMatlab(double(pt),color, ptCamera,colorCamera ,K, Rt,width,height);
imshow(render);
imwrite(render,'demo.png');


function varargout = centerOfMass(A,varargin)
% CENTEROFMASS finds the center of mass of the N-dimensional input array
%
%   CENTEROFMASS(A) finds the gray-level-weighted center of mass of the
%   N-dimensional numerical array A. A must be real and finite. A warning
%   is issued if A contains any negative values. Any NaN elements of A will
%   automatically be ignored. CENTEROFMASS produces center of mass
%   coordinates in units of pixels. An empty array is returned if the
%   center of mass is undefined.
%
%   The center of mass is reported under the assumption that the first
%   pixel in each array dimension is centered at 1.
%
%   Also note that numerical arrays other than DOUBLE and SINGLE are
%   converted to SINGLE in order to prevent numerical roundoff error.
%
%   Examples:
%       A = rgb2gray(imread('saturn.png'));
%       C = centerOfMass(A);
%
%       figure; imagesc(A); colormap gray; axis image
%       hold on; plot(C(2),C(1),'rx')
%
%   See also:
%
%

%
%   Jered R Wells
%   2013/05/07
%   jered [dot] wells [at] gmail [dot] com
%
%   v1.0
%
%   UPDATES
%       YYYY/MM/DD - jrw - v1.1
%
%

%% INPUT CHECK
narginchk(0,1);
nargoutchk(0,1);
fname = 'centerOfMass';

% Checked required inputs
validateattributes(A,{'numeric'},{'real','finite'},fname,'A',1);

%% INITIALIZE VARIABLES
A(isnan(A)) = 0;
if ~(strcmpi(class(A),'double') || strcmpi(class(A),'single'))
    A = single(A);
end
if any(A(:)<0)
    warning('MATLAB:centerOfMass:neg','Array A contains negative values.');
end

%% PROCESS
sz = size(A);
nd = ndims(A);
M = sum(A(:));
C = zeros(1,nd);
if M==0
    C = [];
else
    for ii = 1:nd
        shp = ones(1,nd);
        shp(ii) = sz(ii);
        rep = sz;
        rep(ii) = 1;
        ind = repmat(reshape(1:sz(ii),shp),rep);
        C(ii) = sum(ind(:).*A(:))./M;
    end
end

% Assemble the VARARGOUT cell array
varargout = {C};

end % MAIN


function [ n_data, x, fx ] = cos_degree_values ( n_data )

%*****************************************************************************80
%
%% COS_DEGREE_VALUES: the cosine function with argument in degrees.
%
%  Discussion:
%
%    In Mathematica, the function can be evaluated by:
%
%      Cos[x Degree]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 March 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz, Irene Stegun,
%    Handbook of Mathematical Functions,
%    National Bureau of Standards, 1964,
%    ISBN: 0-486-61272-4,
%    LC: QA47.A34.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Cambridge University Press, 1999,
%    ISBN: 0-521-64314-7,
%    LC: QA76.95.W65.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0
%    before the first call.  On each call, the routine increments N_DATA by 1,
%    and returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real X, the argument of the function.
%
%    Output, real FX, the value of the function.
%
  n_max = 22;

  fx_vec = [ ...
     0.99619469809174553230, ...
     1.0000000000000000000, ...
     0.99984769515639123916, ...
     0.99939082701909573001, ...
     0.99862953475457387378, ...
     0.99756405025982424761, ...
     0.99619469809174553230, ...
     0.98480775301220805937, ...
     0.96592582628906828675, ...
     0.86602540378443864676, ...
     0.70710678118654752440, ...
     0.50000000000000000000, ...
     0.25881904510252076235, ...
     0.087155742747658173558, ...
     0.069756473744125300776, ...
     0.052335956242943832722, ...
     0.034899496702500971646, ...
     0.017452406437283512819, ...
     0.000000000000000000000, ...
    -0.017452406437283512819, ...
    -0.25881904510252076235, ...
    -1.0000000000000000000 ];
  x_vec = [ ...
     -5.0, ...
      0.0, ...
      1.0, ...
      2.0, ...
      3.0, ...
      4.0, ...
      5.0, ...
     10.0, ...
     15.0, ...
     30.0, ...
     45.0, ...
     60.0, ...
     75.0, ...
     85.0, ...
     86.0, ...
     87.0, ...
     88.0, ...
     89.0, ...
     90.0, ...
     91.0, ...
    105.0, ...
    180.0 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    x = 0.0;
    fx = 0.0;
  else
    x = x_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


% -----------------------------------------------------------------  %
% Matlab Programs included the Appendix B in the book:               %
%  Xin-She Yang, Engineering Optimization: An Introduction           %
%                with Metaheuristic Applications                     %
%  Published by John Wiley & Sons, USA, July 2010                    %
%  ISBN: 978-0-470-58246-6,   Hardcover, 347 pages                   %
% -----------------------------------------------------------------  %
% Citation detail:                                                   %
% X.-S. Yang, Engineering Optimization: An Introduction with         %
% Metaheuristic Application, Wiley, USA, (2010).                     %
%                                                                    %
% http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470582464.html %
% http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0470582464.html  %
% -----------------------------------------------------------------  %
% ===== ftp://  ===== ftp://   ===== ftp:// =======================  %
% Matlab files ftp site at Wiley                                     %
% ftp://ftp.wiley.com/public/sci_tech_med/engineering_optimization   %
% ----------------------------------------------------------------   %

% Design Optimization of a Pressure Vessel using fmincon             %
% This is essentially a different problem as integer multiples       %
% are not applied.  If leaves an exercise to modify the program that %
% the first two design variables are the integer multiples of 0.0625 %
% ------------------------------------------------------------------ %

function B7_pressure

  d=0.0625;
  % Linear inequality constraints
  A=[-1 0 0.0193 0;0 -1 0.00954 0;0 0 0 1];
  b=[0; 0; 240];
  % Simple bounds
  Lb=[d; d; 10; 10];
  Ub=[99*d; 99*d; 200; 200];
  x0=Lb+(Ub-Lb).*rand(size(Lb));
  options=optimset('Display','iter','TolFun',1e-08);
  [x,fval]=fmincon(@objfun,x0,A,b,[],[],Lb,Ub,@nonfun,options)

% The objective function
function f=objfun(x)
f=0.6224*x(1)*x(3)*x(4)+1.7781*x(2)*x(3)^2 ...
  +3.1661*x(1)^2*x(4)+19.84*x(1)^2*x(3)

% Nonlinear constraints
function [g,geq]=nonfun(x)
% Nonlinear inequality
  g=-pi*x(3)^2*x(4)-4*pi/3*x(3)^3+1296000;
% Equality constraint [none]
  geq=[];


function lambda = combin_eigenvalues ( alpha, beta, n )

%*****************************************************************************80
%
%% COMBIN_EIGENVALUES returns the eigenvalues of the COMBIN matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real ALPHA, BETA, scalars that define A.
%
%    Input, integer N, the order of A.
%
%    Output, real LAMBDA(N,1), the eigenvalues.
%
  lambda = zeros ( n, 1 );

  lambda(1:n-1,1) = alpha;
  lambda(n,1) = alpha + n * beta;

  return
end


function h = histp(x, xmin, xmax, nbins)
%HISTP	Histogram estimate of 1-dimensional probability distribution.
%
%	Description
%
%	HISTP(X, XMIN, XMAX, NBINS) takes a column vector X  of data values
%	and generates a normalized histogram plot of the  distribution. The
%	histogram has NBINS bins lying in the range XMIN to XMAX.
%
%	H = HISTP(...) returns a vector of patch handles.
%
%	See also
%	DEMGAUSS
%

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

ndata = length(x);

bins = linspace(xmin, xmax, nbins);

binwidth = (xmax - xmin)/nbins;

num = hist(x, bins);

num = num/(ndata*binwidth);

h = bar(bins, num, 0.6);


function hermite_polynomial_test11 ( p, e )

%*****************************************************************************80
%
%% HERMITE_POLYNOMIAL_TEST11 tests HEN_POWER_PRODUCT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer P, the maximum degree of the polynomial factors.
%
%    Input, integer E, the exponent of X in the integrand.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HERMITE_POLYNOMIAL_TEST11\n' );
  fprintf ( 1, '  Compute a normalized probabilist''s Hermite polynomial power product table.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Tij = integral ( -oo < X < +oo ) X^E Hen(I,X) Hen(J,X) exp(-0.5*X*X) dx\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  where Hen(I,X) = normalized probabilist''s Hermite polynomial of degree I.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Maximum degree P = %d\n', p );
  fprintf ( 1, '  Exponent of X = %d\n', e );

  table = hen_power_product ( p, e );

  r8mat_print ( p + 1, p + 1, table, '  Power weighted table:' );

  return
end


%% EXAMPLE 9: Multitaper-Welch.
%  Multitaper-Welch estimators provide lower variance estimates at a fixed
%  frequency resolution or higher frequency resolution at similar variance
%  compared to the standard algorithm. In this example, we retain the high
%  frequency resolution of a three block Welch estimate but significantly
%  reduce the variance of the SPOD spectrum by using 10 Slepian tapers.
%
%   References:
%     [1] O. T. Schmidt, Spectral proper orthogonal decomposition using
%         multitaper estimates, Theor. Comput. Fluid Dyn., 2022, 1-14,
%         DOI 10.1007/s00162-022-00626-x, https://rdcu.be/cUtP3
%
% O. T. Schmidt (oschmidt@ucsd.edu)
% Last revision: 5-Sep-2022

clc, clear variables
addpath('utils')
disp('Loading the entire test database might take a second...')
load(fullfile('jet_data','jetLES.mat'),'p','x','r','dt');

%   trapezoidal quadrature weights for cylindrical coordinates
intWeights = trapzWeightsPolar(r(:,1),x(1,:));

%% Standard SPOD
%   SPOD with a large block size to get a high frequency resolution and
%   resolve the low-frequency regime.
nFFT    = 2048;
nOvlp   = nFFT/2;
[L,P,f] = spod(p,nFFT,intWeights,nOvlp,dt);

%   Plot the SPOD spectrum and three leading modes at the frequency of
%   interest.
f_plot  = 0.24;
[~,fi]  = min(abs(f-f_plot));
nBlk    = size(L,2);

figure
subplot(5,2,[1 3])
loglog(f,L)
xlim([f(2) f(end)]), ylim([1e-9 1e-3])
xlabel('frequency'), ylabel('SPOD mode energy')
title('Welch (standard)')
hold on
plot([f(fi) f(fi)],ylim,'k:')

count   = 5;
for mi  = 1:3
    subplot(5,2,count)
    contourf(x,r,real(squeeze(P(fi,:,:,mi))),11,'edgecolor','none'), axis equal tight, caxis(max(abs(caxis))*[-1 1])
    xlabel('x'), ylabel('r'), title(['f=' num2str(f(fi),'%.2f') ', mode ' num2str(mi)])
    xlim([0 10]); ylim([0 2])
    count = count + 2;
end
drawnow

%% Multitaper-Welch SPOD
%   SPOD using a retangular window of length 256 and 50 snaphots overlap
%   10 Slapian tapers by setting the time-halfbandwidth product to 5.5.
bw      = 5.5;
[L,P,f] = spod(p,[nFFT bw],intWeights,nOvlp,dt);

%   Plot the SPOD spectrum and modes as before. Compared to the standard
%   algorithm, the variance of the spectrum has been reduced significanlty
%   and the modes are better converged.
subplot(5,2,[2 4])
loglog(f,L(:,1:nBlk)), hold on
loglog(f,L(:,nBlk+1:end),'Color',[0.75 0.75 0.75]), hold on
xlim([f(2) f(end)]), ylim([1e-9 1e-3])
xlabel('frequency'), ylabel('SPOD mode energy')
title(['Multitaper-Welch, b_w=' num2str(bw)])

hold on
plot([f(fi) f(fi)],ylim,'k:')

count = 6;
for mi = 1:3
    subplot(5,2,count)
    contourf(x,r,real(squeeze(P(fi,:,:,mi))),11,'edgecolor','none'), axis equal tight, caxis(max(abs(caxis))*[-1 1])
    xlabel('x'), ylabel('r'), title(['f=' num2str(f(fi),'%.2f') ', mode ' num2str(mi)])
    xlim([0 10]); ylim([0 2])
    count = count + 2;
end


function bsv_test06 ( )

%*****************************************************************************80
%
%% BSV_TEST06 estimates the expected value of the zero crossing.
%
%  Discussion:
%
%    We assume that the left boundary condition ALPHA can vary like
%    a Gaussian variable with mean 1 and standard deviation 0.05.
%
%    Estimate the integral:
%
%      E(X0(ALPHA)) = integral ( -oo < alpha < +oo ) x0(alpha) e^(-0.5*alpha^2/sigma^2) dalpha
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 April 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BSV_TEST06:\n' );
  fprintf ( 1, '  For the Burgers equation on [A,B] with viscosity NU and \n' );
  fprintf ( 1, '  boundary conditions U(A)=ALPHA, U(B) = BETA,\n' );
  fprintf ( 1, '  with ALPHA and BETA of opposite sign,\n' );
  fprintf ( 1, '  let X0 be the point where the solution U changes sign.\n' );
  fprintf ( 1, '  Assume ALPHA is Gaussian with mean 0 and standard deviation 0.05.\n' );
  fprintf ( 1, '  Estimate E(X0(ALPHA)) using M Gaussian samples.\n' );

  a = -1.0;
  b = +1.0;
  beta = -1.0;
  nu = 0.1;
  n = 81;
  output = 0;

  x = linspace ( a, b, n );
%
%  Monte Carlo Estimate.
%  Choose M normal random samples with the correct STD,
%  find X0 for each, and average.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '     M    E(X0(ALPHA)) estimate\n' );
  fprintf ( 1, '\n' );

  for j = 4 : 12

    m = 2^j;
    mu = 1.0;
    sigma = 0.05;
    alpha_vec = mu + 0.05 * randn ( m, 1 );

    x0_bar = 0.0;

    for i = 1 : m
      alpha = alpha_vec(i);
      print = 0;
      u = bsv ( a, b, alpha, beta, nu, n, output );
      x0 = bsv_crossing ( a, b, n, x, u );
      x0_bar = x0_bar + x0;
    end

    x0_bar = x0_bar / m;

    fprintf ( 1, '  %4d  %14.6g\n', m, x0_bar );

  end

  return
end


function [A, B] = convertHypergraphToBipartiteGraph(S, printLevel)
% Converts a hypergraph into an undirected bipartite graph
%
% USAGE:
%
%    [A, B] = convertHypergraphToBipartiteGraph(S, printLevel)
%
% INPUT:
%    S:             `m x n` matrix with `m` nodes and `n` hyperedges
%    printLevel:    timer
%
% OUTPUTS:
%    A:             `(m+n) x (m+n)` adjacency matrix for an undirected graph (symmetric)
%    B:             `(m+n) x nnz(S)` incidence matrix for a directed graph
%
% .. Author: - Ronan Fleming 2013

if ~exist('printLevel', 'var')
    printLevel = 0;
end

[nMet, nRxn] = size(S);

if printLevel
    tic
end

S = sparse(S);
nnzS = nnz(S);

[row, col, v] = find(S);
numbers = 1:nnzS;
rowIndices = zeros(2 * nnzS, 1);
colIndices = zeros(2 * nnzS, 1);

values = zeros(2 * nnzS, 1);
rowIndices(1:2:end) = row;
colIndices(1:2:end) = numbers;
values(1:2:end) = v;

rowIndices(2:2:end) = nMet + col;
colIndices(2:2:end) = numbers;
values(2:2:end) = sign(v) * -1;

% incidence matrix for a bipartite graph
B = sparse(rowIndices, colIndices, values);
if printLevel
    toc
end

if printLevel
    tic
end

% create the adjacency matrix from undirected incidence matrix
A = inc2adj(B ~= 0);
if printLevel
    toc
end

% sanity check
assert(all(sum(B ~= 0, 1) == 2))
end

% old code
% %converts to bipartite hypergraph
% A=sparse(nMet+nRxn,nMet+nRxn);
%
% for j=1:nRxn
%     for i=1:nMet
%         if S(i,j)~=0
%             A(i,nMet+j)=1;
%             A(nMet+j,i)=1;
%         end
%     end
% end

% old methods
% switch method
% case 1
%     %incidence matrix for a bipartite graph
%     B=sparse(nMet+nRxn,nnzS);
%     k=1;
%     for j=1:nRxn
%         for i=1:nMet
%             if S(i,j)~=0
%                 if S(i,j)<0
%                     B(i,k)=S(i,j);
%                     B(nMet+j,k)=1;
%                 else
%                     B(i,k)=S(i,j);
%                     B(nMet+j,k)=-1;
%                 end
%                 k=k+1;
%
%             end
%         end
%     end
% case 2
%     rowIndices=zeros(2*nnzS,1);
%     colIndices=zeros(2*nnzS,1);
%     values=zeros(2*nnzS,1);
%     k=1;
%     p=1;
%     for j=1:nRxn
%         for i=1:nMet
%             if S(i,j)~=0
%                 if S(i,j)<0
%                     rowIndices(p)=i;
%                     colIndices(p)=k;
%                     values(p)=S(i,j);
%                     p=p+1;
%                     rowIndices(p)=nMet+j;
%                     colIndices(p)=k;
%                     values(p)=1;
%                     p=p+1;
%                 else
%                     rowIndices(p)=i;
%                     colIndices(p)=k;
%                     values(p)=S(i,j);
%                     p=p+1;
%                     rowIndices(p)=nMet+j;
%                     colIndices(p)=k;
%                     values(p)=-1;
%                     p=p+1;
%                 end
%                 k=k+1;
%             end
%         end
%     end


function y = ainv_x ( x, R, k )

%*****************************************************************************80
%
%% AINV_X computes inverse(A)*x.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X(*), the vector to be multiplied by inverse(A).
%
%    Input, character R, the first argument to the NUMGRID command.
%
%    Input, integer K, the order of the grid.
%
%    Output, real Y, the value of inverse(A)*X.
%
  y = ( delsq ( numgrid ( R, k ) ) ) \ x;

  return
end


function result=robpca(x,varargin)

%ROBPCA is a 'ROBust method for Principal Components Analysis'.
% It is resistant to outliers in the data. The robust loadings are computed
% using projection-pursuit techniques and the MCD method.
% Therefore ROBPCA can be applied to both low and high-dimensional data sets.
% In low dimensions, the MCD method is applied (see mcdcov.m).
%
% The ROBPCA method is described in
%  Hubert, M., Rousseeuw, P.J., Vanden Branden, K. (2005), ROBPCA: a
%  new approach to robust principal components analysis, Technometrics, 47, 64-79.
%
%
% To select the number of principal components, a robust PRESS (predicted
% residual sum of squares) curve is drawn, based on a fast algorithm for
% cross-validation. This approach is described in:
%
%    Hubert, M., Engelen, S. (2007),
%    "Fast cross-validation of high-breakdown resampling algorithms for PCA",
%    Computational Statistics and Data Analysis, 51, 5013-5024.
%
% ROBPCA is designed for normally distributed data. If the data are skewed,
% a modification of ROBPCA is available, based on the adjusted outlyingness
% (see adjustedoutlyingness.m). This method is described in:
%
%    Hubert, M., Rousseeuw, P.J., Verdonck, T. (2008),
%    "Robust PCA for skewed data and its outlier map", Computational Statistics
%    and Data Analysis, in press.
%
%  For the up-to-date reference, please consult the website:
%    wis.kuleuven.be/stat/robust.html
%
% Required input arguments:
%            x : Data matrix (observations in the rows, variables in the
%                columns)
%
% Optional input arguments:
%            k : Number of principal components to compute. If k is missing,
%                or k = 0, a scree plot and a press curve are drawn which allows you to select
%                the number of principal components.
%         kmax : Maximal number of principal components to compute (default = 10).
%                If k is provided, kmax does not need to be specified, unless k is larger
%                than 10.
%        alpha : (1-alpha) measures the fraction of outliers the algorithm should
%                resist. Any value between 0.5 and 1 may be specified (default = 0.75).
%            h : (n-h+1) measures the number of outliers the algorithm should
%                resist. Any value between n/2 and n may be specified. (default = 0.75*n)
%                Alpha and h may not both be specified.
%          mcd : If equal to one: when the number of variables is sufficiently small,
%                the loadings are computed as the eigenvectors of the MCD covariance matrix,
%                hence the function 'mcdcov.m' is automatically called. The number of
%                principal components is then taken as k = rank(x). (default)
%                If equal to zero, the robpca algorithm is always applied.
%        plots : If equal to one, a scree plot, a press curve and a robust score outlier map are
%                drawn (default). If the input argument 'classic' is equal to one,
%                the classical plots are drawn as well.
%                If 'plots' is equal to zero, all plots are suppressed (unless k is missing,
%                then the scree plot and press curve are still drawn).
%                See also makeplot.m
%        labsd : The 'labsd' observations with largest score distance are
%                labeled on the outlier map. (default = 3)
%        labod : The 'labod' observations with largest orthogonal distance are
%                labeled on the outlier map. default = 3)
%      classic : If equal to one, the classical PCA analysis will be performed
%                (see also cpca.m). (default = 0)
%        scree : If equal to one, a scree plot is drawn. If k is given as input, the default value is 0, else the default value is one.
%        press : If equal to one, a plot of robust press-values is drawn.
%                If k is given as input, the default value is 0, else the default value is one.
%                If the input argument 'skew' is equal to one, no plot is
%                drawn.
%    robpcamcd : If equal to one (default), the whole robpca procedure is run (computation of outlyingness and
%                MCD).
%                If equal to zero, the program stops after the computation of the outlyingness. The
%                robust eigenvectors then correspond with the eigenvectors of the covariance matrix
%                of the h observations with smallest outlyingness. This yields the same
%                PCA subspace as the full robpca, but not the same eigenvectors and eigenvalues.
%         skew : If equal to zero the regular robpca is run. If equal to
%                one, the adjusted robpca algorithm for skewed data is run.
%
% I/O: result=robpca(x,'k',k,'kmax',10,'alpha',0.75,'h',h,'mcd',1,'plots',1,'labsd',3,'labod',3,'classic',0);
%  The user should only give the input arguments that have to change their default value.
%  The name of the input arguments needs to be followed by their value.
%  The order of the input arguments is of no importance.
%
% Examples:
%    result=robpca(x,'k',3,'alpha',0.65,'plots',0)
%    result=robpca(x,'alpha',0.80,'kmax',15,'labsd',5)
%
% The output of ROBPCA is a structure containing
%
%    result.P        : Robust loadings (eigenvectors)
%    result.L        : Robust eigenvalues
%    result.M        : Robust center of the data
%    result.T        : Robust scores
%    result.k        : Number of (chosen) principal components
%    result.kmax     : Maximal number of principal components
%    result.alpha    : see interpretation in the list of input arguments
%    result.h        : The quantile h used throughout the algorithm
%    result.Hsubsets : A structure that contains H0, H1 and Hfreq:
%                      H0 : The h-subset that contains the h points with the smallest outlyingness.
%                      H1 : The optimal h-subset of mcdcov.
%                      Hfreq : The subset of h points which are the most frequently selected during the mcdcov
%                              algorithm.
%    result.sd       : Robust score distances within the robust PCA subspace
%    result.od       : Orthogonal distances to the robust PCA subspace
%    result.cutoff   : Cutoff values for the robust score and orthogonal distances
%    result.flag     : The observations whose score distance is larger than result.cutoff.sd (==> result.flag.sd)
%                      or whose orthogonal distance is larger than result.cutoff.od (==> result.flag.od)
%                      can be considered as outliers and receive a flag equal to zero (result.flag.all).
%                      The regular observations receive a flag 1.
%    result.class    : 'ROBPCA'
%    result.classic  : If the input argument 'classic' is equal to one, this structure
%                     contains results of the classical PCA analysis (see also cpca.m).
%
% Short description of the method:
%
% Let n denote the number of observations, and p the number of original variables,
% then ROBPCA finds a robust center (p x 1) of the data M and a loading matrix P which
% is (p x k) dimensional. Its columns are orthogonal and define a new coordinate
% system. The scores (n x k) are the coordinates of the centered observations with
% respect to the loadings: T=(X-M)*P.
% Note that ROBPCA also yields a robust covariance matrix (often singular) which
% can be computed as
%                         cov=out.P*out.L*out.P'
%
% To select the number of principal components, it is useful to look at the scree plot which
% shows the eigenvalues, and the press curve which displays a weighted sum of the squared
% cross-validated orthogonal distances.
% The outlier map visualizes the observations by plotting their orthogonal
% distance to the robust PCA subspace versus their robust distances
% within the PCA subspace. This allows to classify the data points into 4 types:
% regular observations, good leverage points, bad leverage points and
% orthogonal outliers.
%
% This function is part of LIBRA: the Matlab Library for Robust Analysis,
% available at:
%              http://wis.kuleuven.be/stat/robust
%
% Written by Mia Hubert, Sabine Verboven, Karlien Vanden Branden, Sanne Engelen, Tim Verdonck
% Last Update: 17/06/2003,  03/07/2006,  31/07/2007
% Last Revision: 27/03/2008, 09/06/2008

%
% initialization with defaults
%
data=x;
[n,p]=size(data);

% First Step: classical PCA on data
if n < p
    [P1,T1,L1,r,Xc,clm]=kernelEVD(data);
else
	[P1,T1,L1,r,Xc,clm]=classSVD(data);
end
% dim(P1): p x r

if r==0
    error('All data points collapse!')
end

niter=100;
counter=1;
kmax=min([10,floor(n/2),r]);
k=0;
alfa=0.75;
h=min(floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*alfa),n);
labsd=3;
labod=3;
plots=1;
scree = 1;
press = 1;
mcd=1; % user wants the mcd approach (in case n>>p)
robpcamcd = 1;
cutoff  = 0.975;
skew=0;
% default is a structure needed for input checking
default=struct('alpha',alfa,'h',h,'labsd',labsd,'labod',labod,...
    'k',k,'plots',plots,'kmax',kmax,'mcd',mcd,'classic',0,'scree',scree,'press',press,'robpcamcd',robpcamcd,'cutoff',cutoff,'skew',0);
list=fieldnames(default);
options=default; %input by user
IN=length(list);
i=1;
%
if nargin==2
    error('Incorrect number of input arguments!')
end
dummy = 0;  %Assume we didn't get h or alpha, unless we find it below.
if nargin>2
    %
    %placing inputfields in array of strings
    %
    for j=1:nargin-2
        if rem(j,2)~=0
            chklist{i}=varargin{j};
            i=i+1;
        end
    end
    dummy=sum(strcmp(chklist,'h')+2*strcmp(chklist,'alpha')); %checking if h and alpha are provided both or not
    switch dummy
    case 0 % Take on default values
        options.alpha=alfa;
        if any(strcmp(chklist,'kmax'))
            for j=1:nargin-2 % searching the index of the accompanying field
                if rem(j,2)~=0 % fieldnames are placed on odd index
                    if strcmp('kmax',varargin{j})
                        I=j;
                    end
                end
            end
            options=setfield(options,'kmax',varargin{I+1});
            kmax = max(min([floor(options.kmax),floor(n/2),r]),1); %acceptable kmax
            options.h=min(floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*alfa),n); %depends on kmax, so if kmax is given by user, get it first!
        else %kmax is not given by user
           options.h=h;
        end
    case 3
        error('Both inputarguments alpha and h are provided. Only one is required.')
    end

    %
    % Checking which default parameters have to be changed
    % and keep them in the structure 'options'.
    %
    while counter<=IN
        index=strmatch(list(counter,:),chklist,'exact');
        if ~isempty(index) % in case of similarity
            for j=1:nargin-2 % searching the index of the accompanying field
                if rem(j,2)~=0 % fieldnames are placed on odd index
                    if strcmp(chklist{index},varargin{j})
                        I=j;
                    end
                end
            end
            options=setfield(options,chklist{index},varargin{I+1});
            index=[];
        end
        counter=counter+1;
    end
    options.h=floor(options.h);
    options.kmax=floor(options.kmax);
    options.k=floor(options.k);
    kmax=max(min([options.kmax,floor(n/2),r]),1);
    labod=max(0,min(floor(options.labod),n));
    labsd=max(0,min(floor(options.labsd),n));
    k=options.k;

    if k<0
        k=0;
    elseif k > kmax
        k=kmax;
        mess=sprintf(['Attention (robpca.m): The number of principal components, k = ',num2str(options.k)...
            ,'\n is larger than kmax= ',num2str(kmax),'; k is set to ',num2str(kmax)]);
        disp(mess)
    end
    if dummy==1 % checking input variable h
        options.alpha=options.h/n;
        if k==0
            if options.h < floor((n+kmax+1)/2 )
                options.h=floor((n+kmax+1)/2);
                options.alpha=options.h/n;
                mess=sprintf(['Attention (robpca.m): h should be larger than (n+kmax+1)/2.\n',...
                        'It is set to its minimum value ',num2str(options.h)]);
                disp(mess)
            end
        else
            if options.h < floor((n+k+1)/2)
                options.h=floor((n+k+1)/2);
                options.alpha=options.h/n;
                mess=sprintf(['Attention (robpca.m): h should be larger than (n+k+1)/2.\n',...
                        'It is set to its minimum value ',num2str(options.h)]);
                disp(mess)
            end
        end
        if options.h > n
            options.alpha=0.75;
            if k==0
                options.h=floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*options.alpha);
            else
                options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*options.alpha);
            end
            mess=sprintf(['Attention (robpca.m): h should be smaller than n. \n',...
                    'It is set to its default value ',num2str(options.h)]);
            disp(mess)
        end
    elseif dummy==2 %checking input variable alpha
        if options.alpha < 0.5
            options.alpha=0.5;
            mess=sprintf(['Attention (robpca.m): Alpha should be larger than 0.5.\n',...
                    'It is set to 0.5.']);
            disp(mess)
        end
        if options.alpha > 1
            options.alpha=0.75;
            mess=sprintf(['Attention (robpca.m): Alpha should be smaller than 1. \n',...
                    'It is set to 0.75.']);
            disp(mess)
        end
        if k==0
            options.h=floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*options.alpha);
        else
            options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*options.alpha);
        end
    end
    alfa=options.alpha;
    dummyh = strcmp(chklist,'h');
    dummykmax = strcmp(chklist,'kmax');
    %     if all(dummyh == 0) & any(dummykmax) & k==0
    %         h = min(floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*alfa),n);
    %     end
    if all(dummyh == 0)&& any(dummykmax) %kmax was given by the user
        if k==0
            options.h=floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*options.alpha);
        else
            options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*options.alpha);
        end
    elseif all(dummyh == 0) && ~any(dummykmax) %kmax is the default value
        if k==0
            options.h=floor(2*floor((n+kmax+1)/2)-n+2*(n-floor((n+kmax+1)/2))*options.alpha);
        else
            options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*options.alpha);
        end
    end
    h=options.h;
    dummyscree = strcmp(chklist,'scree');
    dummypress = strcmp(chklist,'press');
    if all(dummyscree == 0)
        if k~=0
            options.scree = 0;
        end
    end
    if all(dummypress == 0)
        if k~=0
            options.press = 0;
        end
    end
    scree = options.scree;
    press = options.press;
    labsd=floor(max(0,min(options.labsd,n)));
    labod=floor(max(0,min(options.labod,n)));
    plots=options.plots;
    mcd=options.mcd;
    robpcamcd = options.robpcamcd;
    cutoff = options.cutoff;
    skew = options.skew;
    if skew==1
        press=0; %press curve not available for skewed data
    end
end
%
% MAIN PART
%
X=T1;
center=clm;
rot=P1;
% Depending on n and p, perform MCD or ROBPCA:
% p << n => MCD
p1=size(X,2);
if p1<=min(floor(n/5),kmax) && mcd && (skew==0)
    options.h=h;
    [res,raw]=mcdcov(X,'h',h,'plots',0);
    [U,S,P]=svd(res.cov,0);
    L=diag(S);
    if k~=0
        options.k=min(k,p1);
    else
        bdwidth=5;
        topbdwidth=30;
        set(0,'Units','pixels');
        scnsize=get(0,'ScreenSize');
        pos1=[bdwidth, 1/3*scnsize(4)+bdwidth, scnsize(3)/2-2*bdwidth, scnsize(4)/2-(topbdwidth+bdwidth)];
        pos2=[pos1(1)+scnsize(3)/2, pos1(2), pos1(3), pos1(4)];
        if press == 1
            outcvMcd = cvMcd(X,p1,res,h);
            figure('Position',pos1)
            set(gcf,'Name', 'PRESS curve','NumberTitle', 'off');
            plot(1:p1,outcvMcd.press,'o-')
            title('MCD')
            xlabel('number of LV')
            ylabel('R-PRESS')
        end
        if scree == 1
            figure('Position',pos2)
            screeplot(L,'MCD');
        end
        if (scree == 1) || (press == 1)
            cumperc = cumsum(L)./sum(L);
            disp(['The cumulative percentage of variance explained by the first ',num2str(kmax),' components is:']);
            disp(num2str(cumperc'));
            disp(['How many principal components would you like to retain? Max = ',num2str(kmax),'. ']);
            k=input('');
        end
        % to close the figures.
        if scree == 1
            close
        end
        if press == 1
            close
        end
    end
    options.k = k;
    T=(X-repmat(res.center,size(X,1),1))*U;
    out.M=center+res.center*rot';
    out.L=L(1:options.k)';
    out.P=rot*U(:,1:options.k);
    out.T=T(:,1:options.k);
    out.h=h;
    out.k=options.k;
    out.alpha=alfa;
    out.Hsubsets.H0 = res.Hsubsets.Hopt;
    out.Hsubsets.H1 = [];
    out.Hsubsets.Hfreq = res.Hsubsets.Hfreq;
    out.skew=skew;
else
    % p > n => ROBPCA
    niter=100;
    seed=0;
    if h~=n
        if skew==0
            B=twopoints(T1,250,seed); %n*ri
            for i=1:size(B,1)
                Bnorm(i)=norm(B(i,:),2);
            end
            Bnormr=Bnorm(Bnorm > 1.e-12); %ndirect*1
            B=B(Bnorm > 1.e-12,:);       %ndirect*n
            A=diag(1./Bnormr)*B;         %ndirect*n
            %projected points in columns
            Y=T1*A';%n*ndirect
            m=length(Bnormr);
            Z=zeros(n,m);
            for i=1:m
                [tmcdi,smcdi,weights]=unimcd(Y(:,i),h);
                if smcdi<1.e-12
                    r2=rank(data(weights,:));
                    if r2==1
                        error(['At least ',num2str(sum(weights)),' obervations are identical.']);
                    end
                else
                    Z(:,i)=abs(Y(:,i)-tmcdi)/smcdi;
                end
            end
            d=max(Z,[],2);
        else %adjusted robpca for skewed data
            outAO=adjustedoutlyingness(T1,'ndir',min(250*p,2500));
            d=outAO.adjout;
        end
        [ds,is]=sort(d);
        Xh=T1(is(1:h),:); % Xh contains h (good) points out of Xcentr
        [P2,T2,L2,r2,Xm,clmX]=classSVD(Xh);
        out.Hsubsets.H0 = is(1:h);
        Tn=(T1-repmat(clmX,n,1))*P2;
    else
        P2=eye(r);
        Tn=T1;
        L2=L1;
        r2=r;
        out.Hsubsets.H0=1:n;
        Xm=T1;
        clmX=zeros(1,size(T1,2));
    end

    %dim(P2) = r x r2
    L=L2;
    kmax=min(r2,kmax);

    % choice of k:
    %-------------
    bdwidth=5;
    topbdwidth=30;
    set(0,'Units','pixels');
    scnsize=get(0,'ScreenSize');
    pos1=[bdwidth, 1/3*scnsize(4)+bdwidth, scnsize(3)/2-2*bdwidth, scnsize(4)/2-(topbdwidth+bdwidth)];
    pos2=[pos1(1)+scnsize(3)/2, pos1(2), pos1(3), pos1(4)];

    if press == 1
        disp('The robust press curve based on cross-validation is now computed.')
        outprMCDkmax = projectMCD(Tn,L,kmax,h,niter,rot,P1,P2,center,cutoff);
        if size(out.Hsubsets.H0,2)==1
            out.Hsubsets.H0=out.Hsubsets.H0';
        end
        outprMCDkmax.Hsubsets.H0 = out.Hsubsets.H0;
        outpress = cvRobpca(data,kmax,outprMCDkmax,0,h);
        figure('Position',pos1)
        set(gcf,'Name', 'PRESS curve','NumberTitle', 'off');
        plot(1:kmax,outpress.press,'o-')
        title('ROBPCA')
        xlabel('Number of LV')
        ylabel('R-PRESS')
    else
        if size(out.Hsubsets.H0,2)==1
            out.Hsubsets.H0=out.Hsubsets.H0';
        end
    end

    if scree == 1
        figure('Position',pos2)
        screeplot(L(1:kmax),'ROBPCA')
    end

    if (scree == 1)||(press == 1)
        cumperc = (cumsum(L(1:kmax))./sum(L))';
        disp(['The cumulative percentage of variance explained by the first ',num2str(kmax),' components is:']);
        disp(num2str(cumperc));
        disp(['How many principal components would you like to retain? Max = ',num2str(kmax),'.']);
        k=input('');
        k=max(min(min(r2,k),kmax),1);
        % we compute again the robpca results for a specific k value. alpha
        % and h can change again, because until now they were based on the kmax
        % value.
        if dummy == 2
            options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*alfa);
            %if dummy == 1 no changes needed
        elseif dummy~=1
            options.h=floor(2*floor((n+k+1)/2)-n+2*(n-floor((n+k+1)/2))*options.alpha);
        end
        h=options.h;
        % to close the figures.
        if scree == 1
            close
        end
        if press == 1
            close
        end
    else
        k=min(min(r2,k),kmax);
    end

    if k~=r % extra reweighting step
        XRc=T1-repmat(clmX,n,1);
        Xtilde=XRc*P2(:,1:k)*P2(:,1:k)';
        Rdiff = XRc-Xtilde;
        for i=1:n
            odh(i,1)=norm(Rdiff(i,:));
        end
        if skew==0
            [m,s]=unimcd(odh.^(2/3),h);
            cutoffodh = sqrt(norminv(cutoff,m,s).^3);
        else %adjusted robpca for skewed data
            mcodh=mc(odh);
            if mcodh>0
                cutoffodh = prctile(odh,75)+1.5*exp(3*mcodh)*iqr(odh);
            else
                cutoffodh = prctile(odh,75)+1.5*iqr(odh);
            end
            ttup = sort(-odh(odh<cutoffodh));
            cutoffodh = -ttup(1);
        end
        indexset = find(odh<=cutoffodh)';
        [P2,Th,Lh,rh,Xm,clmX]=classSVD(T1(indexset,:));
        if k>rh
            k = rh;
        end
    end
    center=center+clmX*rot';
    rot=rot*P2(:,1:k);
    Tn=(T1-repmat(clmX,n,1))*P2;

    % if only the subspace is important, not the PC themselves: do not
    % perform MCD anymore.
    if ~robpcamcd
        out.P = rot; %=P1*P2(:,1:k);
        out.T = Tn(:,1:k);
        out.M = center;
        out.L = Lh;
        out.k = k;
        out.h = h;
        out.alpha = alfa;
        out.kmax=kmax;
        out.skew=skew;
    end

    % projection, mcd
    %-----------------
    if skew==0
        outpr = projectMCD(Tn,L,k,h,niter,rot,P1,P2,center,cutoff);
    else %adjusted robpca for skewed data
        outpr = projectAO(Tn,k,h,rot,center);
    end
    out.T = outpr.T;
    out.P = outpr.P;
    out.M = outpr.M;
    out.L = outpr.L;
    out.k = k;
    out.kmax=kmax;
    out.h = h;
    out.alpha = alfa;
    out.skew = skew;
    if skew==0
        out.Hsubsets.H1 = outpr.Hsubsets.H1;
        out.Hsubsets.Hfreq = outpr.Hsubsets.Hfreq;
    else
        out.AO=outpr.AO;
        out.cutoff.AO=outpr.cutoff.AO;
    end
end

% Classical analysis
if options.classic==1
    out.classic.P=P1(:,1:out.k);
    out.classic.L=L1(1:out.k)';
    out.classic.M=clm;
    out.classic.T=T1(:,1:out.k);
    out.classic.k=out.k;
    out.classic.Xc=Xc;
end

outpr = out;

% Calculation of the distances, flags
%-------------------------------------

if options.classic == 1
    outDist = CompDist(data,r,outpr,cutoff,robpcamcd,out.classic);
else
    outDist = CompDist(data,r,outpr,cutoff,robpcamcd);
end

out.sd = outDist.sd;
out.cutoff.sd = outDist.cutoff.sd;
out.od = outDist.od;
out.cutoff.od = outDist.cutoff.od;
out.flag = outDist.flag;
out.class = outDist.class;
out.classic = outDist.classic;
if options.classic == 1
    out.classic.sd = outDist.classic.sd;
    out.classic.od = outDist.classic.od;
    out.classic.cutoff.sd = outDist.classic.cutoff.sd;
    out.classic.cutoff.od = outDist.classic.cutoff.od;
    out.classic.class = outDist.classic.class;
    out.classic.flag = outDist.classic.flag;
end

result=struct('P',{out.P},'L',{out.L},'M',{out.M},'T',{out.T},'k',{out.k},'kmax',{kmax},'alpha',{out.alpha},...
    'h',{out.h},'Hsubsets',{out.Hsubsets},'sd', {out.sd},'od',{out.od},'cutoff',{out.cutoff},'flag',out.flag',...
    'class',{out.class},'classic',{out.classic});

% Plots
try
    if plots && options.classic
        makeplot(result,'classic',1,'labsd',labsd,'labod',labod)
    elseif plots
        makeplot(result,'labsd',labsd,'labod',labod)
    end
catch %output must be given even if plots are interrupted
    %> delete(gcf) to get rid of the menu
end

%--------------------------------------------------------------------------
function outprMCD = projectMCD(Tn,L,k,h,niter,rot,P1,P2,center,cutoff)

% this function performs the last part of ROBPCA when k is determined.
% input :
%   Tn : the projected data
%   L  : the matrix of the eigenvalues
%   k  : the number of components
%   h  : lower bound for regular observations
%   niter : the number of iterations
%   rot : the rotation matrix
%   P1, P2: the different eigenvector matrices after each transformation
%   center : the classical center of the data

X2=Tn(:,1:k);
n = size(X2,1);
rot=rot(:,1:k);
% first apply c-step with h points from first step,i.e. those that
% determine the covariance matrix after the c-steps have converged.
mah=libra_mahalanobis(X2,zeros(size(X2,2),1),'cov',L(1:k));
oldobj=prod(L(1:k));
P4=eye(k);
korig=k;
for j=1:niter
    [mahs,is]=sort(mah);
    Xh=X2(is(1:h),:);
    [P,T,L,r3,Xm,clmX]=classSVD(Xh);
    obj=prod(L);
    X2=(X2-repmat(clmX,n,1))*P;
    center=center+clmX*rot';
    rot=rot*P;
    mah=libra_mahalanobis(X2,zeros(size(X2,2),1),'cov',diag(L));
    P4=P4*P;
    if ((r3==k) && (abs(oldobj-obj) < 1.e-12))
        break;
    else
        oldobj=obj;
        j=j+1;
        if r3 < k
            j=1;
            k=r3;
        end
    end
end
% dim(P4): k x k0 with k0 <= k but denoted as k
% dim X2: n x k0
% perform mcdcov on X2
[zres,zraw]= mcdcov(X2,'plots',0,'ntrial',250,'h',h,'file',0);
out.resMCD = zres;
if zraw.objective < obj
    z = zres;
    out.Hsubsets.H1 = zres.Hsubsets.Hopt;
else
    sortmah = sort(mah);
    if h==n
        factor=1;
    else
        factor = sortmah(h)/chi2inv(h/n,k);
    end
    mah = mah/factor;
    weights = mah <= chi2inv(cutoff,k);
    [center_noMCD,cov_noMCD] = weightmecov(X2,weights);
    mah = libra_mahalanobis(X2,center_noMCD,'cov',cov_noMCD);
    z.flag = (mah <= chi2inv(cutoff,k));
    z.center = center_noMCD;
    z.cov = cov_noMCD;
    out.Hsubsets.H1 = is(1:h);
end
covf=z.cov;
centerf=z.center;
[P6,L]=eig(covf);
[L,I]=greatsort(diag(real(L)));
P6=P6(:,I);
out.T=(X2-repmat(centerf,n,1))*P6;
P=P1*P2;
out.P=P(:,1:korig)*P4*P6;
centerfp=center+centerf*rot';
out.M=centerfp;
out.L=L';
out.k=k;
out.h=h;

% creation of Hfreq
out.Hsubsets.Hfreq = zres.Hsubsets.Hfreq(1:h);

outprMCD = out;
%----------------------------------------------------------------------------
function outprAO = projectAO(Tn,k,h,rot,center)

% this function performs the last part of ROBPCA when k is determined.
% input :
%   Tn : the projected data
%   k  : the number of components
%   h  : lower bound for regular observations
%   rot : the rotation matrix
%   center : the classical center of the data

seed=0;
X2=Tn(:,1:k);
[n,p]=size(X2);
outAO=adjustedoutlyingness(X2,'ndir',min(250*p,2500));
AO=outAO.adjout;
cutoffAO=outAO.cutoff;
indexset = find(AO<=cutoffAO)';
%SVD
[P6,T6,L6,r6,Xm6,clmX6]=classSVD(X2(indexset,:));
out.T = (X2-repmat(clmX6,n,1))*P6;
out.P = rot*P6;
out.M = center+clmX6*rot';
out.L = L6;
out.k = k;
out.h = h;
out.AO=AO;
out.cutoff.AO=cutoffAO;
outprAO=out;

%--------------------------------------------------------------------------------
function outDist = CompDist(data,r,out,cutoff,robpcamcd,classic)

% Calculates the distances.
% input: data : the original data
%           r : the rank of the data
%        out is a structure that contains the results of the PCA.
%        classic: an optional structure:
%               classic.P1
%               classic.T1
%               classic.L1
%               classic.clm
%               classic.Xc

if nargin < 6
    options.classic = 0;
else
    options.classic = 1;
end

n = size(data,1);
p = size(data,2);
k = out.k;
skew=out.skew;

% Computing distances
% Robust score distances in robust PCA subspace
if robpcamcd
    if skew==0
        out.sd=sqrt(libra_mahalanobis(out.T,zeros(size(out.T,2),1),'cov',out.L))';
        out.cutoff.sd=sqrt(chi2inv(cutoff,out.k));
    else
        out.sd=out.AO;
        out.cutoff.sd=out.cutoff.AO;
    end
else
    out.sd=zeros(n,1);
    out.cutoff.sd=0;
end
% Orthogonal distances to robust PCA subspace
XRc=data-repmat(out.M,n,1);
Xtilde=out.T*out.P';
Rdiff=XRc-Xtilde;
for i=1:n
    out.od(i,1)=norm(Rdiff(i,:));
end
% Robust cutoff-value for the orthogonal distance
if k~=r
    if skew==0
        [m,s]=unimcd(out.od.^(2/3),out.h);
        out.cutoff.od = sqrt(norminv(cutoff,m,s).^3);
    else
        mcod=mc(out.od);
        if mcod>0
            out.cutoff.od = prctile(out.od,75)+1.5*exp(3*mcod)*iqr(out.od);
        else
            out.cutoff.od = prctile(out.od,75)+1.5*iqr(out.od);
        end
        ttup = sort(-out.od(out.od<out.cutoff.od));
        out.cutoff.od = -ttup(1);
    end
else
    out.cutoff.od=0;
end
if options.classic==1
    % Mahalanobis distance in classical PCA subspace
    Tclas=classic.Xc*classic.P(:,1:out.k);
    out.classic.sd=sqrt(libra_mahalanobis(Tclas,zeros(size(Tclas,2),1),'invcov',1./classic.L(1:out.k)))';
    % Orthogonal distances to classical PCA subspace
    Xtilde=Tclas*classic.P(:,1:out.k)';
    Cdiff=classic.Xc-Xtilde;
    for i=1:n
        out.classic.od(i,1)=norm(Cdiff(i,:));
    end
    out.classic.cutoff.sd=sqrt(chi2inv(cutoff,out.k)); % should be defined after od to have the output in the correct order
    % Classical cutoff-values
    if k~=r
        m=mean(out.classic.od.^(2/3));
        s=sqrt(var(out.classic.od.^(2/3)));
        out.classic.cutoff.od = sqrt(norminv(cutoff,m,s)^3);
    else
        out.classic.cutoff.od=0;
    end
    out.classic.cutoff.sd=sqrt(chi2inv(cutoff,out.k));
    out.classic.flag.od=(out.classic.od<=out.classic.cutoff.od);
    out.classic.flag.sd=(out.classic.sd<=out.classic.cutoff.sd);
    out.classic.flag.all=(out.classic.flag.od)&(out.classic.flag.sd);
    out.classic.class='CPCA';
else
    out.classic=0;
end

out.class='ROBPCA';

if k~=r
    out.flag.od=(out.od<=out.cutoff.od);
    out.flag.sd=(out.sd<=out.cutoff.sd);
    out.flag.all=(out.flag.od)&(out.flag.sd);
else
    out.flag.od=(out.od<=out.cutoff.od);
    out.flag.sd=(out.sd<=out.cutoff.sd);
    out.flag.all=(out.sd<=out.cutoff.sd);
end

outDist = out;


function geometry_test0243 ( )

%*****************************************************************************80
%
%% TEST0243 tests R8VEC_ANY_NORMAL.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  dim_num = 10;
  test_num = 5;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST0243\n' );
  fprintf ( 1, '  R8VEC_ANY_NORMAL computes a vector V2 that is normal\n' );
  fprintf ( 1, '  to a given vector V1.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    Test    ||V1||      ||V2||        V1.V2\n' );
  fprintf ( 1, '\n' );

  seed = 123456789;

  for test = 1 : test_num

    [ v1, seed ] = r8vec_uniform_01 ( dim_num, seed );
    v1_length = r8vec_norm ( dim_num, v1 );
    v2 = r8vec_any_normal ( dim_num, v1 );
    v2_length = r8vec_norm ( dim_num, v2 );
    v1v2_dot = v1(1:dim_num) * v2(1:dim_num)';
    fprintf ( 1, '  %6d  %10f  %10f  %10f\n', ...
      test, v1_length, v2_length, v1v2_dot );
  end

  return
end


%channel_estimation.m
% for LS/DFT Channel Estimation with linear/spline interpolation
clear all;
close all;
clf;
% figure(1), clf
% figure(2), clf
Nfft=512;
Ng=Nfft/8;
Nofdm=Nfft+Ng;
Nsym=100;
Nps=32;
Np=Nfft/Nps;
Nd=Nfft-Np; % Pilot spacing, Numbers of pilots and data per OFDM symbol
Nbps=4;
M=2^Nbps; % Number of bits per (modulated) symbol
mod_object = modem.qammod('M',M, 'SymbolOrder','gray');
demod_object = modem.qamdemod('M',M, 'SymbolOrder','gray');
Es=1;
A=sqrt(3/2/(M-1)*Es); % Signal energy and QAM normalization factor
%fs = 10e6;  ts = 1/fs;  % Sampling frequency and Sampling period
SNRs = [30];
sq2=sqrt(2);
for i=1:length(SNRs)
   SNR = SNRs(i);
   rand('seed',1);
   randn('seed',1);
   MSE = zeros(1,6);
   nose = 0;
   for nsym=1:Nsym
      Xp = 2*(randn(1,Np)>0)-1;    % Pilot sequence generation
      %Data = ((2*(randn(1,Nd)>0)-1) + j*(2*(randn(1,Nd)>0)-1))/sq2; % QPSK modulation
      msgint=randint(1,Nfft-Np,M);    % bit generation
      Data = modulate(mod_object,msgint)*A;
      %Data = modulate(mod_object, msgint);
      %Data = modnorm(Data,'avpow',1)*Data;   % normalization
      ip = 0;
      pilot_loc = [];
      for k=1:Nfft
         if mod(k,Nps)==1
            X(k) = Xp(floor(k/Nps)+1);
            pilot_loc = [pilot_loc k];
            ip = ip+1;
         else
             X(k) = Data(k-ip);
         end
      end
      x = ifft(X,Nfft);                            % IFFT
      xt = [x(Nfft-Ng+1:Nfft) x];                  % Add CP
      h = [(randn+j*randn) (randn+j*randn)/2];     % generates a (2-tap) channel
      H = fft(h,Nfft);
      channel_length = length(h); % True channel and its time-domain length
      H_power_dB = 10*log10(abs(H.*conj(H)));      % True channel power in dB
      y_channel = conv(xt, h);                     % Channel path (convolution)
      sig_pow = mean(y_channel.*conj(y_channel));
      %y_aw(1,1:Nofdm) = y(1,1:Nofdm) + ...
      %   sqrt((10.^(-SNR/10))*sig_pow/2)*(randn(1,Nofdm)+j*randn(1,Nofdm)); % Add noise(AWGN)
      yt = awgn(y_channel,SNR,'measured');
      y = yt(Ng+1:Nofdm);                   % Remove CP
      Y = fft(y);                           % FFT
      for m=1:3
         if m==1
             H_est = LS_CE(Y,Xp,pilot_loc,Nfft,Nps,'linear');
             method='LS-linear'; % LS estimation with linear interpolation
         elseif m==2
             H_est = LS_CE(Y,Xp,pilot_loc,Nfft,Nps,'spline');
             method='LS-spline'; % LS estimation with spline interpolation
         else
             H_est = MMSE_CE(Y,Xp,pilot_loc,Nfft,Nps,h,SNR);
             method='MMSE'; % MMSE estimation
         end
         H_est_power_dB = 10*log10(abs(H_est.*conj(H_est)));
         h_est = ifft(H_est);
         h_DFT = h_est(1:channel_length);
         H_DFT = fft(h_DFT,Nfft); % DFT-based channel estimation
         H_DFT_power_dB = 10*log10(abs(H_DFT.*conj(H_DFT)));
         if nsym==1
           figure(1)
           subplot(319+2*m)
           plot(H_power_dB,'b','linewidth',1);
           grid on;
           hold on;
           plot(H_est_power_dB,'r:+','Markersize',4,'linewidth',1);
           %axis([0 32 -6 10])
           title(method);
           xlabel('Subcarrier Index');
           ylabel('Power[dB]');
           legend('True Channel',method,4);
           set(gca,'fontsize',9)
           subplot(320+2*m)
           plot(H_power_dB,'b','linewidth',1);
           grid on;
           hold on;
           plot(H_DFT_power_dB,'r:+','Markersize',4,'linewidth',1);
           %axis([0 32 -6 10])
           title([method ' with DFT']);
           xlabel('Subcarrier Index');
           ylabel('Power[dB]');
           legend('True Channel',[method ' with DFT'],4);
           set(gca,'fontsize',9)
         end
         MSE(m) = MSE(m) + (H-H_est)*(H-H_est)';
         MSE(m+3) = MSE(m+3) + (H-H_DFT)*(H-H_DFT)';
      end
      Y_eq = Y./H_est;
      if nsym>=Nsym-10
          figure(2)
          subplot(221)
          plot(Y,'.','Markersize',5)
          axis([-1.5 1.5 -1.5 1.5])
          axis('equal')
          set(gca,'fontsize',9)
          hold on,
          subplot(222)
          plot(Y_eq,'.','Markersize',5)
          axis([-1.5 1.5 -1.5 1.5])
          axis('equal')
          set(gca,'fontsize',9)
          hold on,
      end
      ip = 0;
      for k=1:Nfft
         if mod(k,Nps)==1
             ip=ip+1;
         else
             Data_extracted(k-ip)=Y_eq(k);
         end
      end
      msg_detected = demodulate(demod_object,Data_extracted/A);
      nose = nose + sum(msg_detected~=msgint);
   end
   MSEs(i,:) = MSE/(Nfft*Nsym);
end
Number_of_symbol_errors=nose
figure(3)%, clf
semilogy(SNRs',MSEs(:,1),'-x', SNRs',MSEs(:,3),'-o')
legend('LS-linear','MMSE')
fprintf('MSE of LS-linear/LS-spline/MMSE Channel Estimation = %6.4e/%6.4e/%6.4e\n',MSEs(end,1:3));
fprintf('MSE of LS-linear/LS-spline/MMSE Channel Estimation with DFT = %6.4e/%6.4e/%6.4e\n',MSEs(end,4:6));


% test for denoising using Non Local Means vs Wavelets
%
%   Copyright (c) 2007 Gabriel Peyre

path(path, 'toolbox/');

if not(exist('name'))
    name = 'peppers';
    name = 'polygons_blurred';
    name = 'boat';
    name = 'mandrill';
    name = 'lenacoul';
    name = 'lena';
    name = 'images/corral';
    name = 'barb';
end

%% load image
n = 64*2;
n0 = [];
M = load_image(name, n0);
c = size(M)/2;
if strcmp(name, 'lena') && n==128
    c = [120 200]; % lena hat
end
if strcmp(name, 'mandrill') && n==128
    c = [350 350];
end
eta = 0.12;
M0 = rescale( crop(M,n,c), eta, 1-eta );
s = size(M0,3); % number of colors

%% add some Gaussian noise
sigma = 0.06 * max( M0(:) );
randn('state',1234);    % to have reproductible results
M = M0 + randn(n,n,s)*sigma;
% approx wavelet threshold
T = 3*sigma;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TI Wavelets
clear options;
options.wavelet_type = 'biorthogonal';
options.wavelet_vm = 3;
Jmin = 4;
options.decomp_type = 'quad';
MW = perform_atrou_transform(M,Jmin,options);
disp('--> Computing best threshold (wavelets).');
Twav = compute_best_threshold('wavelet',M,M0,sigma, options);
MWT = perform_thresholding(MW, T);
MW1 = perform_atrou_transform(MWT,Jmin,options);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Portilla and Simoncelli method
options.sigma = sigma;
options.repres2 = 'daub3';
options.parent = 1;
disp('--> BLS-GSM denoising.');
ML1 = perform_blsgsm_denoising(M, options);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Non-local means
% options of NL means  (15,30)
options.max_dist = 5;  % search width, the smaller the faster the algorithm will be
options.ndims = 40;     % number of dimension used for distance computation (PCA dim.reduc. to speed up)
options.do_patchwise = 0;
options.mask = 'linear';
options.mask = 'cst';
disp('--> NLMeans denoising.');
options.Tlist = linspace(0.02,0.07,12);
options.klist = [4 5];
[tmp,options] = compute_best_threshold('nlmeans',M,M0,sigma, options);
[MN1,Wx,Wy] = perform_nl_means(M, options);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Non-local patchwise
do_patchwise = 1;
if do_patchwise
options.do_patchwise = 1;
disp('--> NLMeans denoising.');
[tmp,options] = compute_best_threshold('nlmeans',M,M0,sigma, options);
[MNpwise1,Wx,Wy] = perform_nl_means(M, options);
end

pnoisy = psnr(M,M0);
pwav = psnr(M0,MW1);
pbls= psnr(M0,ML1);
pnlm= psnr(M0,MN1);
if do_patchwise
    pnlpwise = psnr(M0,MNpwise1);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Display
imgs = {M0 M MW1 ML1 MN1};
opts =  {'Original' sprintf('Noisy,psnr=%.2f', pnoisy) sprintf('Wav,psnr=%.2f', pwav) ...
        sprintf('BLS,psnr=%.2f(+%.2f)', pbls, pbls-pwav) ...
        sprintf('NLMeans,psnr=%.2f(+%.2f)', pnlm, pnlm-pwav) };
if do_patchwise
    imgs{end+1} = MNpwise1;
    opts{end+1} = sprintf('NLMedian,psnr=%.2f(+%.2f)', pnlpwise, pnlpwise-pwav);
end
display_image_layout(imgs, opts );

% save
repimg = ['results/denoising/'];
if not(exist(repimg))
    mkdir(repimg);
end
saveas(gcf, [repimg name '-denoising.png'], 'png');

repimg = ['results/denoising/' name '/'];
if not(exist(repimg))
    mkdir(repimg);
end

%% write results
fid = fopen([repimg name '-results.txt'], 'a');
fprintf(fid, '--> %s: n=%d, max_dist=%d, ndims=%d, sigma=%.2f, k=%d, T=%.2f, mask=%s\n', name, n, ...
        options.max_dist, options.ndims, sigma, options.k, options.T, options.mask);
fprintf(fid, 'Noisy    %.4f\n', pnoisy);
fprintf(fid, 'Wavelets %.4f\n', pwav);
fprintf(fid, 'BLS-GSM  %.4f (+%.4f)\n', pbls, pbls-pwav);
fprintf(fid, 'NL-Means %.4f (+%.4f)\n', pnlm, pnlm-pwav);
if do_patchwise
    fprintf(fid, 'NL-Median %.4f (+%.4f)\n', pnlpwise, pnlpwise-pwav);
end
fclose(fid);

% scaling for method noise
s = std(M0(:)-MW1(:))*6;

%% save images
warning off;
imwrite(clamp(M0), [repimg name '-original.png'], 'png');
imwrite(clamp(M), [repimg name '-noisy.png'], 'png');
imwrite(clamp(MW1), [repimg name '-wavelets.png'], 'png');
imwrite(clamp(ML1), [repimg name '-blsgsm.png'], 'png');
imwrite(clamp(MN1), [repimg name '-nlmeans.png'], 'png');
imwrite(clamp( 0.5+ (M-MW1)/s ) , [repimg name '-wavelets-methnoise.png'], 'png');
imwrite(clamp( 0.5+ (M-ML1)/s ) , [repimg name '-blsgsm-methnoise.png'], 'png');
imwrite(clamp( 0.5+ (M-MN1)/s ) , [repimg name '-nlmeans-methnoise.png'], 'png');
if do_patchwise
imwrite(clamp(MNpwise1), [repimg name '-nlpatchwise.png'], 'png');
imwrite(clamp( 0.5+ (M-MNpwise1)/s ) , [repimg name '-nlpatchwise-methnoise.png'], 'png');
end
warning off;


function [v,x,t,m,ze]=v_quadpeak(z)
%V_PEAK2DQUAD find quadratically-interpolated peak in a N-D array
%
%  Inputs:  Z(m,n,...)   is the input array (ignoring trailing singleton dimensions)
%                        Note: a row vector will have 2 dimensions
%
% Outputs:  V        is the peak value
%           X(:,1)  is the position of the peak (in fractional subscript values)
%           T        is -1, 0, +1 for maximum, saddle point or minimum
%           M        defines the fitted quadratic: z = [x y ... 1]*M*[x y ... 1]'
%           ZE       the estimated version of Z

%	   Copyright (C) Mike Brookes 2008
%      Version: $Id: v_quadpeak.m 10865 2018-09-21 17:22:45Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

persistent wz a
% first calculate the fixed matrix, a (can be stored if sz is constant)
sz=size(z);         % size of input array
psz=prod(sz);       % number of elements in input array
dz=numel(sz);       % number of input dimensions
mz=find(sz>1);      % non-singleton dimension indices
nm=numel(mz);       % number of non-singleton dimensions
vz=sz(mz);          % size of squeezed input array
dx=max(mz);         % number of output dimensions
if ~nm              % if the input array is a scalar
    error('Cannot find peak of a scalar');
end
nc=(nm+1)*(nm+2)/2;  % number of columns in A matrix
if min(vz)<3
    error('Need at least 3 points in each non-singleton dimension');
end
if isempty(wz) || numel(wz)~=numel(vz) || ~all(wz==vz)
    wz=vz;
    a=ones(psz,nc);
    ix=(0:psz-1)';
    for i=1:nm
        jx=floor(ix/sz(mz(i)));
        a(:,i+nc-nm-1)=1+ix-jx*sz(mz(i));
        ix=jx;
        a(:,(i^2-i+2)/2:i*(i+1)/2)=a(:,nc-nm:i+nc-nm-1).*repmat(a(:,i+nc-nm-1),1,i);
    end
    a=(a'*a)\a';        % converts to polynomial coeficients {x^2 xy y^2 x y 1]
end

% now find the peak

c=a*z(:);   % polynomial coefficients for this data
w=zeros(nm+1,nm+1);
i=1:(nm+1)*(nm+2)/2;
j=floor((sqrt(8*i-7)-1)/2);
w(i+j.*(2*nm+1-j)/2)=c;
w=(w+w.')/2; % make it symmetrical
mr=w(1:nm,1:nm);
we=w(1:nm,nm+1);
y=-(mr\we);
v=y'*we+w(nm+1,nm+1);  % value at peak

% insert singleton dimensions into outputs

x=zeros(dx,1);
x(mz)=y;
m=zeros(dx+1,dx+1);
mz(nm+1)=dx+1;
m(mz,mz)=w;
if nargout>2
    ev=eig(mr);
    t=all(ev>0)-all(ev<0);
end
if nargout>4
    ze=zeros(sz);
    scp=cumprod([1 sz(1:end-1)]);
    ivec=fix(repmat((0:psz-1)',1,dz)./repmat(scp,psz,1));
    xe=[1+ivec-repmat(sz,psz,1).*fix(ivec./repmat(sz,psz,1)) ones(psz,1)];
    ze=reshape(sum((xe*m).*xe,2),sz);
end

if ~nargout && nm<=2
    % plot the data
    desc={'Maximum','Saddle Point','Minimum'};
    if nargout<=2
        ev=eig(mr);
        t=all(ev>0)-all(ev<0);
    end
    if nm==1
        xax=linspace(1,psz,100);
        plot(xax,c(1)*xax.^2+c(2)*xax+c(3),'-r',1:psz,z(:),'ob',x,v,'^k');
        set(gca,'xlim',[0.9 psz+0.1]);
        ylabel('z');
        xlabel(sprintf('x%d',mz(1)));
        title(sprintf('\\Delta = %s: z(%.2g) = %.2g',desc{t+2},y(1),v));
    else
        ngr=17;
        xax=repmat(linspace(1,vz(1),ngr)',1,ngr);
        yax=repmat(linspace(1,vz(2),ngr),ngr,1);
        zq=(c(1)*xax+c(2)*yax+c(4)).*xax+(c(3)*yax+c(5)).*yax+c(6);
        hold off
        mesh(xax,yax,zq,'EdgeColor','r');
        hold on
        plot3(repmat((1:vz(1))',1,vz(2)),repmat(1:vz(2),vz(1),1),reshape(z,vz),'ob',y(1),y(2),v,'^k');
        hold off
        set(gca,'xlim',[0.9 vz(1)+0.1],'ylim',[0.9 vz(2)+0.1]);
        xlabel(sprintf('x%d',mz(1)));
        ylabel(sprintf('x%d',mz(2)));
        zlabel('z');
        title(sprintf('\\Delta = %s: z(%.2g,%.2g) = %.2g',desc{t+2},y(1),y(2),v));
    end
end


function bc = specific_bc(xbd,ybd)
%solution4_bc   Reference problem 1.4  boundary condition
%   bc = specific_bc(xbd,ybd);
%   input
%          xbd          x boundary coordinate vector
%          ybd          y boundary coordinate vector
%   IFISS function: DJS; 28 February 2005.
% Copyright (c) 2005 D.J. Silvester, H.C. Elman, A. Ramage
bc=(xbd.^2+ybd.^2).^(1/3) .*sin((pi+2*atan2(ybd,xbd))/3);
return


      function [A, phi, f] = amplitude_spectrum(td)
         %amplitude_spectrum   Simple method to compute amplitude
         %   spectrum for a trace. Uses the MATLAB fft function.
         %   [A, phi, f] = amplitude_spectrum(td)
         %
         %   Inputs:
         %       td - a single TraceData
         %
         %   Outputs:
         %       A - the amplitude coefficients
         %       phi - the phase coefficients
         %       f - the frequency values corresponding to elements of A and phi
         %
         %   Example:
         %       [A phi, f] = amplitude_spectrum(td)
         %       plot(f,A);
         %       xlabel('Frequency (Hz)')
         %       ylabel('Amplitude');
         %
         %   See also fft
         %   Glenn Thompson, November 21, 2014

         %TODO: Rename this to amplitudespectrum or move it elsewhere

         N = length(td.data);
         NFFT = 2 ^ nextpow2(N); % Next power of 2 from length of y
         Y = fft(td.data, NFFT); % X will have same length as signal, and will be complex with a magnitude and phase
         A = 2 * abs(Y(1:NFFT/2+1)) / N;
         phi = angle(Y);
         f = td.samplerate / 2 * linspace(0,1,NFFT/2+1);
      end


function R = p2p_rcu(a, n_vals, eps)
% Compute the achievable sum rate (at the symmetrical rate point) from the point-to-point RCU bound
% for the joint source distribution: [a 1/3*(1-a); 1/3*(1-a) 1/3*(1-a)].

% Input:
% a: parameter to define the joint source distribution, should be in range [0.25, 1)
% n_vals: a vector containing the blocklengths
% eps: target error probability
% Output:
% R: the achievable rates for the blocklengths specified in n_vals.

    p = [a 1/3*(1-a); 1/3*(1-a) 1/3*(1-a)];
    H = sum(sum(p.*log(1./p)));  % Source joint entropy

    % Compute log binomial coefficients
    log_b = binomial_coeff(max(n_vals));

    R = zeros(length(n_vals),1);

    for i = 1:length(n_vals)
        n = n_vals(i);
        m = 0:n;  % Number of occurrence of the largest joint probability mass
        % log_Pr stores all the log probabilities in descending order
        log_Pr = m*log(a)+(n-m)*log(1/3*(1-a));

        % [x, y]: initial range for the bisection algorithm
        x = H;
        y = H + 2;
        %%%%%%%%%% Use this part to check if the range is valid for bisection algorithm %%%%%%%%%%
        c = x;
        log_indicator = zeros(1,n+1);
        for j = 0:n
            log_indicator(j+1) = min(0, my_logsumexp(log_b{n+1}(j+1:n+1)+(n-(j:n))*log(3))-n*c);
        end
        err = exp(my_logsumexp(log_Pr + log_b{n+1} + (n-m)*log(3) + log_indicator));
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        % Start of bisection iteration
        iter = 0;
        while abs(x - y) > 0.00001 && iter <= 25
            c = (x+y)/2;
            %%%%%%%%%%%%%%%% body of iteration %%%%%%%%%%%%%%%%
            log_indicator = zeros(1,n+1);
            for j = 0:n
                log_indicator(j+1) = min(0, my_logsumexp(log_b{n+1}(j+1:n+1)+(n-(j:n))*log(3))-n*c);
            end
            err = exp(my_logsumexp(log_Pr + log_b{n+1} + (n-m)*log(3) + log_indicator));
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            if err - eps < 0
                y = c;
            else
                x = c;
            end
            iter = iter + 1;
        end
        R(i) = c;
    end
end


function [F, p, resid, df_model, df_error] = F_test_full_vs_red(y, X, Xred, px, pxred)
% :Usage:
% ::
%
%     [F, p, resid, df_model, df_error] = F_test_full_vs_red(y, X, Xred, px, pxred)
%
% :Examples:
% ::
%
%    X = randn(100, 3); Xred = X(:,1); y = X(:,2) + randn(100, 1);
%    px = pinv(X); pxred = pinv(Xred);
%    [F, p, resid] = F_test_full_vs_red(y, X, Xred, px, pxred);
%
%
%    % Test full-model F-value against regress.m
%    Xred = X(:,end); % intercept only
%    px = pinv(X);
%    pxred = pinv(Xred);
%    [F, p, resid, dfm, dfe] = F_test_full_vs_red(y, X, Xred, px, pxred); % full model F-test
%    [b, bint, r, rint, stats] = regress(y, X);
%
% ..
%    Tested OK on 11/27/07, by tor
% ..

    T = length(y);      % Length of time course

    k = size(px, 1);        % predictors: full model
    kred = size(pxred, 1);  % predictors: reduced model

    % Degrees of freedom: model: Full - reduced
    df_model = k - kred;                        % degrees of freedom for model (param - 1)
    df_error = T - k;                           % error DF, full model

    % Step 1: Find the OLS solution for the FULL model
    % ---------------------------------------------------
    beta = px * y;                             % Beta values
    resid = y - X * beta;                       % Residuals

    % Sums of squares
    %SST = y' * y;
    SSE = resid' * resid;
    %SSfull = SST - SSE;
    var_est = SSE / df_error;                   % Estimate of Sigma^2

    % Step 2: Find the OLS solution for the REDUCED model
    % F-test for full vs. reduced
    % ---------------------------------------------------
    betared = pxred * y;                          % Beta values
    residred = y - Xred * betared;
    SSEred = residred' * residred;
    %SSred = betared' * Xred' * y;                      % Full model sum of squares

    % F stat
    % (SSred - SSfull) ./ (var * df_model)
    F = (SSEred - SSE) / (var_est * df_model);         % F-statistic - compare with F-distribution with (param-1, df) degrees of freedom

    p = 1 - fcdf(F, df_model, df_error);
end


function d=jensen_shannon_divergence(XI,XJ)
  % Implementation of the Jensen-Shannon Divergence to use with pdist
  % (cf. "The Earth Movers' Distance as a Metric for Image Retrieval",
  %      Y. Rubner, C. Tomasi, L.J. Guibas, 2000)
  %
  % @author: B. Schauerte
  % @date:   2009
  % @url:    http://cvhci.anthropomatik.kit.edu/~bschauer/

  % Copyright 2009 B. Schauerte. All rights reserved.
  %
  % 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 B. SCHAUERTE ''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 B. SCHAUERTE 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.
  %
  % The views and conclusions contained in the software and documentation
  % are those of the authors and should not be interpreted as representing
  % official policies, either expressed or implied, of B. Schauerte.

  d=jeffrey_divergence(XI,XJ);
  d=d / 2;


function popDist = totaldistance(pop,dis)
% TOTALDISTANCE
% popDist = TOTALDISTANCE(pop, dis) calculate total distance of pop(routes)
% with the distance matrix dis. Evaluate Each Population Member (Calculate
% Total Distance)

[popSize, numberofcities] = size(pop);
for i = 1:popSize
    d = dis(pop(i,end),pop(i,1)); % Closed Path
    for k = 2:numberofcities
        d = d + dis(pop(i,k-1),pop(i,k));
    end
    popDist(i) = d;
end