function yred=rednoise(N,g,a);
% REDNOISE: A fast rednoise generator using filter.
%
% example: rednoise(N,g);
%
% Description: generates a rednoise series
% with zero process mean.
% note: statistical mean&variance will be different.
%
% Inputs: n - desired length of time series
%         g - lag-1 autocorrelation
%         a - noise innovation variance parameter (optional, default=1)
%
% Example:
%   plot(rednoise(1000,.95))
%
% Aslak Grinsted 2006-2014

% -------------------------------------------------------------------------
%The MIT License (MIT)
%
%Copyright (c) 2014 Aslak Grinsted
%
%Permission is hereby granted, free of charge, to any person obtaining a copy
%of this software and associated documentation files (the "Software"), to deal
%in the Software without restriction, including without limitation the rights
%to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%copies of the Software, and to permit persons to whom the Software is
%furnished to do so, subject to the following conditions:
%
%The above copyright notice and this permission notice shall be included in
%all copies or substantial portions of the Software.
%
%THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%THE SOFTWARE.
%---------------------------------------------------------------------------

if nargin<3
    a=1;
end

if g==0
    yred=randn(N,1)*a;
    return
end
tau=ceil(-2/log(abs(g))); %2 x de-correlation time

yred=filter([1 0],[1;-g],randn(tau+N,1)*a);
yred=yred(tau+1:end);


%   getBox:  Given the current state, returns a number from 1 to 162
%             designating the region of the state space encompassing the current state.
%             Returns a value of -1 if a failure state is encountered.

function box = getBox(theta,thetaDot,x,xDot)
theta = rad2deg(theta);
thetaDot = rad2deg(thetaDot);
if (x < -2.4 || x > 2.4  || theta < -12 || theta > 12)
    box = -1;
else

if (theta<-6&&theta>=-12)
	thetaBucket = 1;
elseif (theta<-1&&theta>=-6)
	thetaBucket = 2;
elseif (theta<0&&theta>=-1)
	thetaBucket = 3;
elseif (theta<1&&theta>=0)	% zero included
	thetaBucket = 4;
elseif (theta<6&&theta>=1)
	thetaBucket = 5;
elseif (theta<=12&&theta>=6)
	thetaBucket = 6;
end

if (x<-0.8&&x>=-2.4)
	xBucket = 1;
elseif (x<=0.8&&x>=-0.8)
	xBucket = 2;
elseif (x<=2.4&&x>0.8)
	xBucket = 3;
end

if (xDot<-0.5)
	xDotBucket = 1;
elseif (xDot>=-0.5&&xDot<=0.5)
	xDotBucket = 2;
else
	xDotBucket = 3;
end

if (thetaDot<-50)
	thetaDotBucket = 1;
elseif (thetaDot>=-50&&thetaDot<=50)
	thetaDotBucket = 2;
else
	thetaDotBucket = 3;
end

box = sub2ind([6,3,3,3],thetaBucket, thetaDotBucket,xBucket,xDotBucket);
end
return;


% Calculate border score for a firing map
%
% Calculates a border score for a firing rate map according to the article "Representation of Geometric
% Borders in the Entorhinal Cortex" by Solstad et. al. (Science 2008).
% Border score ranges from -1 to +1 with +1 being "a perfect border cell". If the firing map contains
% no firing fields, then the returned score is -1.
% The score reflects not only how close a field is to a border and how big the coverage of this field is,
% but also it reflects spreadness of a field. The best border score (+1) will be calculated for a thin
% line (1 px, bin) that lies along the wall and fully covers this wall.
%
%  USAGE
%   score = analyses.borderScore(map, fieldsMap, fields, <options>)
%   map         A 2D firing map, not a struct you get from analyses.map, but actual values.
%   fieldsMap   Matrix of the same size as map with only non-zero elements
%               belonging to detected fields. This is an output from
%               function analyses.placefield.
%   fields      Array of structures with information about detected fields.
%               This is an output from function analyses.placefield.
%   <options>   Optional list of property-value pairs (see table below)
%
%   ==============================================================================================
%    Properties    Values
%   ----------------------------------------------------------------------------------------------
%    'searchWidth'  If map is not perfect, but contains NaN values along borders, then
%                   search for border pixels can have NaNs. To mitigate this, we check
%                   searchWidth rows/columns near border and if the closest to the border pixel
%                   equals to NaN, we search for first non-NaN value in searchWidth rows-columns.
%                   This argument is optional and default value is 8.
%    'walls'        Definition of walls along which the border score is calculated. Provided by
%                   a string which contains characters that stand for walls:
%                   T - top wall (we assume the bird-eye view on the arena)
%                   R - right wall
%                   B - bottom wall
%                   L - left wall
%                   Characters are case insensitive. Default value is 'TRBL' meaning that border
%                   score is calculated along all walls. Any combination is possible, e.g.
%                   'R' to calculate along right wall, 'BL' to calculate along two walls, e.t.c.
%   ==============================================================================================
%   score       Border score. Ranges from -1 to +1 (if there are no fields,
%               then score is -1).
%
%  SEE
%   See analyses.placefield
%
function score = borderScore(map, fieldsMap, fields, varargin)
    score = -1;

    if ~isempty(fields)
        coverage = analyses.borderCoverage(fields, varargin{:});

        fieldsFiringMap = fieldsMap;
        fieldsFiringMap(fieldsFiringMap > 0) = 1; % different fields are assigned different numbers,
                                                  % make them all 1.
        fieldsFiringMap = map .* fieldsFiringMap;

        fdist = weighted_firing_distance(fieldsFiringMap);
        score = (coverage - fdist)/(coverage + fdist);
    end
end

function wfd = weighted_firing_distance(map)
    % normalized firing map. Normalization is done by
    % the sum of firing rates of all pixels belonging to all fields
    map = map/nansum(map(:));

    [ly, lx] = size(map);
    [mx, my] = meshgrid(1:lx, 1:ly);

    % alternative code for distance matrix is:
    % map = zeros(ly, lx);
    % map(1, :) = 1;
    % map(end, :) = 1;
    % map(:, 1) = 1;
    % map(:, end) = 1;
    % D = bwdist(map);
    % but this code is slower.

    distance_matrix = min(min(my,mx), min(flipud(my), fliplr(mx)));

    wfd = nansum(nansum(map .* distance_matrix));

    % normalization by half of the smallest arena size min(ly, lx)/2.
    wfd = (2 * wfd) / min(ly, lx);
end


%% [core,U] = tensor_hosvd(T,t,r)
%
%%% Normal HoSVD
% [core,U] = tensor_hosvd(T)
% [core,U] = tensor_hosvd(T,0)
% [core,U] = tensor_hosvd(T,[0 0 0])
%
%%% Truncate mode-3 basis matrice (keep the first 2 eigenvalues)
% [core,U] = tensor_hosvd(T,[0 0 2])
%
%%% Perform mode-3 rank-2 partial svd
% [core,U] = tensor_hosvd(T,0,[0 0 2])
%
function [core,U] = tensor_hosvd(T,t,r)
  core = T;

  if(nargin < 3) r = zeros(1,ndims(T)); end
  if(nargin < 2) t = zeros(1,ndims(T)); end

  if(t == 0) t = zeros(1,ndims(T)); end
  if(r == 0) r = zeros(1,ndims(T)); end

  for i = 1:ndims(T)
    M{i} = double(tenmat(T,i));
    %M{i} = unfolding(double(T),i);

    %%% perform partial svd
    if(r(i) > 0)
      [U{i},S{i},V{i}] = svds(M{i},r(i),'L');
    else
      [U{i},S{i},V{i}] = svd(M{i});
    end

    %%% truncate basis matrice
    if(t(i) > 0)
      U{i}(:,t(i)+1:end) = 0;
    end

    %[m n] = size(U{i});
    %s(i) = n;
    %core = tensor(folding(U{i}'*unfolding(double(core),i), i, s));
    %core = double(ttm(tensor(core),U{i},i,'t'));
    core = ttm(core,U{i}',i);
  end
end


function pass = test_basic_arithmetic(pref)

% TODO: We currently only test scalar autonomous chebops.
%       We also do not check for errors boundary conditions are dealt with.

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

dom = [0 3];
u = chebfun(@sin, dom);
A = chebop(@(u) u, dom);
B = chebop(@(u) u, dom);

% Basic plus:
C = A + B;
pass(1) = norm(A(u) + B(u) - C(u)) == 0;

% Basic minus:
C = A - B;
pass(2) = norm(C(u)) == 0;

% Basic uminus:
C = -B;
pass(3) = norm(B(u) + C(u)) == 0;

% Basic times (scalar):
C = 2*A;
pass(4) = norm(2*A(u) - C(u)) == 0;
C = 2.*A;
pass(5) = norm(2*A(u) - C(u)) == 0;

% Basic divide (scalar):
C = A/2;
pass(6) = norm(A(u)/2 - C(u)) == 0;
C = A./2;
pass(7) = norm(A(u)/2 - C(u)) == 0;

% eye
I = eye(A);
pass(8) = norm(u - I(u)) == 0;
pass(9) = norm((A-I)*u - (A(u)-u)) == 0;

end


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

%*****************************************************************************80
%
%% STRUVE_H1_VALUES returns some values of the Struve H1 function.
%
%  Discussion:
%
%    The function is defined by:
%
%      H1(x) = 2*x/pi * Integral ( 0 <= t <= pi/2 )
%        sin ( x * cos ( t ) )^2 * sin ( t ) dt
%
%    In Mathematica, the function can be evaluated by:
%
%      StruveH[1,x]
%
%    The data was reported by McLeod.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%    Allan McLeod,
%    Algorithm 757, MISCFUN: A software package to compute uncommon
%      special functions,
%    ACM Transactions on Mathematical Software,
%    Volume 22, Number 3, September 1996, pages 288-301.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Wolfram Media / Cambridge University Press, 1999.
%
%  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 = 20;

  fx_vec = [ ...
     0.80950369576367526071E-06, ...
     0.12952009724113229165E-04, ...
     0.82871615165407083021E-03, ...
     0.13207748375849572564E-01, ...
     0.19845733620194439894E+00, ...
     0.29853823231804706294E+00, ...
     0.64676372828356211712E+00, ...
     0.10697266613089193593E+01, ...
     0.38831308000420560970E+00, ...
     0.74854243745107710333E+00, ...
     0.84664854642567359993E+00, ...
     0.58385732464244384564E+00, ...
     0.80600584524215772824E+00, ...
     0.53880362132692947616E+00, ...
     0.72175037834698998506E+00, ...
     0.58007844794544189900E+00, ...
     0.60151910385440804463E+00, ...
     0.70611511147286827018E+00, ...
     0.61631110327201338454E+00, ...
     0.62778480765443656489E+00 ];

  x_vec = [ ...
        0.0019531250E+00, ...
       -0.0078125000E+00, ...
        0.0625000000E+00, ...
       -0.2500000000E+00, ...
        1.0000000000E+00, ...
        1.2500000000E+00, ...
        2.0000000000E+00, ...
       -4.0000000000E+00, ...
        7.5000000000E+00, ...
       11.0000000000E+00, ...
       11.5000000000E+00, ...
      -16.0000000000E+00, ...
       20.0000000000E+00, ...
       25.0000000000E+00, ...
      -30.0000000000E+00, ...
       50.0000000000E+00, ...
       75.0000000000E+00, ...
      -80.0000000000E+00, ...
      100.0000000000E+00, ...
     -125.0000000000E+00 ];

  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


function inside = polygon_contains_point_2d ( n, v, p )

%*****************************************************************************80
%
%% POLYGON_CONTAINS_POINT_2D finds if a point is inside a simple polygon in 2D.
%
%  Discussion:
%
%    A simple polygon is one whose boundary never crosses itself.
%    The polygon does not need to be convex.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    M Shimrat,
%    Position of Point Relative to Polygon,
%    ACM Algorithm 112,
%    Communications of the ACM,
%    Volume 5, Number 8, page 434, August 1962.
%
%  Parameters:
%
%    Input, integer N, the number of nodes or vertices in the polygon.
%    N must be at least 3.
%
%    Input, real V(2,N), the coordinates of the vertices of the polygon.
%
%    Input, real P(2), the coordinates of the point to be tested.
%
%    Output, logical INSIDE, is TRUE if the point is inside the polygon.
%
  inside = 1;

  for i = 1 : n

    x1 = v(1,i);
    y1 = v(2,i);

    if ( i < n )
      x2 = v(1,i+1);
      y2 = v(2,i+1);
    else
      x2 = v(1,1);
      y2 = v(2,1);
    end

    if ( ( y1 < p(2) & p(2) <= y2 ) | ( p(2) <= y1 & y2 < p(2) ) )
      if ( ( p(1) - x1 ) - ( p(2) - y1 ) * ( x2 - x1 ) / ( y2 - y1 ) < 0.0 )
        inside = ~inside;
      end
    end

  end

  inside = ~inside;

  return
end


function jmp = estimateJump(series,jmp_idx,same_slope,mode)
    %Description: estimate jmp in a series doing a dtrend using medians
    %INPUT:
    % series : the series
    % jmp_idx : where the jmp occurs
    % mode : 1 joint detrend , 2: detrend separately
    if nargin < 3
        same_slope = true;
        mode = 'median';
    end
    if nargin < 4
        mode = 'median';
    end
    if strcmp(mode, 'median')
        diff_pre = diff(series(1:jmp_idx-1));
        diff_post = diff(series(jmp_idx:end));
        if same_slope
            trnd = median([diff_pre ;diff_post],'omitnan');
            series = series - trnd * [1:length(series)]';
        else
            trend1 = median([diff_pre],'omitnan');
            trend2 = median([diff_post],'omitnan');
            %series(1:jmp_idx-1) = series(1:jmp_idx-1) - trend1 * [1 : jmp_idx-1]';
            %series(jmp_idx:end) = series(jmp_idx:end) - trend2 * [1 : (length(series) - jmp_idx + 1)]';
        end
        jmp = median(series(jmp_idx:end),'omitnan') - median(series(1:jmp_idx-1),'omitnan')  ;
    elseif strcmp(mode, 'ls')
        valid_idx_l = ~isnan(series);
        valid_idx = find(valid_idx_l);
        idx_bf = valid_idx < jmp_idx;
        idx_aft = valid_idx >= jmp_idx;
        n_valid = sum(valid_idx_l);
        if same_slope
            A= zeros(n_valid,3);
            A(:,1) = find(valid_idx_l);
            A(idx_bf,2) = 1;
            A(idx_aft,3) = 1;
            x = A\series(valid_idx_l);
            jmp = x(3) -x(2);
        else
            A= zeros(n_valid,4);
            A(idx_bf, 1) = valid_idx(idx_bf);
            A(idx_aft, 2) = valid_idx(idx_aft);
            A(idx_bf, 3) = 1;
            A(idx_aft, 4) = 1;
            x = A\series(valid_idx_l);
            jmp = x(4) -x(3);
        end
    end
end


function compspec
% Competing species phase diagram
%    using MATLAB ode
%
%   $Ekkehard Holzbecher  $Date: 2006/09/04 $
%--------------------------------------------------------------------------
T = 1000;                % maximum time
r = [1; 1];              % rates
e = [1; 1];              % equilibria
lambda = 1;              % lambda parameter
c0 = [1; 1];             % initial concentrations

gtraj = 1;               % trajectory plot
gquiv = 20;              % arrow field plot; value for no. of arrows in 1D
xmin = 0; xmax = 1;      % x- interval for arrow field plot
ymin = 0; ymax = 1;      % y-     "     "    "     "     "
scale = 2;               % scaling factor for arrows
%----------------------execution-------------------------------------------

options = odeset('AbsTol',1e-20);
[~,c] = ode15s(@CS,[0 T],c0,options,r,e,lambda);

%---------------------- graphical output ----------------------------------

if (gtraj)
    plot (c(:,1)',c(:,2)'); hold on;
    plot (e(1),0,'s'); plot (0,e(2),'s');
    legend ('trajectory');
    xlabel ('specie 1'); ylabel ('specie 2');
    title ('Competing species');
end
if (gquiv)
    [x,y] = meshgrid (linspace(xmin,xmax,gquiv),linspace(ymin,ymax,gquiv));
    dy = zeros(gquiv,gquiv,2);
    for i = 1:gquiv
        for j = 1:gquiv
            dy(i,j,:) = CS(0,[x(i,j);y(i,j)],r,e,lambda);
        end
    end
    quiver (x,y,dy(:,:,1),dy(:,:,2),scale);
end

%---------------------- function ------------------------------------------
function dydt = CS(~,y,r,e,lambda)
k = [e(1)/(1+lambda*y(2)/y(1)); e(2)/(1+y(1)/y(2)/lambda)];
dydt = r.*y.*(1-y./k);


function [ r, seed ] = r8_uniform_01 ( seed )

%*****************************************************************************80
%
%% R8_UNIFORM_01 returns a unit pseudorandom R8.
%
%  Discussion:
%
%    This routine implements the recursion
%
%      seed = 16807 * seed mod ( 2^31 - 1 )
%      r8_uniform_01 = seed / ( 2^31 - 1 )
%
%    The integer arithmetic never requires more than 32 bits,
%    including a sign bit.
%
%    If the initial seed is 12345, then the first three computations are
%
%      Input     Output      R8_UNIFORM_01
%      SEED      SEED
%
%         12345   207482415  0.096616
%     207482415  1790989824  0.833995
%    1790989824  2035175616  0.947702
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Linus Schrage,
%    A Guide to Simulation,
%    Springer Verlag, pages 201-202, 1983.
%
%    Pierre L'Ecuyer,
%    Random Number Generation,
%    in Handbook of Simulation,
%    edited by Jerry Banks,
%    Wiley Interscience, page 95, 1998.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, pages 362-376, 1986.
%
%    Peter Lewis, Allen Goodman, James Miller,
%    A Pseudo-Random Number Generator for the System/360,
%    IBM Systems Journal,
%    Volume 8, pages 136-143, 1969.
%
%  Parameters:
%
%    Input, integer SEED, the integer "seed" used to generate
%    the output random number.  SEED should not be 0.
%
%    Output, real R, a random value between 0 and 1.
%
%    Output, integer SEED, the updated seed.  This would
%    normally be used as the input seed on the next call.
%
  i4_huge = 2147483647;

  if ( seed == 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8_UNIFORM_01 - Fatal error!\n' );
    fprintf ( 1, '  Input SEED = 0!\n' );
    error ( 'R8_UNIFORM_01 - Fatal error!' );
  end

  seed = floor ( seed );

  seed = mod ( seed, i4_huge );

  if ( seed < 0 )
    seed = seed + i4_huge;
  end

  k = floor ( seed / 127773 );

  seed = 16807 * ( seed - k * 127773 ) - k * 2836;

  if ( seed < 0 )
    seed = seed + i4_huge;
  end

  r = seed * 4.656612875E-10;

  return
end


% PDELDEMO This program creates the left preconditionied PDE example
%          from Chapter 3
%
% The example has the form
%
% L(u) = f, 0 < x,y < 1
% with homogeneous Dirichlet BC
%
% In terms of the program below, the equation is
% Lu = - (u_xx + u_yy) + 20*u*(u_x + u_y)  = f
%
% Within the nonlinear map, pdefun.m, we apply fish2d.m as
% a preconditioner.
%
% The action of the laplacian, partial wrt x, and partial wrt y
% are computed in the routines lapmf, dxmf, and dymf. Here mf
% stands for MATRIX FREE.
%
global rhsf prhsf;
m=31; n=m*m;
h=1/(m+1);
h2=(m+1)*(m+1);
h1=(m+1);
tolh=1/h2;
mres=3;
%
% set up the equation
%
x=1:m;
e=x';
x=x'*h;
%
% Form the solution: sol(x,y)= 10 x y (1-x) (1-y) exp(x^4.5)
%
zsoly=x.*(1-x);
zsolx=zsoly.*exp(x.^4.5);
solt=10*zsolx*zsoly';
sol=solt(:);
clear rhs; clear axt; clear at; clear ayt; clear solt;

% fix the right side so that the solution is known
%
% unpreconditioned and right preconditioned
%
rhsf = lapmf(sol) + 20*sol.*(dxmf(sol)+dymf(sol));
%
% left preconditioned
%
prhsf = sol + 20*fish2d(sol.*(dxmf(sol)+dymf(sol)));
%
% Set the initial iterate to zero. Call the solver three times with
% each of the Krylov methods
%
u0=zeros(m*m,1);
%
tol=[1.d-1,1.d-1]*tolh;
%
% GMRES
%
x=zeros(n,1); parms = [40,40,.9,1];
[sol, it_histg, ierr] = nsoli(x,'pdeleft',tol,parms);
%
% BICGSTAB
%
x=zeros(n,1); parms = [40,40,.9,3];
[sol, it_histb, ierr] = nsoli(x,'pdeleft',tol,parms);
%
% TFQMR
%
x=zeros(n,1); parms = [40,40,.9,4];
[sol, it_histt, ierr] = nsoli(x,'pdeleft',tol,parms);
figure(1)
ng=length(it_histg(:,1));
nb=length(it_histb(:,1));
nt=length(it_histt(:,1));
semilogy(0:ng-1,it_histg(:,1)/it_histg(1,1),'-',...
0:nb-1,it_histb(:,1)/it_histg(1,1),'--',...
0:nt-1,it_histt(:,1)/it_histg(1,1),'-.');
xlabel('Nonlinear iterations');
ylabel('Relative residual');
legend('GMRES','BICGSTAB','TFQMR');
figure(2)
semilogy(it_histg(:,2),it_histg(:,1)/it_histg(1,1),'-',...
it_histb(:,2),it_histb(:,1)/it_histb(1,1),'--',...
it_histt(:,2),it_histt(:,1)/it_histt(1,1),'-.');
xlabel('Function evaluations');
ylabel('Relative residual');
legend('GMRES','BICGSTAB','TFQMR');


function SmoothY=fastsmooth(Y,w,type,ends)
% fastsmooth(Y,w,type,ends) smooths vector Y with smooth
%  of width w. Version 3.0, October 2016.
% The argument "type" determines the smooth type:
%   If type=1, rectangular (sliding-average or boxcar)
%   If type=2, triangular (2 passes of sliding-average)
%   If type=3, pseudo-Gaussian (3 passes of sliding-average)
%   If type=4, pseudo-Gaussian (4 passes of same sliding-average)
%   If type=5, multiple-width (4 passes of different sliding-average)
% The argument "ends" controls how the "ends" of the signal
% (the first w/2 points and the last w/2 points) are handled.
%   If ends=0, the ends are zero.  (In this mode the elapsed
%     time is independent of the smooth width). The fastest.
%   If ends=1, the ends are smoothed with progressively
%     smaller smooths the closer to the end. (In this mode the
%     elapsed time increases with increasing smooth widths).
% fastsmooth(Y,w,type) smooths with ends=0.
% fastsmooth(Y,w) smooths with type=1 and ends=0.
% Examples:
% fastsmooth([1 1 1 10 10 10 1 1 1 1],3)= [0 1 4 7 10 7 4 1 1 0]
%
% fastsmooth([1 1 1 10 10 10 1 1 1 1],3,1,1)= [1 1 4 7 10 7 4 1 1 1]
%
% x=1:100;
% y=randn(size(x));
% plot(x,y,x,fastsmooth(y,5,3,1),'r')
% xlabel('Blue: white noise.    Red: smoothed white noise.')
%
% Copyright (c) 2012, Thomas C. O'Haver
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
% THE SOFTWARE.
if nargin==2, ends=0; type=1; end
if nargin==3, ends=0; end
  switch type
    case 1
       SmoothY=sa(Y,w,ends);
    case 2
       SmoothY=sa(sa(Y,w,ends),w,ends);
    case 3
       SmoothY=sa(sa(sa(Y,w,ends),w,ends),w,ends);
    case 4
       SmoothY=sa(sa(sa(sa(Y,w,ends),w,ends),w,ends),w,ends);
    case 5
       SmoothY=sa(sa(sa(sa(Y,round(1.6*w),ends),round(1.4*w),ends),round(1.2*w),ends),w,ends);
  end

function SmoothY=sa(Y,smoothwidth,ends)
w=round(smoothwidth);
SumPoints=sum(Y(1:w));
s=zeros(size(Y));
halfw=round(w/2);
L=length(Y);
for k=1:L-w,
   s(k+halfw-1)=SumPoints;
   SumPoints=SumPoints-Y(k);
   SumPoints=SumPoints+Y(k+w);
end
s(k+halfw)=sum(Y(L-w+1:L));
SmoothY=s./w;
% Taper the ends of the signal if ends=1.
  if ends==1,
  startpoint=(smoothwidth + 1)/2;
  SmoothY(1)=(Y(1)+Y(2))./2;
  for k=2:startpoint,
     SmoothY(k)=mean(Y(1:(2*k-1)));
     SmoothY(L-k+1)=mean(Y(L-2*k+2:L));
  end
  SmoothY(L)=(Y(L)+Y(L-1))./2;
  end


function pass = test_feval(pref)
% Test feval

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

tol = 100*pref.cheb2Prefs.chebfun2eps;

f = chebfun2(@(x,y) x);
pass(1) = (abs(f(pi/6,pi/12)-pi/6) < tol);

f = chebfun2(@(x,y) x, [-1 2 -pi/2 pi]);
pass(2) = (abs(f(0,0)) < 1e-14);
pass(3) = (abs(f(pi/6,pi/12)-pi/6) < tol);

f = chebfun2(@(x,y) y, [-1 2 -pi/2 pi]);
pass(4) = (abs(f(0,0)) < 1e-14);
pass(5) = (abs(f(pi/6,pi/12)-pi/12) < tol);

% some harder tests.
f = @(x,y) cos(x) + sin(x.*y);
g = chebfun2(f);

r = 0.126986816293506; s = 0.632359246225410; % two fixed random number in domain.
pass(6) = (abs(f(r,s) - g(r,s))<tol);

% Are we evaluating on arrays correctly
seedRNG(0)
r = rand(10,1);
s = rand(10,1);
[rr, ss]=meshgrid(r,s);
pass(7) = (norm((f(r,s) - g(r,s))) < tol);
pass(8) = (norm((f(rr,ss) - g(rr,ss))) < tol);  % on arrays as well.

% Does this work off [-1,1]^2
g = chebfun2(f,[-pi/6 pi/2 -pi/12 sqrt(3)]); % strange domain.
r = 0.126986816293506; s = 0.632359246225410; % two fixed random number in domain.
pass(9) = (abs(f(r,s) - g(r,s))<tol);

% Are we evaluating on arrays correctly
r = rand(10,1); s = rand(10,1); [rr, ss]=meshgrid(r,s);
pass(10) = (norm((f(r,s) - g(r,s)))<tol);
pass(11) = (norm((f(rr,ss) - g(rr,ss)))<2*tol); % on arrays as well.

% Evaluation at complex arguments.
f = chebfun2(@(x,y) x+1i*y);
pass(12) = ( norm( f(-1,-1) - (-1-1i) )  < tol );
pass(13) = ( norm( f(r,s) - (r + 1i*s) )  < tol );
pass(14) = (norm((f(rr,ss) - (rr + 1i*ss)))<tol); % on arrays as well.

% Evaluation at complex arguments, different syntax.
f = chebfun2(@(z) z);
pass(15) = ( norm( f(-1-1i) - (-1-1i) )  < tol );
pass(16) = ( norm( f(r+1i*s) - (r + 1i*s) )  < tol );
pass(17) = (norm((feval(f,rr,ss) - (rr + 1i*ss)))<tol); % on arrays as well.

% Evaluation at transposed meshgrid
op = @(x,y) cos(pi*(x+y))+y.*sin(pi*x);
[yy,xx] = meshgrid(linspace(-1,1,1001));
f = chebfun2( op );
pass(18) = (norm( feval(f,xx,yy) - op(xx,yy) ) < 100*tol);

% Check sizes:
n = 10;
f = chebfun2(@(x,y) cos(x.*y));
x = ones(1,n);
[xx, yy] = meshgrid(x);
pass(19) = ( all( size( feval(f, 1, 1) ) == [1 1] ) );
pass(20) = ( all( size( feval(f, [1 1], [1 1]) ) == [1 2] ) );
pass(21) = ( all( size( feval(f, [1;1], [1;1]) ) == [2 1] ) );
pass(22) = ( all( size( feval(f, [1 1;1 1], [1 1; 1 1]) ) == [2 2] ) );
pass(23) = ( all( size( feval(f, x, x) ) == size(x) ) );
pass(24) = ( all( size( feval(f, xx, yy)  ) == [n n] ) );

end


function [p,t] = initmesh(fd,fh,h0,bbox,pfix,varargin)
%% INITMESH initialize a triangulation
%
% Modifed from distmesh. Please refer to distmesh on the usage.
%
%   Example: (Rectangle with circular hole, refined at circle boundary)
%      fd=inline('ddiff(drectangle(p,-1,1,-1,1),dcircle(p,0,0,0.5))','p');
%      fh=inline('min(4*sqrt(sum(p.^2,2))-1,2)','p');
%      [p,t]=initmesh(fd,fh,0.05,[-1,-1;1,1],[-1,-1;-1,1;1,-1;1,1]);
%
%   Copyright (C) 2004-2006 Per-Olof Persson. See COPYRIGHT.TXT for details.

% parameters;
geps = 0.001*h0;

% 1. Create initial distribution in bounding box (equilateral triangles)
[x,y] = meshgrid(bbox(1,1):h0:bbox(2,1),bbox(1,2):h0*sqrt(3)/2:bbox(2,2));
x(2:2:end,:) = x(2:2:end,:)+h0/2;                % Shift even rows
p = [x(:),y(:)];                                 % List of node coordinates

% 2. Remove points outside the region, apply the rejection method
p = p(feval(fd,p,varargin{:}) < geps,:);        % Keep only d<0 points
r0 = 1./feval(fh,p,varargin{:}).^2;              % Probability to keep point
p = p(rand(size(p,1),1) < r0./max(r0),:);
p = [pfix; p + (rand(size(p,1),2)-2)*geps];  % Rejection method
% p = unique(p,'rows');
% p(1:size(pfix,1),:) = pfix;

% 3. Retriangulation by the Delaunay algorithm
t = delaunayn(p);                                % List of triangles
pmid = (p(t(:,1),:)+p(t(:,2),:)+p(t(:,3),:))/3;  % Compute centroids
t = t(feval(fd,pmid,varargin{:})<-geps,:);       % Keep interior triangles


function [s, err_mse, iter_time]=greed_omp_linsolve(x,A,m,varargin)
% greed_omp_linsolve: Orthogonal Matching Pursuit algorithm based on matlab
% linsolve solution. For reference only!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Usage
% [s, err_mse, iter_time]=greed_omp_linsolve(x,P,m,'option_name','option_value')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input
%   Mandatory:
%               x   Observation vector to be decomposed
%               P   Either:
%                       1) An nxm matrix (n must be dimension of x)
%                       2) A function handle (type "help function_format"
%                          for more information)
%                          Also requires specification of P_trans option.
%                       3) An object handle (type "help object_format" for
%                          more information)
%               m   length of s
%
%   Possible additional options:
%   (specify as many as you want using 'option_name','option_value' pairs)
%   See below for explanation of options:
%__________________________________________________________________________
%   option_name    |     available option_values                | default
%--------------------------------------------------------------------------
%   stopCrit       | M, corr, mse, mse_change                   | M
%   stopTol        | number (see below)                         | n/4
%   P_trans        | function_handle (see below)                |
%   maxIter        | positive integer (see below)               | n
%   verbose        | true, false                                | false
%   start_val      | vector of length m                         | zeros
%
%   Available stopping criteria :
%               M           -   Extracts exactly M = stopTol elements.
%               corr        -   Stops when maximum correlation between
%                               residual and atoms is below stopTol value.
%               mse         -   Stops when mean squared error of residual
%                               is below stopTol value.
%               mse_change  -   Stops when the change in the mean squared
%                               error falls below stopTol value.
%
%   stopTol: Value for stopping criterion.
%
%   P_trans: If P is a function handle, then P_trans has to be specified and
%            must be a function handle.
%
%   maxIter: Maximum number of allowed iterations.
%
%   verbose: Logical value to allow algorithm progress to be displayed.
%
%   start_val: Allows algorithms to start from partial solution.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Outputs
%	 s              Solution vector
%    err_mse        Vector containing mse of approximation error for each
%                   iteration
%    iter_time      Vector containing computation times for each iteration
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Description
%   greed_omp_linsolve performs a greedy signal decomposition.
%   In each iteration a new element is selected depending on the inner
%   product between the current residual and columns in P.
%   The non-zero elements of s are approximated by orthogonally projecting
%   x onto the selected elements in each iteration.
%   The inverse problem is solved using matlabs linsolve command.
%   This is slow and is only provided for reference.
%
% See Also
%   greed_qr, greed_omp_chol, greed_omp_cg, greed_omp_cgp, greed_omp_pinv,
%   greed_gp, greed_nomp
%
% Copyright (c) 2007 Thomas Blumensath
%
% The University of Edinburgh
% Email: thomas.blumensath@ed.ac.uk
% Comments and bug reports welcome
%
% This file is part of sparsity Version 0.1
% Created: April 2007
%
% Part of this toolbox was developed with the support of EPSRC Grant
% D000246/1
%
% Please read COPYRIGHT.m for terms and conditions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                    Default values and initialisation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[n1 n2]=size(x);
if n2 == 1
    n=n1;
elseif n1 == 1
    x=x';
    n=n2;
else
   display('x must be a vector.');
   return
end

sigsize     = x'*x/n;
initial_given=0;
err_mse     = [];
iter_time   = [];
STOPCRIT    = 'M';
STOPTOL     = ceil(n/4);
MAXITER     = n;
verbose     = false;
s_initial   = zeros(m,1);
vectnfact   = ones(m,1);

if verbose
   display('Initialising...')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                           Output variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

switch nargout
    case 3
        comp_err=true;
        comp_time=true;
    case 2
        comp_err=true;
        comp_time=false;
    case 1
        comp_err=false;
        comp_time=false;
    case 0
        error('Please assign output variable.')
    otherwise
        error('Too many output arguments specified')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                       Look through options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Put option into nice format
Options={};
OS=nargin-3;
c=1;
for i=1:OS
    if isa(varargin{i},'cell')
        CellSize=length(varargin{i});
        ThisCell=varargin{i};
        for j=1:CellSize
            Options{c}=ThisCell{j};
            c=c+1;
        end
    else
        Options{c}=varargin{i};
        c=c+1;
    end
end
OS=length(Options);
if rem(OS,2)
   error('Something is wrong with argument name and argument value pairs.')
end

for i=1:2:OS
   switch Options{i}
        case {'stopCrit'}
            if (strmatch(Options{i+1},{'M'; 'corr'; 'mse'; 'mse_change'},'exact'));
                STOPCRIT    = Options{i+1};
            else error('stopCrit must be char string [M, corr, mse, mse_change]. Exiting.'); end
        case {'stopTol'}
            if isa(Options{i+1},'numeric') ; STOPTOL     = Options{i+1};
            else error('stopTol must be number. Exiting.'); end
        case {'P_trans'}
            if isa(Options{i+1},'function_handle'); Pt = Options{i+1};
            else error('P_trans must be function _handle. Exiting.'); end
        case {'maxIter'}
            if isa(Options{i+1},'numeric'); MAXITER     = Options{i+1};
            else error('maxIter must be a number. Exiting.'); end
        case {'verbose'}
            if isa(Options{i+1},'logical'); verbose     = Options{i+1};
            else error('verbose must be a logical. Exiting.'); end
        case {'vecNormFac'}
            if isa(Options{i+1},'numeric')& length(Options{i+1}) == m , vectnfact = Options{i+1};
            else error('verbose must be a logical. Exiting.'); end
        case {'start_val'}
            if isa(Options{i+1},'numeric') & length(Options{i+1}) == m ;
                s_initial     = Options{i+1};
                initial_given=1;
            else error('start_val must be a vector of length m. Exiting.'); end
        otherwise
            error('Unrecognised option. Exiting.')
   end
end

if strcmp(STOPCRIT,'M')
    maxM=STOPTOL;
else
    maxM=MAXITER;
end

if nargout >=2
    err_mse = zeros(maxM,1);
end
if nargout ==3
    iter_time = zeros(maxM,1);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Make P and Pt functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if          isa(A,'float')      P =@(z) A*z;  Pt =@(z) A'*z;
elseif      isobject(A)         P =@(z) A*z;  Pt =@(z) A'*z;
elseif      isa(A,'function_handle')
    try
        if          isa(Pt,'function_handle'); P=A;
        else        error('If P is a function handle, Pt also needs to be a function handle. Exiting.'); end
    catch error('If P is a function handle, Pt needs to be specified. Exiting.'); end
else        error('P is of unsupported type. Use matrix, function_handle or object. Exiting.'); end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Do we start from zero or not?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if initial_given ==1;
    IN          = find(s_initial);
    s=zeros(m,1);
    if isa(A,'function_handle') || isobject(A)
         Pmat=zeros(n,length(IN));
         for i=1:length(IN)
             mask=zeros(m,1);
             mask(IN(i))=1;
             Pmat(:,i)=P(mask);
         end
         s(IN)=linsolve(Pmat,x);
     else
         s(IN)=linsolve(A(:,IN),x);
     end
    Residual    = x-P(s);
    oldERR      = Residual'*Residual/n;

else
    IN          = [];
    Residual    = x;
    s           = s_initial;
    sigsize     = x'*x/n;
    oldERR      = sigsize;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                 Random Check to see if dictionary is normalised
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%         mask=zeros(m,1);
%         mask(ceil(rand*m))=1;
%         nP=norm(P(mask));
%         if abs(1-nP)>1e-3;
%             display('Dictionary appears not to have unit norm columns.')
%         end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Main algorithm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if verbose
   display('Main iterations...')
end
tic
t=0;
DR=Pt(Residual).*vectnfact;
done = 0;
iter=1;
while ~done
     DR(IN)=0;
     [v I]=max(abs(DR));
     IN=[IN I];
     if isa(A,'function_handle') || isobject(A)
         Pmat=zeros(n,length(IN));
         for i=1:length(IN)
             mask=zeros(m,1);
             mask(IN(i))=1;
             Pmat(:,i)=P(mask);
         end
         s(IN)=linsolve(Pmat,x);
     else
         s(IN)=linsolve(A(:,IN),x);
     end
     Residual=x-P(s);
     DR=Pt(Residual).*vectnfact;

     ERR=Residual'*Residual/n;
     if comp_err
         err_mse(iter)=ERR;
     end

     if comp_time
         iter_time(iter)=toc;
     end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Are we done yet?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     if strcmp(STOPCRIT,'M')
         if iter >= STOPTOL
             done =1;
         elseif verbose && toc-t>10
            display(sprintf('Iteration %i. --- %i iterations to go',iter ,STOPTOL-iter))
            t=toc;
         end
    elseif strcmp(STOPCRIT,'mse')
         if comp_err
            if err_mse(iter)<STOPTOL;
                done = 1;
            elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse',iter ,err_mse(iter)))
                t=toc;
            end
         else
             if ERR<STOPTOL;
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse',iter ,ERR))
                t=toc;
             end
         end
     elseif strcmp(STOPCRIT,'mse_change') && iter >=2
         if comp_err && iter >=2
              if ((err_mse(iter-1)-err_mse(iter))/sigsize <STOPTOL);
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse change',iter ,(err_mse(iter-1)-err_mse(iter))/sigsize ))
                t=toc;
             end
         else
             if ((oldERR - ERR)/sigsize < STOPTOL);
                done = 1;
             elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i mse change',iter ,(oldERR - ERR)/sigsize))
                t=toc;
             end
         end
     elseif strcmp(STOPCRIT,'corr')
          if max(abs(DR)) < STOPTOL;
             done = 1;
          elseif verbose && toc-t>10
                display(sprintf('Iteration %i. --- %i corr',iter ,max(abs(DR))))
                t=toc;
          end
     end

    % Also stop if residual gets too small or maxIter reached
     if comp_err
         if err_mse(iter)<1e-16
             display('Stopping. Exact signal representation found!')
             done=1;
         end
     else

         if iter>1
             if ERR<1e-16
                 display('Stopping. Exact signal representation found!')
                 done=1;
             end
         end
     end

     if iter >= MAXITER
         display('Stopping. Maximum number of iterations reached!')
         done = 1;
     end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                    If not done, take another round
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     if ~done
        iter=iter+1;
        oldERR=ERR;
     end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                  Only return as many elements as iterations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargout >=2
    err_mse = err_mse(1:iter);
end
if nargout ==3
    iter_time = iter_time(1:iter);
end

if verbose
   display('Done')
end

% Change history
%
% 8 of Februray: Algo does no longer stop if dictionary is not normaliesd.


classdef SMOP2 < PROBLEM
% <multi/many> <real> <large/none> <expensive/none> <sparse/none>
% Benchmark MOP with sparse Pareto optimal solutions
% theta --- 0.1 --- Sparsity of the Pareto set

%------------------------------- Reference --------------------------------
% Y. Tian, X. Zhang, C. Wang, and Y. Jin, An evolutionary algorithm for
% large-scale sparse multi-objective optimization problems, IEEE
% Transactions on Evolutionary Computation, 2020, 24(2): 380-393.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    properties(Access = private)
        theta = 0.1;    % Sparsity of the Pareto set
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            obj.theta = obj.ParameterSet(0.1);
            if isempty(obj.M); obj.M = 2; end
            if isempty(obj.D); obj.D = 100; end
            obj.lower    = [zeros(1,obj.M-1)+0,zeros(1,obj.D-obj.M+1)-1];
            obj.upper    = [zeros(1,obj.M-1)+1,zeros(1,obj.D-obj.M+1)+2];
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,X)
            K = ceil(obj.theta*(obj.D-obj.M+1));
            g = sum(g2(X(:,obj.M:obj.M+K-1),pi/3),2) + sum(g3(X(:,obj.M+K:end),0),2);
            PopObj = repmat(1+g/(obj.D-obj.M+1),1,obj.M).*fliplr(cumprod([ones(size(X,1),1),X(:,1:obj.M-1)],2)).*[ones(size(X,1),1),1-X(:,obj.M-1:-1:1)];
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R = UniformPoint(N,obj.M);
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            if obj.M == 2
                R = obj.GetOptimum(100);
            elseif obj.M == 3
                a = linspace(0,1,10)';
                R = {a*a',a*(1-a'),(1-a)*ones(size(a'))};
            else
                R = [];
            end
        end
    end
end

function g = g2(x,t)
    g = 2*(x-t).^2 + sin(2*pi*(x-t)).^2;
end

function g = g3(x,t)
    g = 4-(x-t)-4./exp(100*(x-t).^2);
end


function [S, V, D] = MySVDs(A, R)
[m, n] = size(A);
if 10*m < n
    AAT = A*A';
    [S, V, D] = svd(AAT);
    V = diag(V) .^ 0.5;
    tol = max(size(A)) * eps(max(V));
    R = min([R, sum(V > tol)]);
    V = V(1:R);
    S = S(:,1:R);
    D = A'*S*diag(1./V);
    V = diag(V);
    return;
end
if m > 10*n
    [S, V, D] = MySVD(A');
    mid = D;
    D = S;
    S = mid;
    return;
end
[S,V,D] = svd(A);
S = S(:, 1:R);
V = V(1:R, 1:R);
D = D(:, 1:R);


function A = int_area(X1,Y1,X2,Y2)
% Compute area of intersection:
%
% area = int_area(X1,Y1,X2,Y2)

X1 = double(X1);
Y1 = double(Y1);
X2 = double(X2);
Y2 = double(Y2);

max_res = 100;

min_x = min([X1(:); X2(:)]);
max_x = max([X1(:); X2(:)]);
min_y = min([Y1(:); Y2(:)]);
max_y = max([Y1(:); Y2(:)]);

X1 = X1-min_x;
X2 = X2-min_x;
Y1 = Y1-min_y;
Y2 = Y2-min_y;
max_x = max_x - min_x;
max_y = max_y - min_y;

max_dim = max(max_x,max_y);

ratio = 1;
% $$$   if max_dim > max_res
% $$$     ratio = max_res/max_dim;
% $$$     X1 = X1*ratio;
% $$$     X2 = X2*ratio;
% $$$     Y1 = Y1*ratio;
% $$$     Y2 = Y2*ratio;
% $$$     max_x = round(max_x*ratio);
% $$$     max_y = round(max_y*ratio);
% $$$   end

X1 = X1+1; X2 = X2+1;
Y1 = Y1+1; Y2 = Y2+1;
max_x = ceil(max_x+1);
max_y = ceil(max_y+1);

M1 = poly2mask(X1,Y1,max_y,max_x);
M2 = poly2mask(X2,Y2,max_y,max_x);

A = sum(sum(double(M1&M2)))/ratio;


%RBSVC Trainable automatic radial basis Support Vector Classifier
%
%   [W,KERNEL,NU,C] = RBSVC(A)
%   [W,KERNEL,NU,C] = A*RBSVC
%
% INPUT
%   A	      Dataset
%
% OUTPUT
%   W       Mapping: Radial Basis Support Vector Classifier
%   KERNEL  Untrained mapping, representing the optimised kernel
%   NU      Resulting value for NU from NUSVC (W = NUSVC(A,KERNEL,C)
%   C       Resulting value for C (W = SVC(A,KERNEL,C)
%
% DESCRIPTION
% This routine computes a classifier by NUSVC using a radial basis kernel
% with an optimised standard deviation by REGOPTC. The resulting classifier
% W is identical to NUSVC(A,KERNEL,NU). As the kernel optimisation is based
% on internal cross-validation the dataset A should be sufficiently large.
% Moreover it is very time-consuming as the kernel optimisation needs
% about 100 calls to SVC.
%
% SEE ALSO (PRTools Guide)
% MAPPINGS, DATASETS, PROXM, SVC, NUSVC, REGOPTC

% Copyright: R.P.W. Duin, r.p.w.duin@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands

function [w,kernel,nu,c] = rbsvc(a,sig)

if nargin < 2 | isempty(sig)
	sig = NaN;
end

if nargin < 1 | isempty(a)

	w = prmapping(mfilename,{sig});

else

	islabtype(a,'crisp');
	isvaldfile(a,2,2);              % at least 1 object per class, 2 classes
	a = testdatasize(a,'objects');
  c = getsize(a,3);

	if (c > 2)

    % Compute c classifiers: each class against all others.
		w = mclassc(a,prmapping(mfilename,{sig}));

  else

	  if isnan(sig) % optimise sigma

		  % find upper bound
		  d = sqrt(+distm(a));
		  sigmax = min(max(d)); % max: smallest furthest neighbor distance
      % find lower bound
		  d = d + 1e100*eye(size(a,1));
		  sigmin = max(min(d)); % min: largest nearest neighbor distance
		  % call optimiser
		  defs = {1};
		  parmin_max = [sigmin,sigmax];
		  [w,kernel,nu,c] = regoptc(a,mfilename,{sig},defs,[1],parmin_max,testc([],'soft'));

	  else % kernel is given

		  kernel = proxm([],'r',sig);
		  [w,J,nu,c] = nusvc(a,kernel);

	  end

  end

end

w = setname(w,'RB-SVM');
return


function [F,sA] = spm_MDP_log_evidence(qA,pA,rA)
% Bayesian model reduction for Dirichlet hyperparameters
% FORMAT [F,sA] = spm_MDP_log_evidence(qA,pA,rA)
%
% qA  - sufficient statistics of posterior of full model
% pA  - sufficient statistics of prior of full model
% rA  - sufficient statistics of prior of reduced model
%
% F   - free energy or (negative) log evidence of reduced model
% sA  - sufficient statistics of reduced posterior
%
% This routine computes the negative log evidence of a reduced model of a
% categorical distribution parameterised in terms of Dirichlet
% hyperparameters (i.e., concentration parameters encoding probabilities).
% It uses Bayesian model reduction to evaluate the evidence for models with
% and without a particular parameter.
%
% It is assumed that all the inputs are column vectors.
%
% A demonstration of the implicit pruning can be found at the end of this
% routine
%__________________________________________________________________________
% Copyright (C) 2005 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_MDP_log_evidence.m 7326 2018-06-06 12:16:40Z karl $

% change in free energy or log model evidence
%--------------------------------------------------------------------------
sA = qA + rA - pA;
F  = spm_betaln(qA) + spm_betaln(rA) - spm_betaln(pA) - spm_betaln(sA);

return

% notes: Illustration of synaptic homoeostasis in terms of Bayesian model
% reduction that considers a competition between two inputs:
%--------------------------------------------------------------------------
x     = linspace(1,32,128);
pA    = [1; 1];
rA    = pA;
rA(2) = 8;
for i = 1:numel(x)
    for j = 1:numel(x)
        qA = [x(i);x(j)];
        F(i,j) = spm_MDP_log_evidence(qA,pA,rA);
    end
end

subplot(2,2,1), imagesc(x,x,F + (F > 0)*4),
title('Free energy landscape','FontSize',16), axis square xy
xlabel('concentration parameter'), ylabel('concentration parameter')
subplot(2,2,2), plot(x,F'),  title('log evidence','FontSize',16)
xlabel('concentration parameter'), ylabel('Log-evidence'), axis square


function [f, df] = myFunNew(X0, x, y, sn)
if nargin == 0
    clc; close all;
    x = [-20:0.1:60]';
    y = rand(length(x), 1);
    n = length(x);
    sn = 0.1;
    X0 = [0.1 0.1 log([2.0 2.0])]';
end
if isrow(x)
    x = x';
end
if isrow(y)
    y = y';
end
a = X0(1);
b = X0(2);
l = exp(X0(3));
l2 = l*l;
sf = exp(X0(4));
sf2 = sf*sf;
sn2 = sn^2;

n = length(x);
[K0, dK] = CalKFun(x, x, X0(3:4));
K = K0 + sn2*eye(n);
scale = 1000;
tt = eig(scale*K)/scale;
%%%%%%%%% make sure K is positive definite.
if min(tt) < 0.0
    K = K - min(tt)*eye(n);
end
if rank(K) < n
    K = K + 1e-6*eye(n);
end
% save('./K.mat');
L = chol(K, 'lower');
iL = inv(L);
iK = iL'*iL;
logDetK = 2*sum(log(diag(L)));

mx = a*x + b;
f = -0.5*(y-mx)'*iK*(y-mx) - 0.5*logDetK-0.5*n*log(2*pi);
%%%%%%%%%% calculate gradient.

Alpha = iK*(y-mx);
df2m = [x'; ones(1, n)] * Alpha;
A = Alpha * Alpha' - iK;
df2c = zeros(2, 1);
for i = 1 : 1 : 2
     nSum = 0;
     for id = 1 : 1 : n
         nSum = nSum + A(id, :) * dK{i}(:, id);
     end
     df2c(i) = 0.5*nSum;
end
df = [df2m; df2c];
f = -f;
df = -df;
bTest = 1;
end


function w_lcmv = sphLCMV(sphCOV, constraint_dirs, constraints)
%SPHLCMV Get beamforming weights for a LCMV beamformer in the SHD
%
%   Computes the beamweights for a linearly constrained minimum variance
%   (LCMV) beamformer using SH signals.
%
%   Inputs:
%       sphCOV:     (order+1)^2x(order+1)^2 covariance/correlation matrix
%           of SH signals
%       constraint_dirs:    Kx2 [azi elev] directions that the beamformer
%           should achieve the user-specified constraints
%       constraints:        Kx1 constraint values
%
%   Outputs:
%       w_lcmv: (order+1)^2x1 vector of beamforming weights
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SPHLCMV.M - 5/10/2016
% Archontis Politis, archontis.politis@aalto.fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

nSH = size(sphCOV,1);
order = sqrt(nSH)-1;

% steering vectors for distortionless constraints
constraint_dirs2 = [constraint_dirs(:,1) pi/2-constraint_dirs(:,2)]; % from azi-elevation to azi-inclination
Y_lcmv = getSH(order, constraint_dirs2, 'real');

% LCMV weights vector
stVecMtx = Y_lcmv.';
invA_B = sphCOV\stVecMtx;
B_invA_B = stVecMtx' * invA_B;
w_lcmv = (invA_B / B_invA_B) * constraints;

end


M = 5;
S1 = 4;
S2 = 4;
S = S1 + S2;
K = 2;
Y = zeros(M, S);
Y(1, 1:4) = [1 2 3 4];
Y(2, 1:4) = [3 3 2 6];
Y(3, 5:8) = [3 3 6 6];
Y(4, 5:8) = [4 5 6 7];
Y
Y = spx.norm.normalize_l2(Y)
C = spx.fast.omp_spr(Y, K, 0)

Y * C
abs(Y - Y * C)


clear;
clc
close all;
addpath('../../library/nav_lib');

%% inital state
SV_pos_ecef = [26580000, 0, 0]';
SV_vel_evef = [0 1755 3170]';
lat = 0.785398;
lon =  0.174533;
ght = 1000;
R0 = 6378137;
e = 0.0818191908425;
omaga = 7.29E-05;
c = 299792458;

[~, RE ] = ch_earth(lat, ght);

usr_ecef = ch_lla2ecef(lat, lon, ght);

 [az, el] = satellite_az_el(SV_pos_ecef, usr_ecef);
 rad2deg(el)
 rad2deg(az)


clear; clf;
		% Introducerea punctelor definite
t=[0,0.3,0.8,1.1,1.6,2.3]';
y=[0.5,0.82,1.14,1.25,1.35,1.4]';
		% Se reprezinta cu O-uri negre puntele date
plot(t,y,'Ko');
hold on;
        %Generarea matricei coeficientilor sistemului
A=[ones(size(t)),exp(-t),t.*exp(-t)];
        % Rezolvarea sistemului de ecuatii
a=A\y
        % Extragerea coeficientilor functiei de aproximare
a0=a(1); a1=a(2); a2=a(3);
        % Generarea punctelor in care se calculeaza
        % valorile functiei de aproximare
tt=linspace(0,2.5,200);
		% Calcularea valorilor functiei de aproximare
yy=a0+a1.*exp(-tt)+a2.*tt.*exp(-tt);
        % Reprezentarea grafica a functiei de aproximare
plot(tt,yy,'b','LineWidth', 1.5);
        % Personalizarea reprezentarii grafice
grid on;
xlabel('t');
ylabel('y');


function varargout = prtRvUtilPlotMvnEllipse(mu,Sigma,nStds,n)
% prtRvUtilPlotMvnEllipse plots the confidence region of a multivariate Gaussian
%
% Syntax: [ellipseHandle, contourXY] = prtRvUtilPlotMvnEllipse(mu,Sigma,nStds)
%
% Adapted From: http://www.mathworks.com/matlabcentral/fileexchange/8793
% Then re-adpated from Beals Mixture of Factor Analyzes Code

%assert(ismember(numel(mu),[2 3]),'prtRvUtilPlotMvnEllipse only works in 2 or 3 /lr   Bv  5,plot(sigmaEigVectors(1,iVec)*[-1 1]*sigmaEigValues(iVec,iVec)*nStd + cMean(1),sigmaEigVectors(2,iVec)*[-1 1]*sigmaEigValues(iVec,iVec)*nStd + cMean(2),'color',cmap(max(ceil(cPi*size(cmap,1)),1),:));dimensions.');

if nargin < 3 || isempty(nStds)
    nStds = 1;
end
if nargin < 4 || isempty(n)
    n = 20;
end
mu = mu(:);

switch numel(mu)
    case 2
        theta = (0:1:n-1)/(n-1)*2*pi;

        epoints = nStds*sqrtm(Sigma) * [cos(theta); sin(theta)]*1   + mu*ones(1,n);

        ellipseHandle = plot(epoints(1,:),epoints(2,:),'LineWidth',3);

    case 3
        theta = (0:1:n-1)'/(n-1)*pi;
        phi = (0:1:n-1)/(n-1)*2*pi;

        sx = sin(theta)*cos(phi);
        sy = sin(theta)*sin(phi);
        sz = cos(theta)*ones(1,n);

        svect = [reshape(sx,1,n*n); reshape(sy,1,n*n); reshape(sz,1,n*n)];
        epoints = nStds*sqrtm(Sigma) * svect  + mu*ones(1,n*n);

        ex = reshape(epoints(1,:),n,n);
        ey = reshape(epoints(2,:),n,n);
        ez = reshape(epoints(3,:),n,n);

        ellipseHandle = mesh(ex,ey,ez);
end
% [Ev,D] = eig(Sigma);
% iV = inv(Sigma);
%
% % Find the l    arger projection
% P = [1,0;0,0];  % X-axis projection operator
% P1 = P * 2*sqrt(D(1,1)) * Ev(:,1);
% P2 = P * 2*sqrt(D(2,2)) * Ev(:,2);
% if abs(P1(1)) >= abs(P2(1)),
%     Plen = P1(1);
% else
%     Plen = P2(1);
% end
% count = 1;
% step = 0.001*Plen;
% Contour1 = zeros(2001,2);
% Contour2 = zeros(2001,2);
% for x = -Plen:step:Plen,
%     a = iV(2,2);
%     b = x * (iV(1,2)+iV(2,1));
%     c = (x^2) * iV(1,1) - 1;
%     Root1 = (-b + sqrt(b^2 - 4*a*c))/(2*a);
%     Root2 = (-b - sqrt(b^2 - 4*a*c))/(2*a);
%     if isreal(Root1),
%         Contour1(count,:) = [x,Root1] + mu(:)';
%         Contour2(count,:) = [x,Root2] + mu(:)';
%         count = count + 1;
%     end
% end
% Contour1 = Contour1(1:count-1,:);
% Contour2 = [Contour1(1,:);Contour2(1:count-1,:);Contour1(count-1,:)];
%
% contourXY = cat(1,Contour1,flipud(Contour2));
%
% ellipseHandle = plot(contourXY(:,1),contourXY(:,2));

varargout = {};
if nargout
    varargout = {ellipseHandle};
end

end


function [mm] = nm2mm(nm)
% Convert length from nanometers to millimeters.
% Chad A. Greene 2012
mm = nm*0.000001;


function [prod,deriv] = mm_special(w,extractA,extractB)
% This is an MV2DF. See MV2DF_API_DEFINITION.readme.
%
%   [vec(A);vec(B)] --> vec(A*B)
%
% where
%   A is extractA(w)
%   B is extractB(w)

if nargin==0
    test_this();
    return;
end

if isempty(w)
    prod = @(w)mm_special(w,extractA,extractB);
    return;
end

if isa(w,'function_handle')
    outer = mm_special([],extractA,extractB);
    prod = compose_mv(outer,w,[]);
    return;
end

w = w(:);
A = extractA(w);
[m,k] = size(A);

B = extractB(w);
[k2,n] = size(B);
assert(k==k2,'inner matrix dimensions must agree');

M = A*B;
prod = M(:);

deriv = @(g2) deriv_this(g2);

function [g,hess,linear] = deriv_this(g2)
g = vJ_this(g2,A,B);
linear = false;
hess = @(w) hess_this(g2,w);
end

function [h,Jv] = hess_this(g2,w)
h = vJ_this(g2,extractA(w),extractB(w));
if nargout>=2
    Jv = Jv_this(w);
end
end

function prod = Jv_this(w)
Aw = extractA(w);
Bw = extractB(w);
M = Aw*B + A*Bw;
prod = M(:);
end

function w = vJ_this(prod,A,B)
M = reshape(prod,m,n);
Bp = A.'*M;
Ap = M*B.';
w = [Ap(:);Bp(:)];
end

end

function A = extractA_this(w,m,k)
A = w(1:m*k);
A = reshape(A,m,k);
end

function B = extractB_this(w,m,k,n)
B = w(m*k+(1:k*n));
B = reshape(B,k,n);
end

function test_this()

m = 4;
k = 5;
n = 6;

A = randn(m,k);
B = randn(k,n);

w = [A(:);B(:)];

extractA = @(w) extractA_this(w,m,k);
extractB = @(w) extractB_this(w,m,k,n);

f = mm_special([],extractA,extractB);
test_MV2DF(f,w);
end


function y = daub4_transform ( n, x )

%*****************************************************************************80
%
%% DAUB4_TRANSFORM computes the DAUB4 transform of a vector.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 July 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of the vector.
%    N must be a power of 2 and at least 4.
%
%    Input, real X(N), the vector to be transformed.
%
%    Output, real Y(N), the transformed vector.
%
  c = [  0.4829629131445341E+00; ...
         0.8365163037378079E+00; ...
         0.2241438680420133E+00; ...
        -0.1294095225512603E+00 ];

  y(1:n,1) = x(1:n);
  z(1:n,1) = 0.0;

  m = n;

  while ( 4 <= m )

    i = 1;

    for j = 1 : 2 : m - 1
      j0 = i4_wrap ( j,     1, m );
      j1 = i4_wrap ( j + 1, 1, m );
      j2 = i4_wrap ( j + 2, 1, m );
      j3 = i4_wrap ( j + 3, 1, m );
      z(i,1)     = c(1) * y(j0) + c(2) * y(j1) + c(3) * y(j2) + c(4) * y(j3);
      z(i+m/2,1) = c(4) * y(j0) - c(3) * y(j1) + c(2) * y(j2) - c(1) * y(j3);
      i = i + 1;
    end

    y(1:m,1) = z(1:m);

    m = floor ( m / 2 );

  end

  return
end


function poly_coef_count_test ( )

%*****************************************************************************80
%
%% POLY_COEF_COUNT_TEST tests POLY_COEF_COUNT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 October 2008
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'POLY_COEF_COUNT_TEST\n' );
  fprintf ( 1, '  POLY_COEF_COUNT counts the number of coefficients\n' );
  fprintf ( 1, '  in a polynomial of degree DEGREE and dimension DIM\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ' Dimension    Degree     Count\n' );

  for dim = 1 : 3 : 10
    fprintf ( 1, '\n' );
    for degree = 0 : 5
      fprintf ( 1, '  %8d  %8d  %8d\n', ...
        dim, degree, poly_coef_count ( dim, degree ) );
    end
  end

  return
end


function lattice_rule_test11 ( )

%*****************************************************************************80
%
%% LATTICE_RULE_TEST11 tests MONTE_CARLO;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 November 2008
%
%  Author:
%
%    John Burkardt
%
  dim_num = 2;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'LATTICE_RULE_TEST11\n' );
  fprintf ( 1, '  MONTE_CARLO applies a Monte Carlo scheme\n' );
  fprintf ( 1, '  to estimate the integral of a function\n' );
  fprintf ( 1, '  over the unit hypercube.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The spatial dimension DIM_NUM = %d\n', dim_num );

  a(1:dim_num) = 0.0;
  b(1:dim_num) = 1.0;

  exact = e_01_2d ( dim_num, a, b );

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

  for k = 2 : 5

    m = 10^k;

    quad = monte_carlo ( dim_num, m, @f_01_2d );

    error = abs ( exact - quad );

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

  end

  return
end


% function h = plotclr(x,y,v,marker,vlim)
% plots the values of v colour coded
% at the positions specified by x and y.
% A colourbar is added on the right side of the figure.
%
% The colourbar strectches from the minimum value of v to its
% maximum.
%
% 'marker' is optional to define the marker being used. The
% default is a point. To use a different marker (such as circles, ...) send
% its symbol to the function (which must be enclosed in '; see example).
%
% 'vlim' is optional, to define the limits of the colourbar.
% v values outside vlim are not plotted
%
% modified by Stephanie Contardo, CSIRO, 2009
% from 'plotc' by Uli Theune, University of Alberta, 2004
%

function h = plotclr(x,y,v,marker,vlim)

if nargin <4
    marker='.';
end

map=colormap;
if nargin >4
    miv = vlim(1) ;
    mav = vlim(2) ;
else
    miv=min(v);
    mav=max(v);
end
clrstep = (mav-miv)/size(map,1) ;
% Plot the points
hold on
for nc=1:size(map,1)
    iv = find(v>miv+(nc-1)*clrstep & v<=miv+nc*clrstep) ;
    plot(x(iv),y(iv),marker,'color',map(nc,:),'markerfacecolor',map(nc,:))
end
hold off

% Re-format the colorbar
h=colorbar;

%set(h,'ylim',[1 length(map)]);
yal=linspace(1,length(map),10);
set(h,'ytick',yal);
% Create the yticklabels
ytl=linspace(miv,mav,10);
s=char(10,4);
for i=1:10
    if min(abs(ytl)) >= 0.001
        B=sprintf('%-4.3f',ytl(i));
    else
        B=sprintf('%-3.1E',ytl(i));
    end
    s(i,1:length(B))=B;
end
set(h,'yticklabel',s);
grid on
view(2)


function ccfi_1_tabulate ( )

%*****************************************************************************80
%
%% CCFI_1_TABULATE tabulates CCFI_1 quadrature rules for the Laguerre integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 May 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CCFI_1_TABULATE\n' );
  fprintf ( 1, '  Tabulate CCFI_1 quadrature rules for the Laguerre integral.\n' );
  fprintf ( 1, '  Density function rho(x) = 1.\n' );
  fprintf ( 1, '  Region: 0 <= x < +oo.\n' );
  fprintf ( 1, '  Exactness: NONE.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Print the first 5 rules:\n' );
  fprintf ( 1, '   I          X(I)            W(I)\n' );
  fprintf ( 1, '\n' );

  ell = 1.0;

  for n = 1 : 5

    [ x, w ] = ccfi_1 ( n, ell );

    fprintf ( 1, '\n' );
    for i = 1 : n
      fprintf ( 1, '  %2d  %14.6f  %14.6f\n', i, x(i), w(i) );
    end
    fprintf ( 1, ' Sum                  %14.6f\n', sum ( w(1:n) ) );

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Print the first 5 nested rules:\n' );
  fprintf ( 1, '   I          X(I)            W(I)\n' );
  fprintf ( 1, '\n' );

  ell = 1.0;

  for j = 1 : 5

    n = 2^j - 1;

    [ x, w ] = ccfi_1 ( n, ell );

    fprintf ( 1, '\n' );
    for i = 1 : n
      fprintf ( 1, '  %2d  %14.6f  %14.6f\n', i, x(i), w(i) );
    end
    fprintf ( 1, ' Sum                  %14.6f\n', sum ( w(1:n) ) );

  end

  return
end


function showrateh4(h1,err1,k1,opt1,str1,h2,err2,k2,opt2,str2,...
                    h3,err3,k3,opt3,str3,h4,err4,k4,opt4,str4)
%% SHOWRATEH4 rate of two error sequences
%
% showrateh4(N1,err1,k1,opt1,str1,N2,err2,k2,opt2,str2,N3,err3,k3,opt3,str3,err4,k4,opt4,str4)
% plots the err1 vs N1, err2 vs N2, err3 vs N3, and err4 vs N4 in the
% loglog scale. Additional input
%
%   - k1, k2, k3, k4: specify the starting indices; see showrate
%   - opt1, opt2, opt3, opt4: the line color and style
%   - str1, str2, str3, str4: strings used in legend
%
% Example
%
%
% See also showrate, showresult, showmesh, showsolution
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

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


function grid_test ( code )

%*****************************************************************************80
%
%% GRID_TEST tests the grid routines.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string CODE, the code for the element.
%    Legal values include 'Q4', 'Q8', 'Q9', 'Q12', 'Q16', 'QL',
%    'T3', 'T4', 'T6' and 'T10'.
%

%
%  NODE is defined as a vector rather than a two dimensional array,
%  so that we can handle the various cases using a single array.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  GRID_TEST: Test the grid routine for element "%s"\n', code );

  nelemx = 3;
  nelemy = 2;

  fprintf ( 1, '  Number of elements in X direction = %d\n', nelemx );
  fprintf ( 1, '  Number of elements in Y direction = %d\n', nelemy );

  element_order = order_code ( code );

  node_num = grid_node_num ( code, nelemx, nelemy );

  fprintf ( 1, '  Element order =       %d\n', element_order );
  fprintf ( 1, '  Nodes in grid =       %d\n', node_num );

  element_num = grid_element_num ( code, nelemx, nelemy );

  element_node = grid_element ( code, element_order, nelemx, nelemy );

  grid_print ( element_order, element_num, element_node );

  width = grid_width ( element_order, element_num, element_node );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The grid width is %d\n', width );

  return
end


%% Toolbox Sparsity - A toolbox for sparse coding and sparse regularization
%
% Copyright (c) 2008 Gabriel Peyre
%

%%
% The toolbox can be downloaded from Matlab Central
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=16204&objectType=FILE

%%
% We first includes in the path some additional useful scripts.
path(path, 'toolbox/');

%% Overview
%
% This toolbox implements several algorithms to compute sparse expansion in redundant dictionaries and to solve inverse problems with sparse regularization
% (and also TV regularization).
%

%%
% Sparse expansion of a signal |f| of size |n| in a redundant dictionary |D| (which is a matrix of size |n x p| with |p>n|, or an implicit operator)
% corresponds to the computation of coefficients |x| of size |p| such that |f=D*x| (or approximate equality |norm(y-D*x)<epsilon|). Since many |x| are possible, one
% can assume that |x| is sparse, for instance supposing that it as a small L1 norm |sum(abs(x))|. This can be achieved by Lagrangian optimization
%

%%
% |min_x 1/2*norm(f-D*x)^2 + T*sum(abs(x))|  (1)

%%
% where |T| is increased if |epsilon| is increased.

%%
% Sparse regularization for the resolution of |y=U*f + noise| (where |U| is a rank defficientis equivalent) corresponds to the computation of a solution
% |f| that is sparse in a dictionary |D|, thus being |f=D*x| with small L1 norm. This is performed by solving

%%
% |min_x 1/2*norm(y-U*D*x)^2 + T*sum(abs(x))|   (2)

%%
% And the solution is computed from the optimal coefficients |x| as |f=D*x|.
%
% Problems (1) and (2) are equivalent if one replaces the dictionary |D| of (1) by the transformed dictionary |U*D| in (2). One can thus use the same
% software to solve both (2) and (1).

%%
% TV regularization corresponds to replacing (2) by

%%
% |min_f 1/2*norm(y-U*f)^2 + T*TV(f)|   (3)
%
% where |TV(f)| is the discrete TV norm of the signal/image |f|. Intuitively, this corresponds to assuming that the gradient of |f| is sparse, so (3) is
% quite close to (2) if |D| is chosen a translation invariant Haar wavelet dictionary. But optimizing (3) and (2) necessitate different algorithms.

%%
%
% * To solve (1) or (2) with |epsilon=0| (no noise), which corresponds to the minimum L1 norm solution to |f=D*x| or |y=U*D*x|, this toolbox implements the Douglas-Rachford iterative algorithm.
% * To solve (1) or (2), this toolbox implements the iterative soft thresholding algorithm. If |T| is not known but |epsilon| is known, then the implementation automatically computes the correct |T| during the iterations.
% * To solve (3), this toolbox implements Chambolle's JMIV 2002 algorithm. If |T| is not known but |epsilon| is known, then the implementation automatically computes the correct |T| during the iterations.

%% Compressed sensing of exactely sparse signals with Fourier measurements.

%%
% First, we create an |s|-sparse signal with random spikes locations and
% random coefficients values.

% dimensionality
n = 1024;
% sparsity
s = 25;
% generate random spikes
x0 = compute_rand_sparse(n, s, 'uniform');

%%
% We select an operator |U|, which is a pre-defined implicit operator.
% This is done by filling in a structure |options| with the correct
% parameters. Many other measurement matrices are available for Compressive
% Sensing (Gaussian, Bernouilli, Fourier, Sinus, Hadamard, etc).

% number of measurements
p = 100;
% type of matrix
clear options;
options.cs_type = 'fourier';
options.n = n;
options.p = p;

%%
% We perform the measurements (without noise) by applying the sensing
% operator.

y = callback_sensing_rand(x0, +1, options);

%%
% We can display the signal vector and the measurements

clf;
subplot(2,1,1);
plot_sparse_diracs(x); title('Signal x_0');
subplot(2,1,2);
h = plot(real(y)); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Measurements y=U*x_0');

%%
% Since there is no noise, the recovery can be performed using
% Douglas-Rachford algorithm. Special thanks to Jalal Fadili for his help
% on this algorithm.

% set to 1 these options if you want cool displays
options.verb = 0;
options.draw_iter = 0;
% parameter of the algorithm
options.niter = 3000;
options.x = zeros(n,1);
[xlun,lun] = perform_douglas_rachford(@callback_sensing_rand, y, options);
xlun = real(xlun);

%%
% We can display the result. This is a case of perfect recovery, |xlun=x0|!
% However, if you increase slightly the value of |s|, then the recovery
% fails ...

clf;
options.title = {'Signal' 'Recovery'};
options.val = .01; % remove small residual
plot_sparse_diracs({x0 xlun}, options);

%%
% We can also display the decrease of the L1 norm of the solution during
% the iterations, to check that the algorithm really does a good job.

clf;
h = plot(lun); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
xlabel('#iteration'); ylabel('L_1 norm |x|_1');

%% Compressed sensing of a noisy sparse signals with Gaussian measurements.

%%
% To be more robust to noise, we need to decrease the number of
% measurements. Also, we are going to use Gaussian real measurements, which
% in fact perform twice less measurements than complex Fourier
% measurements.

% sparsity
s = 20;
% generate random spikes
x0 = compute_rand_sparse(n, s, 'uniform');

%%
% We perform noisy measurements.
% We also select an other kind of matrix, given in explicit form (an array |U|
% of double). This is possible only for small size problems.

% Generate a matrix for sensing
U = randn(p,n);
% noiseless measurements
y = U*x0;
% make some noise
sigma = .06*std(y(:)); % noise level
y = y + sigma*randn(size(y));

%%
% Since there is some noise, we need to use iterative thresholding.
% The regularization parameter is adapted automatically to fit the noise
% level |sigma|.

% amplification is >1 to further sparsify the solution
amplification = 2;
% norm of the noise |epsilon|
options.etgt = amplification * sigma*sqrt(p);
% initial regularization parameter
options.T = 1;
% perform iterative thresholding
options.niter = 4000;
[xlun,err,lun,lambda] = perform_iterative_thresholding( U,y,options);

%%
% We can display the evolution of the threshold |lambda| during the iterations
% and also display the decay of the Lagrangian to see what the algorithm is
% doing.

clf;
subplot(2,1,1);
h = plot(lambda); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of \lambda');
subplot(2,1,2);
lagr = .5*err.^2 + lambda(end)*lun;
h = plot(lagr); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of |y-U x|^2+\lambda |x|_1');
axis([1 options.niter min(lagr) min(lagr)*1.5]);

%%
% The solution of the L1 minimization is biased, because L1 tends to
% under-estimate the value of the true coefficients (this is very much
% similar to the issue with soft thresholding). To remediate to this
% issue, it is possible to "debiased" the solution by extracting the
% support and then performing an L2 best fit (which is not biased) of the
% measurements. Be aware that this might give bad results if the
% support is baddly estimated.

% remove small amplitude coefficients because they are not very reliable
xdeb = xlun .* (abs(xlun)>.05);
% perform L2 regression
xdeb = perform_debiasing(U,xdeb,y);

%%
% We can display the result. There is no more perfect recovery because of
% the noise, but the solution is close to the original signal.

clf;
options.title = {'Signal' 'Recovery' 'Debiased'};
options.val = .01; % remove small residual
plot_sparse_diracs({x0 xlun xdeb}, options);

%% Tomography inversion of an image with TV regularization.
% We can recover from partial Fourier measurements using TV regularization.
% We add some noise to the measurement, and perform the recovery using
% Chambolle's algorithm for TV regularization.

%%
% First we load the image.

n = 256;
M = load_image('phantom', n);
M = rescale(M,.05,.95);

%%
% Then we load the tomography mask.

nrays = 18; % Candes/Romberg/Tao set up
mask = compute_tomography_mask(n,nrays);
% number of measurements
p = sum(mask(:)==1);
% display
imageplot({M mask}, {'Signal' 'Frequencies'});

%%
% We set up |options| for the tomography operator (sub-sampling of the
% frequencies) and perform measurements.

options.size = size(M);
options.mask = mask;
y = callback_tomography(M,+1,options);
% add some noise
sigma = .01*std(y(:));
y = y + sigma*randn(size(y));

%%
% We can perform L2 pseudo-inversion (zero padding in Fourier) by just applying
% the transpose operator.

M2 = callback_tomography(y,-1,options); M2 = real(M2);
imageplot({M clamp(M2)}, {'Original' 'L2 inversion'});

%%
% We can perform inversion with TV regularization.

% set up parameter for the regularization
options.TVoperator = @callback_tomography;
options.TVrhs = y;
options.etgt = 4*sigma*sqrt(p); % target noise level
options.niter = 300;
options.niter_inner = 30; % iteration for inner loop of Chambolle's algorithm.
options.tol = 1e-4;
options.display = 0; % set to 1 for sexy display
options.verb = 0;
options.tau = 1/8;
% perform the regularization
[Mtv,err,tv,lambda] = perform_tv_denoising(zeros(n),options);

%%
% We can display the results.

clf;
imageplot({M clamp(Mtv)}, {'Original' 'Recovery'});

%%
% We can display the evolution of the regularization
% parameter and the TV energy.

clf;
subplot(2,1,1);
h = plot(lambda); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of \lambda');
subplot(2,1,2);
lagr = .5*err.^2 + lambda(end)*tv;
h = plot(lagr); axis tight;
set(h, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Evolution of |y-U x|^2+\lambda |x|_1');
axis([1 options.niter min(lagr) min(lagr)*1.5]);

%% Sparse spikes deconvolution with L1 regularization and Matching Pursuit
% sparse spikes deconvolution corresponds to inverting a band pass filter.
% This is very much used in seismic imaging where the filter is called a
% wavelet. Since the signal (reflecticity of the ground) is composed of
% isolated spikes, one uses L1 minimisation in the diract basis to recover
% the signal. This can also be performed by other sparse optimization
% technics such as greedy matching pursuit. Note that the operator |U| is
% equal to the dictionary |D| in this case, and is composed of translated
% copy of the filter. Since this results in a highly ill posed operator,
% one needs to sub-sample the dictionary a little.

%%
% First we load a filter which is a second derivative of a Gaussian

clear options;
n = 1024;
options.sigma = .02;
h = compute_sparse_spike_filter('dergauss',n,options);
h = h/max(h);

%%
% We can display the filter and its fourier transform (to see how much
% frequencies are removed by the filtering).

hf = real(fft(h)); hf = hf / max(hf);
clf;
subplot(2,1,1);
hh = plot(fftshift(h)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Filter');
subplot(2,1,2);
hh = plot(fftshift(hf)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Fourier Transform');

%%
% Then we build a dictionary of sub-sampled translated copies of |h|.

q = 2; % sub-sampling (distance between wavelets)
p = n/q;
[Y,X] = meshgrid(1:q:n,1:n);
D = h(mod(X-Y,n)+1);

%%
% We can display a sub-set of elements of the dictionary.

clf;
sel = round( linspace(1,p,5) ); sel(end) = [];
hh = plot(D(:,sel)); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Translated wavelets');

%%
% Joel Tropp and Jean-Jacques Fuchs have derived in several IEEE Tr. Info.
% Theory papers some powerfull bounds of the recovery of signals with L1
% minimization. This includes the Fuchs (which depends on the sign of the coefficients),
% ERC and WERC (which depend only on the support of the coefficients) criterions.
% We display here these three criterions to see wether a Dirac spikes train
% of spacing |Delta| between two consecutive spikes can be recovered stably
% by both matching
% pursuit and L1 minimization (basis pursuit).
% The dashed vertical lines display the critical spacing as detected by
% these three criterions.

options.display = 1;
options.delta_max = 100;
options.verb = 0;
[minscale,crit,lgd] = compute_minimum_scale(D, options);
set(gca, 'FontSize', 20);
xlabel('\Delta');

%%
% We create a sparse spikes train, with a default in the middle (two close
% spikes). Note that we select the spacing between the spikes slightly below the minimum scale detected
% by ERC<1, which causes sparsity methods to become unstable, and matching pursuit to fail.

options.delta = 23; % regular spacing
options.delta0 = 3; % create default that is not recovered by BP
x = compute_rand_sparse(p, 0, 'seismic', options);

%%
% The signal is the convolution with the filters plus noise.

sigma = .03;
y = D*x + randn(n,1)*sigma;
% display
clf;
subplot(2,1,1);
plot_sparse_diracs(x);
title('Sparse spikes x');
subplot(2,1,2);
hh = plot(y); axis tight;
set(hh, 'LineWidth', 2);
set(gca, 'FontSize', 20);
title('Signal y=Dx+w');

%%
% We can recover the signal using L1 minimisation plus debiasing.

options.T = 1;
options.niter = 1000;
options.etgt = 5*sigma*sqrt(n); % noise level
options.x = zeros(p,1); % initial solution
[xlun,err,lun,Tlist]  = perform_iterative_thresholding(D,y,options);
% perform debiasins
xlun(abs(xlun)<.08)=0;
xdeb = perform_debiasing(D,xlun,y);
% display
options.title = {'Signal' 'L1' 'Debiased'};
plot_sparse_diracs({x xlun xdeb}, options);

%%
% Another way to solve the problem is using greedy matching pursuit
% procedure. Most of the time, it gives results comparable or a little worse
% than basis pursuit, but it is faster. Here, we are in a critical set up
% where basis pursuit performs better than matching pursuit. The toolbox
% implements basis matching pursuit and its orthogonalized version. Only
% the basic pursuit is implemented with implicit operator, and orthogonalized
% pursuit requires the computation of many pseudo inverse (so it is quite slow).

% parameters for the pursuits
options.tol = 3*norm(w)/norm(y);
options.nbr_max_atoms = 80;
xmp = perform_mp(D,y,options);
xomp = perform_omp(D,y,options);
% display
options.title = {'Signal' 'Matching pursuit' 'Orthogonal Matching Pursuit'};
plot_sparse_diracs({x xmp xomp}, options);

%% Image inpainting with sparse wavelets regularization
% Image inpainting consists in filling missing pixels in an image. Many inpainting
% algorithm rely on a diffusion PDE that try to propagate information from
% the boundary of the missing region. An alternative methods consist in
% treating this problem as an inverse problem. Inpainting indeed
% corresponds to a diagonal operator |U| with 0 and 1 on the diagonal (0
% indicating missing pixels). This can be regularized using iterative
% thresholding. Since there is no noise, we want to use a very low
% threshold. This can be achieved by decaying the threshold during the
% iterations, and corresponds to the Morphological Component Analysis
% strategy of Jean-Luc Starck, Miki Elad and David Donoho.
% See also the homepage of Jalal Fadili for many example of inpainting.

%%
% First we load an image and a mask.

clear options;
n = 128;
M = load_image('lena');
M = rescale( crop(M,n) );
options.rho = .7; % remove 70% of pixels
mask = compute_inpainting_mask('rand',n,options);
options.mask = mask;

%%
% Apply the operator to remove pixels.

y = callback_inpainting(M, +1, options);
imageplot({M y}, {'Image' 'Data to inpaint'});

%%
% First we set up the dictionary: a translation invariant wavelet
% dictionary.

options.Jmin = 4;
options.wavelet_type = 'biorthogonal';
options.wavelet_vm = 3;
options.D = @callback_atrou;

%%
% Then we set up decaying thresholding parameter for the MCA solver.

options.thresh = 'soft';
options.Tmax = .1;
options.Tmin = 0;
options.niter = 200;
options.tau = 1;
options.drawiter = 0;
options.verb = 0;

%%
% Perform the inpainting using sparse wavelet expansion.

% do the resolution
[MW,err,lun,Tlist] = perform_iterative_thresholding(@callback_inpainting, y, options);
% retrieve the image from its coefficients
Mlun = callback_atrou(MW, +1, options);

%%
% Display the result

imageplot({M clamp(Mlun)},{'Original' 'Recovered'});

%% Dictionary Learning
% Instead of using a fixed dictionary |D| to compress or denoise a signal
% with sparse coding (or to solve an inverse problem), it is possible to
% optimize |D| in order to sparsify a set of given exemplar. In practice,
% these exemplar are taken as small patches extracted from tons of natural
% images. As first shown by Olshausen and Field, the optimized atoms then
% ressemble those of an oriented (steerable) wavelet frame.

%%
% The parameter of the dictionary

% size of the patches
w = 12; n = w^2;
% redundancy of the dictionary
redun = 1.5;
% number of atoms
p = round( n*redun );
% overtraining factor
overtraining = 6;
% number of example
m = round( overtraining*p );

%%
% First we load a set of images
Mlist = load_image({'lena' 'barb' 'boat'});

%%
% Then we extract a large set of patches from these images

Y = load_random_patches(Mlist,w,m);

%%
% Parameters for the learning of the dictionary (optimization of the atoms
% using an iterative method).

% number of atoms
options.K = p;
% number of iterations
options.niter_learning = 60;
% solver used for the sparse coding stage
options.sparse_coder = 'omp';
options.sparse_coder = 'mp';
% sparsity targeter for the sparse code
options.nbr_max_atoms = 5;
% initialization method
options.options.init_dico = 'input';

%%
% Perform the learning using an optimization procedure called the MOD
% (Method of Direction) algorithm.

options.learning_method = 'mod';
options.verb = 0;
[D1,X1,E1] = perform_dictionary_learning(Y,options);

%%
% Display the vectors of the dictionary as small images.
% You can notice that the texture of barbara is occupating many atoms !

clf;
options.ndim = 2;
options.normalization = 'clamp';
display_dictionnary(D1, X1, [10 14], options );


function label = DBSCAN(data, eps, minPts)
% label = DBSCAN(data, epsilon, minPts)
%   Main part of DBSCAN (Density-Based Spatial Clustering of Application with
% Noise)clustering algorithm.
% ----
% Args:
%   data: data to be clustered (n * p)
%   eps: distance threshold for finding neighbors
%   minPts: minimum required number of neighbor observations for one core object
% ----
% Returns:
%   label: corresponding class for each observation

% Initialization
core_object = [];
count = 1;
k = 1; % label index
vmask = ones(size(data, 1), 1); % variable used to record whether one observation has been visited (1: not visited, 0: visited)
label = zeros(size(data, 1), 1); % pre-allocate result

% Find core objects
for i = 1:size(data, 1)
    x = data(i, :); % current observation of interests
    [~, neighbors] = Find_Neighbor(data, x, eps);

    % Check if the number of observations in neighbors of x is larger than minPts
    if((size(neighbors,1)-1) >= minPts)

        % Add the index of x to the set of core object
        core_object(count, 1) = i;
        count = count + 1;
    end
end

fprintf('---- DBSCAN finds a total number of %i core objects ----\n', size(core_object, 1));

while(~isempty(core_object))

    % Construct one queue for further use
    queue = [];
    qcount = 1;

    % Update core_object, observations have been visited should be deleted
    tcount = 1;
    list = [];
    for i = 1:size(core_object, 1)
        if(vmask(core_object(i, 1),1) == 0)
            list(tcount ,1) = i;
            tcount = tcount + 1;
        end
    end
    core_object(list,:) = [];

    if(isempty(core_object))
        break;
    end

    % Randomly choose one core object
    index = core_object(randi(size(core_object, 1)), 1);
    queue(qcount, 1) = index; % add the selected core object to the queue
    qcount = qcount + 1;
    vmask(index, 1) = 0; % update vmask
    label(index, 1) = k; % assign result
    core_object(core_object == index, :) = []; % remove the selected core object from the set

    while(~isempty(queue))
        pivot = queue(1, 1);
        queue(1, :) = []; % remove the first element in queue
        qcount = qcount - 1;

        % Find neighbors for current observation of interests
        [tindex, tneighbors] = Find_Neighbor(data, data(pivot, :), eps);
        if(size(tneighbors, 1) >= minPts)
            for i = 1 : size(tindex, 1)
                % If one neighbor has not been visited, add it to the queue
                if(vmask(tindex(i, 1),1) == 1)
                    queue(qcount, 1) = tindex(i, 1);
                    qcount = qcount + 1;
                    vmask(tindex(i, 1),1) = 0; % update vmask
                    label(tindex(i, 1),1) = k; % assign result
                end
            end
        end
    end

    fprintf('---- Finish finding observations for class %i ----\n', k);
    k = k + 1; % next class
end
end

function d = Eculidean_Distance(x1, x2)
% Calculate eculidean distance between x1 and x2.
%
% Args:
%   x1: observation 1
%   x2: observation 2
%
% Returns:
%   d: Eculidean distance between x1 and x2

d = sqrt((x1 - x2) * (x1 - x2)');
end

function [index, neighbors] = Find_Neighbor(data, x, eps)
% Find neighbors for x, where neighbors are defined to be observations in data
% with eculidean distance from x smaller than epsilon.
%
% Args:
%   data: dataset
%   x: current observation of interests
%   eps: pre-defined distance threshold
%
% Returns:
%   index: the index of these neighbors in data
%   neighbors: neighbor set of x

neighbors = []; % pre-allocate neighbor result
count = 1;
for i = 1 : size(data,1)
    d = Eculidean_Distance(data(i,:), x);
    if(d <= eps)
        index(count, 1) = i;
        neighbors(count,:) = data(i,:);
        count = count + 1;
    end
end
end


function [ fea, out ] = ex_axistressstrain5( varargin )
%EX_AXISTRESSSTRAIN5 Axisymmetric vibration modes of a hollow cylinder.
%
%   [ FEA, OUT ] = EX_AXISTRESSSTRAIN5( VARARGIN ) Axisymmetric
%   vibration modes of a hollow cylinder (NAFEMS Free Vibration Benchmark 41).
%
%   Reference:
%
%   [1] F. Abassian, D.J. Dawswell, and N.C. Knowles, Free Vibration
%   Benchmarks, Volume 3, NAFEMS, Glasgow, 1987.
%
%   Accepts the following property/value pairs.
%
%       Input       Value/{Default}        Description
%       -----------------------------------------------------------------------------------
%       igrid       scalar 0/{2}           Cell type (>0=quadrilaterals, <0=triangles)
%       sfun        string {sflag1}        Shape function
%       iplot       scalar 0/{1}           Plot solution (=1)
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       fea         struct                 Problem definition struct
%       out         struct                 Output struct

% Copyright 2013-2022 Precise Simulation, Ltd.

cOptDef = { 'igrid',    2;
            'sfun',     'sflag1';
            'iplot',    1;
            'tol',      0.01;
            'fid',      1 };
[got,opt] = parseopt(cOptDef,varargin{:});
fid       = opt.fid;

E   = 2e11;
nu  = 0.3;
rho = 8000;

% Geometry definition.
fea.sdim = {'r' 'z'};
gobj = gobj_rectangle( 1.8, 2.2, 0, 10, 'R1' );
fea.geom.objects = { gobj };

fea.grid = rectgrid( abs(opt.igrid)*2, abs(opt.igrid)*50, [ 1.8, 2.2; 0, 10 ]);
if( opt.igrid<0 )
  fea.grid = quad2tri( fea.grid );
end

% Equations and problem definition.
fea = addphys( fea, @axistressstrain );
fea.phys.css.eqn.coef{1,end} = { nu  };
fea.phys.css.eqn.coef{2,end} = { E   };
fea.phys.css.eqn.coef{3,end} = { rho };
fea.phys.css.sfun            = { opt.sfun, opt.sfun };

% Solve problem.
fea = parsephys( fea );
fea = parseprob( fea );

[fea.sol.u,fea.sol.l] = solveeig( fea, 'fid', fid );

% Postprocessing.
if( opt.iplot>0 )
  postplot( fea, 'surfexpr', 'sqrt((r*u)^2+w^2)', 'solnum', 2 )
end

out = [];
f = sqrt(max(0,fea.sol.l))/(2*pi);
f_ref = [ 0; 243.773387; 378.534723; 394.046384; 397.467494; 405.041753 ];
out.err  = norm(f_ref-f)/norm(f_ref);
out.pass = out.err < opt.tol;

if( nargout==0 )
  clear fea out
end


% SYNTAX:
% [yAvgStd, yAvgStdErr] = hmrG_SubjAvgStd(ySubjAvg)
%
% UI NAME:
% Subj_Average_Standard_Deviation_and_Standard_Error
%
% DESCRIPTION:
% Calculate avearge HRF standard deviation and standard error of all subjects in a group.
%
% INPUTS:
% ySubjAvg:
%
% OUTPUTS:
% yAvgStdOut: the standard deviation across subjects.
% yAvgStdErrOut: the standard error across subjects.
%
% USAGE OPTIONS:
% Subj_Average_Standard_Deviation_on_Concentration_Data:  [dcAvgStd, dcAvgStdErr]  = hmrG_SubjAvgStd(dcAvgSubjs)
% Subj_Average_Standard_Deviation_on_Delta_OD_Data:       [dodAvgStd, dodAvgStd] = hmrG_SubjAvgStd(dodAvgSubjs)
%

function [yAvgStdOut, yAvgStdErrOut] = hmrG_SubjAvgStd(ySubjAvg)

yAvgStdOut = DataClass().empty();
yAvgStdErrOut = DataClass().empty();

if isempty(ySubjAvg)
    return;
end
for iBlk = 1:length(ySubjAvg{1})
    yAvgStdOut(iBlk) = DataClass(ySubjAvg{1});
    yAvgStdErrOut(iBlk) = DataClass(ySubjAvg{1});
    foo = ySubjAvg{1}(iBlk).GetDataTimeSeries();
    dts = zeros(size(foo,1), size(foo,2), length(ySubjAvg));
    for iRun = 1:length(ySubjAvg)
        dts(:,:,iRun) = ySubjAvg{iRun}(iBlk).GetDataTimeSeries();
    end
    yAvgStdOut(iBlk).SetDataTimeSeries(std(dts,0,3,'omitnan'));
    yAvgStdErrOut(iBlk).SetDataTimeSeries(std(dts,0,3,'omitnan')/sqrt(length(ySubjAvg)-1));
end


function cov = pc2covv(pc,R0,ncov)

%function cov = pc2covv(pc,R0,ncov)
%   Transforms partial correlations pc into a covariancefunction cov
%   ncov is the number of covariances
%   For a zero-mean process, the covariance function has been defined as
%   R(s)(.) = E{X[n+s]<X[n],.>},
%   or, in old-fashioned notation:
%   R(s) = E{X[n+s]X[n]'} where X[n] is a column vector.

%S. de Waele, March 2003.

if ~isstatv(pc), error('Partial correlations non-stationairy!'), end

s = kingsize(pc);
order = s(3)-1;
dim = s(1); I = eye(dim);

if nargin <  3, ncov = order; end

m = min(order,ncov);

par = zeros(dim,dim,m+1);
parb = zeros(dim,dim,m+1);
cov = zeros(dim,dim,ncov+1);

[rc,rcb,Pf,Pb] = pc2rcv(pc(:,:,1:m+1),R0);

cov(:,:,1) = R0;
par(:,:,1) = I;
parb(:,:,1)= I;
if m,
	cov(:,:,2) = -rc(:,:,2)*R0;
	par(:,:,2) = rc(:,:,2);
	parb(:,:,2)= rcb(:,:,2);
	par_o  = par;
	parb_o = parb;
end

for p = 2:m,

   par(:,:,2:p) = par_o(:,:,2:p) +flipdim(timesv(rc(:,:,p+1),parb_o(:,:,2:p)),3);
   par(:,:,p+1) = rc(:,:,p+1);

   parb(:,:,2:p)= parb_o(:,:,2:p)+flipdim(timesv(rcb(:,:,p+1) ,par_o(:,:,2:p)),3);
   parb(:,:,p+1)= rcb(:,:,p+1);

   cov(:,:,p+1) = -prodsumv(par(:,:,2:p+1),cov(:,:,p:-1:1));

   par_o  = par;
   parb_o = parb;
end %for p = 2:m,
if ncov > order,
	cov(:,:,order+2:end) = armafilterv(zeros(dim,dim,ncov-order),par,I,cov(:,:,2:order+1));
end


function x = nco_abscissas ( n )

%*****************************************************************************80
%
%% NCO_ABSCISSAS computes the Newton Cotes Open abscissas.
%
%  Discussion:
%
%    The interval is [ -1, 1 ].
%
%    The abscissas are the equally spaced points between -1 and 1,
%    not including the endpoints.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the rule.
%
%    Output, real X(N), the abscissas.
%
  for i = 1 : n
    x(i) = ( ( n - i + 1 ) * ( -1.0 )   ...
           + (     i     ) * ( +1.0 ) ) ...
           / ( n     + 1 );
  end

  return
end


function FbVisualize( FB, show )
% Used to visualize a series of 1D/2D/3D filters.
%
% For 1D and 2D filterabnks also shows the Fourier spectra of the filters.
%
% USAGE
%  FbVisualize( FB, [show] )
%
% INPUTS
%  FB      - filter bank to visualize (either 2D, 3D, or 4D array)
%  show    - [1] figure to use for display
%
% OUTPUTS
%
% EXAMPLE
%  FB=FbMake(1,1,0);  FbVisualize( FB, 1 );  %1D
%  load FbDoG.mat;    FbVisualize( FB, 2 );  %2D
%  FB=FbMake(3,1,0);  FbVisualize( FB, 3 );  %3D
%
% See also FBAPPLY2D, FILTERVISUALIZE
%
% Piotr's Image&Video Toolbox      Version 2.0
% Copyright 2012 Piotr Dollar.  [pdollar-at-caltech.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the Simplified BSD License [see external/bsd.txt]

if( nargin<2 || isempty(show) ); show=1; end
if( show<=0); return; end;

% get Fourier Spectra for 1D and 2D filterbanks
nd = ndims(FB)-1;
if( nd==1 || nd==2 )
  FBF=zeros(size(FB));
  if( nd==1 )
    for n=1:size(FB,1);  FBF(n,:)=abs(fftshift(fft(FB(n,:)))); end
  else
    for n=1:size(FB,3);  FBF(:,:,n)=abs(fftshift(fft2(FB(:,:,n)))); end
  end
end

% display
figure(show); clf;
if( nd==1 )
  r = (size(FB,2)-1)/2;
  subplot(1,3,1); plot( -r:r, FB );
  subplot(1,3,2); plot( (-r:r)/(2*r+1), FBF );
  subplot(1,3,3); stem( (-r:r)/(2*r+1), max(FBF,[],1) );

elseif( nd==2 )
  subplot(1,3,1); montage2(FB);  title('filter bank');
  subplot(1,3,2); montage2(FBF);
  title('filter bank fft');
  subplot(1,3,3); im(sum(FBF,3));  title('filter bank fft coverage');

elseif( nd==3 )
  n = size(FB,4); nn = ceil( sqrt(n) ); mm = ceil( n/nn );
  for i=1:n
    subplot(nn,mm,i);
    filterVisualize( FB(:,:,:,i), 0 );
  end
end


% Test: Mesh subdivision using the Loop scheme.
%
% Author: Jesus Mena

% Example: Box
vertices = [10 10 10; -10 10 10; 10 -10 10; -10 -10 10; 10 10 -10; -10 10 -10; 10 -10 -10; -10 -10 -10]';
faces = [1 2 3; 4 3 2; 1 3 5; 7 5 3; 1 5 2; 6 2 5; 8 6 7; 5 7 6; 8 7 4; 3 4 7; 8 4 6; 2 6 4]';

figure(1);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Tetrahedron
vertices = [10 10 10; -100 10 -10; -100 -10 10; 10 -10 -10]';
faces = [1 2 3; 1 3 4; 1 4 2; 4 3 2]';

figure(2);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Cylinder
vertices = [0 -5 0; 0 5 0; 10 -5 0; 9.65 -5 2.58; 8.66 -5 5; 7.07 -5 7.07; 5 -5 8.66; 2.58 -5 9.65; 0 -5 10; -2.58 -5 9.65; -5 -5 8.66; -7.07 -5 7.07; -8.66 -5 5; -9.65 -5 2.58; -10 -5 0; -9.65 -5 -2.58; -8.66 -5 -5; -7.07 -5 -7.07; -5 -5 -8.66; -2.58 -5 -9.65; -0 -5 -10; 2.58 -5 -9.65; 5 -5 -8.66; 7.07 -5 -7.07; 8.66 -5 -5; 9.65 -5 -2.58; 10 5 0 ; 9.65 5 2.58; 8.66 5 5; 7.07 5 7.07; 5 5 8.66; 2.58 5 9.65; 0 5 10; -2.58 5 9.65; -5 5 8.66; -7.07 5 7.07; -8.66 5 5; -9.65 5 2.58; -10 5 0; -9.65 5 -2.58; -8.66 5 -5; -7.07 5 -7.07; -5 5 -8.66; -2.58 5 -9.65; -0 5 -10; 2.58 5 -9.65; 5 5 -8.66; 7.07 5 -7.07; 8.66 5 -5; 9.65 5 -2.58]';
faces = [1 3 4; 1 4 5; 1 5 6; 1 6 7; 1 7 8; 1 8 9; 1 9 10; 1 10 11; 1 11 12; 1 12 13; 1 13 14; 1 14 15; 1 15 16; 1 16 17; 1 17 18; 1 18 19; 1 19 20; 1 20 21; 1 21 22; 1 22 23; 1 23 24; 1 24 25; 1 25 26; 1 26 3; 2 28 27; 2 29 28; 2 30 29; 2 31 30; 2 32 31; 2 33 32; 2 34 33; 2 35 34; 2 36 35; 2 37 36; 2 38 37; 2 39 38; 2 40 39; 2 41 40; 2 42 41; 2 43 42; 2 44 43; 2 45 44; 2 46 45; 2 47 46; 2 48 47; 2 49 48; 2 50 49; 2 27 50; 3 27 28; 3 28 4; 4 28 29; 4 29 5; 5 29 30; 5 30 6; 6 30 31; 6 31 7; 7 31 32; 7 32 8; 8 32 33; 8 33 9; 9 33 34; 9 34 10; 10 34 35; 10 35 11; 11 35 36; 11 36 12; 12 36 37; 12 37 13; 13 37 38; 13 38 14; 14 38 39; 14 39 15; 15 39 40; 15 40 16; 16 40 41; 16 41 17; 17 41 42; 17 42 18; 18 42 43; 18 43 19; 19 43 44; 19 44 20; 20 44 45; 20 45 21; 21 45 46; 21 46 22; 22 46 47; 22 47 23; 23 47 48; 23 48 24; 24 48 49; 24 49 25; 25 49 50; 25 50 26; 26 50 27; 26 27 3]';

figure(3);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end

% Example: Grid
vertices = [-4 -4 0; -2 -4 0; 0 -4 0; 2 -4 0; 4 -4 0; -4 -2 0; -2 -2 0; 0 -2 0; 2 -2 0; 4 -2 0; -4 0 0; -2 0 0; 0 0 0; 2 0 0; 4 0 0; -4 2 0; -2 2 0; 0 2 0; 2 2 0; 4 2 0; -4 4 0; -2 4 0; 0 4 0; 2 4 0; 4 4 0]';
faces = [7 2 1; 1 6 7; 8 3 2; 2 7 8; 9 4 3; 3 8 9; 10 5 4; 4 9 10; 12 7 6; 6 11 12; 13 8 7; 7 12 13; 14 9 8; 8 13 14; 15 10 9; 9 14 15; 17 12 11; 11 16 17; 18 13 12; 12 17 18; 19 14 13; 13 18 19; 20 15 14; 14 19 20; 22 17 16; 16 21 22; 23 18 17; 17 22 23; 24 19 18; 18 23 24; 25 20 19; 19 24 25]';

figure(4);
subplot(1,4,1);
plotMesh(vertices, faces);
for i=2:4
 subplot(1,4,i);
 [vertices, faces] = loopSubdivision(vertices, faces);
 plotMesh(vertices, faces);
end