function pass = test_definePoint(pref)

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

% Test a scalar-valued CHEBFUN object:
f = chebfun(@(x) x, [-1, 0, 1], pref);
% Use DEFINEPOINT:
f = definePoint(f, .5, 1);
pass(1) = all(f.domain == [-1, 0, .5, 1]) && feval(f, .5) == 1;
% Use SUBSASGN:
f(-.5) = 2;
pass(2) = all(f.domain == [-1, -.5, 0, .5, 1]) && feval(f, -.5) == 2;

% Test an array-valued CHEBFUN object:
f = chebfun(@(x) [x, x], [-1, 0, 1], pref);
% Use DEFINEPOINT:
f = definePoint(f, .5, [1, 2]);
pass(3) = all(f.domain == [-1, 0, .5, 1]) && all(feval(f, .5) == [1, 2]);
% Use SUBSASGN:
f(-.5) = [2, 3];
pass(4) = all(f.domain == [-1, -.5, 0, .5, 1]) && all(feval(f, -.5) == [2, 3]);

% Test an array-valued CHEBFUN object at a number of points:
f = chebfun(@(x) [x, x], [-1, 0, 1], pref);
% Use DEFINEPOINT:
f = definePoint(f, [-.25, .5], [1, 2 ; 3 4]);
pass(5) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 2 ; 0 0 ; 3 4 ; 1 1]));
% Use SUBSASGN:
f([-.25, .5]) = [1, 2 ; 3 4];
pass(6) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 2 ; 0 0 ; 3 4 ; 1 1]));

% Test an array-valued CHEBFUN object at a number of points (vector expansion):
f = chebfun(@(x) [x, x], [-1, 0, 1], pref);
% Use DEFINEPOINT:
f = definePoint(f, [-.25, .5], [1, 2]);
pass(7) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 2 ; 0 0 ; 1 2 ; 1 1]));
% Use SUBSASGN:
f([-.25, .5]) = [1, 2];
pass(8) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 2 ; 0 0 ; 1 2 ; 1 1]));

% Test an array-valued CHEBFUN object at a number of points (scalar expansion):
f = chebfun(@(x) [x, x], [-1, 0, 1], pref);
% Use DEFINEPOINT:
f = definePoint(f, [-.25, .5], 1);
pass(9) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 1 ; 0 0 ; 1 1 ; 1 1]));
% Use SUBSASGN:
f([-.25, .5]) = 1;
pass(10) = all(size(f.pointValues) == [5, 2]) && ...
    all(all(f.pointValues == [-1 -1 ; 1 1 ; 0 0 ; 1 1 ; 1 1]));

%% Test on singular function: piecewise smooth chebfun

% define the domain:
dom = [-2 -1 0 1];

op1 = @(x) sin(x);
op2 = @(x) 1./((1+x).^0.5);
op3 = @(x) x+1;
op = {op1, op2, op3};

f = chebfun(op, dom, 'exps', [0 0 -0.5 0 0 0]);
brkpts = zeros(1,2);
brkpts(1) = -0.7;
brkpts(2) = -0.5;
g = definePoint(f, brkpts(1), 1);
g(brkpts(2)) = 2;

% check values:
check = zeros(1,4);
check(1) = all(g.domain == unique([dom, brkpts]));
check(2) = feval(g, brkpts(1)) == 1;
check(3) = feval(g, brkpts(2)) == 2;
check(4) = all(g.pointValues == [f.pointValues(1:2); 1; 2; f.pointValues(3:4)]);

pass(11) = all( check );

%% Test for function defined on unbounded domain:

% Functions on [-inf inf]:

% Set the domain:
dom = [-Inf Inf];

% Blow-up function:
op = @(x) (1-exp(-x.^2));
f = chebfun(op, dom);
brkpts = zeros(1,2);
brkpts(1) = -7;
brkpts(2) = 2;
g = definePoint(f, brkpts(1), 3);
g(brkpts(2)) = 4;

% check values:
check = zeros(1,4);
check(1) = all(g.domain == unique([dom, brkpts]));
check(2) = feval(g, brkpts(1)) == 3;
check(3) = feval(g, brkpts(2)) == 4;
check(4) = all(g.pointValues == [f.pointValues(1); 3; 4; f.pointValues(end)]);

pass(12) = all( check );

%% Test assigning to an endpoint (#896)
f = chebfun(0, [-1, 1]);
f(1) = 1;
pass(13) = abs(feval(f, 1) - 1) < eps;

end


% function [Lbdi, Rbdi] = synsq_bd_loc(t, fs)
%
% For a given time series and set of frequency values, calculate the left
% and right boundaries for each frequency.  Beyond these boundaries,
% boundary effects affect the signal.  Output is in indices.
%   If length(t)==n, then length(Lbdi)==length(Rbdi)==n
%
% t is assumed to be sampled uniformly
%
%---------------------------------------------------------------------------------
%    Synchrosqueezing Toolbox
%    Authors: Eugene Brevdo (http://www.math.princeton.edu/~ebrevdo/)
%---------------------------------------------------------------------------------
function [Lbdi, Rbdi] = synsq_bd_loc(t, fs)
    if (fs(2)>fs(1))
        Ts = 1./fs;
    else
        Ts = fs;
    end

    dt = t(2)-t(1);
    Tsn = ceil(1.5 * Ts / dt);

    Lbdi = min(length(t), Tsn);
    Rbdi = max(1, length(t)-Tsn);
end


function imOut = warpUV(imIn, u, v, x, y, interpolationMethod, template)
%
% function imOut = vWarpUV(imIn, u, v, x, y, interpolationMethod, template)
%
% DESCRIPTION
%   This function warps an input image according to the displacement
%     fields for all pixels (u and v) by using the MATLAB function interp2.
%     The interpolation method, e.g., bilinear interpolation or
%     nearest-neighbor interpolation, can be specified. Since this
%     function is called often, e.g., many times during the
%     registration process, the function tries to use stored
%     (persistent) matrices that are needed as arguments for
%     interp2 instead of recreating the matrices.
%
% INPUT
%   - imIn = image that is to be warped
%   - u = pixel displacement field in x direction
%   - v = pixel displacement field in y direction
%   - x is optional; can be given to the function to improve speed
%   - y is optional; can be given to the function to improve speed
%   - interpolationMetho is optional; 'nearest' is the default
%     'nearest':  edges better because of NaNs outside
%     'linear':   smoother inside
%   - template (optional): NaN regions in this image will be NaN in the
%     warped image as well; this can be the original phWedgeIm
%
% OUTPUT / RESULTS
%   - imOut = warped image
%
% AUTHOR:
%   Volker Maximillian Koch
%   vk@volker-koch.de
%
% DATE:
%   January - June 2001
%
% COMMENTS:
%   This function tries to avoid the calculation of x and y with meshgrid
%   since that takes some time. Therefore, these variables are stored
%   persistent.
%
% TO-DO:
%
% Update History:
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
persistent xStored;
persistent yStored;
persistent sizeStored;
if ~exist('x','var'),  x=[]; end
if ~exist('y','var'),  y=[]; end
if (isempty(x) | isempty(y))
    if isempty(sizeStored)
        sizeStored = [0 0];
    end
    if sizeStored == size(imIn)
        x = xStored;
        y = yStored;
    else
        [x,y] = meshgrid(1:size(imIn,2),1:size(imIn,1));
    end
end
xStored = x;
yStored = y;
sizeStored = size(imIn);
if eval('isempty(interpolationMethod)' , '1')
    interpolationMethod = '*linear';
end
imOut = zeros(size(imIn));
% we could use Bernd's version of interp2 (updateTinC).
%imOut = updateTinC(imIn, x+u, y+v);
imOut = interp2(imIn, x+u, y+v, interpolationMethod);
if eval('~isempty(template)' , '0')
    imOut(isnan(template)) = NaN;
end
return


function i4_log_2_test ( )

%*****************************************************************************80
%
%% I4_LOG_2_TEST tests I4_LOG_2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 April 2009
%
%  Author:
%
%    John Burkardt
%
  test_num = 17;

  x_test = [ 0, 1, 2, 3, 9, 10, 11, 99, 101, -1, -2, ...
    -3, -9, 1000, 1023, 1024, 1025 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'I4_LOG_2_TEST\n' );
  fprintf ( 1, '  I4_LOG_2: whole part of log base 2.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '       X     I4_LOG_2\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
    x = x_test(test);
    fprintf ( 1, '  %6d  %12d\n', x, i4_log_2 ( x ) );
  end

  return
end


function [sos,P] = sospolymatrixvar(sos,ZSym,n,matrixstr)
% SOSMATRIXVAR --- Declare a polynomial matrix variable P in the sos program
% SOS of
%
% [SOSP,P] = sosmatrixvar(SOSP,ZSym,n,matrixstr)
%
% SOSP is the sum of squares program.
% P is the new polynomial matrix.
% n is the dimension of the matrix P: n(1) x n(2)
% ZSym is the vector of monomials contained in VAR. Decision
% variables corresponding to those monomials will be assigned
% automatically by SOSPOLYVAR.
% matrixstr is a char string with the option 'symmetric' when required

% This file is part of SOSTOOLS - Sum of Squares Toolbox ver 3.00.
%
% Copyright (C)2002, 2004, 2013  A. Papachristodoulou (1), J. Anderson (1),
%                                G. Valmorbida (1), S. Prajna (2),
%                                P. Seiler (3), P. A. Parrilo (4)
% (1) Department of Engineering Science, University of Oxford, Oxford, U.K.
% (2) Control and Dynamical Systems - California Institute of Technology,
%     Pasadena, CA 91125, USA.
% (3) Aerospace and Engineering Mechanics Department, University of
%     Minnesota, Minneapolis, MN 55455-0153, USA.
% (4) Laboratory for Information and Decision Systems, M.I.T.,
%     Massachusetts, MA 02139-4307
%
% Send bug reports and feedback to: sostools@cds.caltech.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.

% JA&GV - 6/13/2013

% Original Code
if nargin == 4
    if matrixstr=='symmetric'
        if n(1)==n(2)
            if isfield(sos,'symvartable')
                P = sym(zeros(n(1),n(2)));
            else
                % Code for multipoly: PJS 9/9/2013
                P = polynomial(zeros(n(1),n(2)));
            end
            for i = 1:n(1)
                for j = i:n(1)
                    [sos,var] = sospolyvar(sos,ZSym);
                    P(i,j) = var;
                    P(j,i) = var;
                    clear var;
                end
            end
        else
            disp(['''symmetric''' ' option used, matrix must be square.']);
            P = [];
            return
        end
    else
        disp(['Matrix structure ' matrixstr ' is not defined.' ]);
        P = [];
        return

    end
else
    if isfield(sos,'symvartable')
        P = sym(zeros(n(1),n(2)));
    else
        % Code for multipoly: PJS 9/9/2013
        P = polynomial(zeros(n(1),n(2)));
    end
    for i = 1:n(1)
        for j = 1:n(2)
            [sos,var] = sospolyvar(sos,ZSym);
            P(i,j) = var;
            clear var;
        end
    end

end


function [res,errorL2]=FBP(proj,geo,angles,varargin)
%TODO docs FBP
%
%
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% This file is part of the TIGRE Toolbox
%
% Copyright (c) 2015, University of Bath and
%                     CERN-European Organization for Nuclear Research
%                     All rights reserved.
%
% License:            Open Source under BSD.
%                     See the full license at
%                     https://github.com/CERN/TIGRE/blob/master/LICENSE
%                     and
%                     https://www.mathworks.com/matlabcentral/fileexchange/view_license?file_info_id=35548
%
% Contact:            tigre.toolbox@gmail.com
% Codes:              https://github.com/CERN/TIGRE/
% Coded by:           Kyungsang Kim, modified by Ander Biguri
%--------------------------------------------------------------------------

% Assertion exploiting lazy evaluation
if isfield(geo,'mode') && ~strcmpi(geo.mode,'parallel')
     assert(false,'Only use FBP for parallel beam CT')
end
geo=checkGeo(geo,angles);

[filter,parker]=parse_inputs(proj,geo,angles,varargin);
geo.filter=filter;

%Input is data,geosize,angles

if size(geo.offDetector,2)==1
    offset=repmat(geo.offDetector,[1 size(angles,2)]);
else
    offset=geo.offDetector;
end

%% Weight
%proj=data
proj=permute(proj,[2 1 3]);

%% filter
proj_filt = filtering(proj,geo,angles,parker); % Not sure if offsets are good in here
%RMFIELD Remove fields from a structure array.
geo=rmfield(geo,'filter');
%% backproject

res=Atb((proj_filt),geo,angles)*geo.DSO(1)/geo.DSD(1);

if nargout>1
     error=proj-Ax(res,geo,angles);
     errorL2=norm(error(:));
end

end

function [filter, parker]=parse_inputs(proj,geo,alpha,argin)
opts=     {'filter','parker'};
defaults=ones(length(opts),1);
% Check inputs
nVarargs = length(argin);
if mod(nVarargs,2)
    error('TIGRE:FBP:InvalidInput','Invalid number of inputs')
end

% check if option has been passed as input
for ii=1:2:nVarargs
    ind=find(ismember(opts,lower(argin{ii})));
    if ~isempty(ind)
        defaults(ind)=0;
    end
end

for ii=1:length(opts)
    opt=opts{ii};
    default=defaults(ii);
    % if one option isnot default, then extranc value from input
    if default==0
        ind=double.empty(0,1);jj=1;
        while isempty(ind)
            ind=find(isequal(opt,lower(argin{jj})));
            jj=jj+1;
        end
         if isempty(ind)
            error('CBCT:FDK:InvalidInput',['Optional parameter "' argin{jj} '" does not exist' ]);
        end
        val=argin{jj};
    end

    switch opt
        % % % % % % % Verbose
        case 'parker'
            if default
                parker=0;
            else
                parker=val;
            end

        case 'filter'
            if default
                filter='ram-lak';
            else
                if  ~ischar( val)
                    error('CBCT:FDK:InvalidInput','Invalid filter')
                end
                filter=val;
            end

        otherwise
            error('CBCT:FDK:InvalidInput',['Invalid input name:', num2str(opt),'\n No such option in FAK()']);
    end
end

end


function [ a, ipvt, rcond ] = zgeco ( a, lda, n )

%*****************************************************************************80
%
%% ZGECO factors a complex matrix and estimates its condition.
%
%  Discussion:
%
%    If RCOND is not needed, ZGEFA is slightly faster.
%
%    To solve A*X = B, follow ZGECO by ZGESL.
%
%    To compute inverse(A)*C, follow ZGECO by ZGESL.
%
%    To compute determinant(A), follow ZGECO by ZGEDI.
%
%    To compute inverse(A), follow ZGECO by ZGEDI.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 May 2007
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979,
%    ISBN13: 978-0-898711-72-1,
%    LC: QA214.L56.
%
%  Parameters:
%
%    Input, complexA(LDA,N), the matrix to be factored.
%
%    Input, integer LDA, the leading dimension of A.
%
%    Input, integer N, the order of the matrix.
%
%    Output, complex A(LDA,N), an upper triangular matrix and the multipliers
%    which were used to obtain it.  The factorization can be written A = L*U
%    where L is a product of permutation and unit lower triangular matrices
%    and U is upper triangular.
%
%    Output, integer IPVT(N), the pivot indices.
%
%    Output, real RCOND, an estimate of the reciprocal condition of A.
%    For the system A*X = B, relative perturbations in A and B of size
%    EPSILON may cause relative perturbations in X of size (EPSILON/RCOND).
%    If RCOND is so small that the logical expression
%      1.0 + RCOND == 1.0
%    is true, then A may be singular to working precision.  In particular,
%    RCOND is zero if exact singularity is detected or the estimate
%    underflows.
%

%
%  Compute the 1-norm of A.
%
  anorm = 0.0;
  for j = 1 : n
    anorm = max ( anorm, dzasum ( n, a(1:n,j), 1 ) );
  end
%
%  Factor.
%
  [ a, ipvt, info ] = zgefa ( a, lda, n );
%
%  RCOND = 1/(norm(A)*(estimate of norm(inverse(A)))).
%
%  Estimate = norm(Z)/norm(Y) where A*Z = Y and hermitian(A)*Y = E.
%
%  Hermitian(A) is the conjugate transpose of A.
%
%  The components of E are chosen to cause maximum local
%  growth in the elements of W where hermitian(U)*W = E.
%
%  The vectors are frequently rescaled to avoid overflow.
%
%  Solve hermitian(U)*W = E.
%
  ek = 1.0;
  z(1:n) = 0.0;

  for k = 1 : n

    if ( zabs1 ( z(k) ) ~= 0.0 )
      ek = zsign1 ( ek, -z(k) );
    end

    if ( zabs1 ( a(k,k) ) < zabs1 ( ek - z(k) ) )
      s = zabs1 ( a(k,k) ) / zabs1 ( ek - z(k) );
      z(1:n) = z(1:n) * s;
      ek = s * ek;
    end

    wk = ek - z(k);
    wkm = -ek - z(k);
    s = zabs1 ( wk );
    sm = zabs1 ( wkm );

    if ( zabs1 ( a(k,k) ) ~= 0.0 )
      wk = wk / conj ( a(k,k) );
      wkm = wkm / conj ( a(k,k) );
    else
      wk = 1.0;
      wkm =1.0;
    end

    for j = k+1 : n
      sm = sm + zabs1 ( z(j) + wkm * conj ( a(k,j) ) );
      z(j) = z(j) + wk * conj ( a(k,j) );
      s = s + zabs1 ( z(j) );
    end

    if ( s < sm )
      t = wkm - wk;
      wk = wkm;
      z(k+1:n) = z(k+1:n) + t * conj ( a(k,k+1:n) );
    end

    z(k) = wk;

  end

  s = 1.0 / dzasum ( n, z, 1 );
  z(1:n) = z(1:n) * s;
%
%  Solve hermitian(L) * Y = W.
%
  for k = n : -1 : 1

    if ( k < n )
      z(k) = z(k) + z(k+1:n) * conj ( a(k+1:n,k) );
    end

    if ( 1.0 < zabs1 ( z(k) ) )
      s = 1.0 / zabs1 ( z(k) );
      z(1:n) = z(1:n) * s;
    end

    l = ipvt(k);

    t    = z(l);
    z(l) = z(k);
    z(k) = t;

  end

  s = 1.0 / dzasum ( n, z, 1 );
  z(1:n) = z(1:n) * s;
  ynorm = 1.0;
%
%  Solve L * V = Y.
%
  for k = 1 : n

    l = ipvt(k);

    t    = z(l);
    z(l) = z(k);
    z(k) = t;

    if ( k < n )
      z(k+1:n) = z(k+1:n) + t * transpose ( a(k+1:n,k) );
    end

    if ( 1.0 < zabs1 ( z(k) ) )
      s = 1.0 / zabs1 ( z(k) );
      z(1:n) = z(1:n) * s;
      ynorm = s * ynorm;
    end

  end

  s = 1.0 / dzasum ( n, z, 1 );
  z(1:n) = z(1:n) * s;
  ynorm = s * ynorm;
%
%  Solve U * Z = V.
%
  for k = n : -1 : 1

    if ( zabs1 ( a(k,k) ) < zabs1 ( z(k) ) )
      s = zabs1 ( a(k,k) ) / zabs1 ( z(k) );
      z(1:n) = z(1:n) * s;
      ynorm = s * ynorm;
    end

    if ( zabs1 ( a(k,k) ) ~= 0.0 )
      z(k) = z(k) / a(k,k);
    else
      z(k) = 1.0;
    end

    t = -z(k);
    z(1:k-1) = z(1:k-1) + t * transpose ( a(1:k-1,k) );

  end
%
%  Make ZNORM = 1.
%
  s = 1.0 / dzasum ( n, z, 1 );
  z(1:n) = z(1:n) * s;
  ynorm = s * ynorm;

  if ( anorm ~= 0.0 )
    rcond = ynorm / anorm;
  else
    rcond = 0.0;
  end

  return
end


%  INTERNAL FUNCTION: creates a grid of unique permutations of derivatives,
%  with non-increasing elements from left to right
%
%  ::
%
%    R1=derivatives_grid(R0)
%
%  Args:
%
%     - **R0** [vector|matrix]: initial permutation of derivatives
%
%  Returns:
%     :
%
%     - **R1** [matrix]: permutation indexes for derivatives of next order
%
%  See also:
%      mygrid
%
%


function test_suite=test_montecarlo_cluster_stat_distribution
% probability uniformity tests for cosmo_montecarlo_cluster_stat
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #
    try % assignment of 'localfunctions' is necessary in Matlab >= 2016
        test_functions=localfunctions();
    catch % no problem; early Matlab versions can use initTestSuite fine
    end
    initTestSuite;

function test_mccs_uniformity_slow()
    show_progress=true;

    if show_progress
        cleaner=onCleanup(@()progress_helper('-clear'));
        progress_helper(sprintf('Slow test in %s ',...
                                    mfilename()));
    end

    % test for uniformity of p-values of monte_carlo_cluster_stat
    %
    % this test aims to verify that there is not an excessive number of
    % false positives under the null hypothesis. It does so by running
    % monte_carlo_cluster_stat several times on random data, storing the p
    % values for each iteration, and comparing those to a uniform
    % distribution.
    %
    % because running this test is slow, it can perform the same test
    % multiple times, each time increasing the number of iterations. This
    % is repeated until enough evidence is gathered that p values are
    % uniform or not.

    max_attempts=8;
    grow_niter=1.2;

    % benchmark values obtained by runnning
    % helper_mccs_get_correlation_with_uniform multiple times with
    % 'correct' monte carlo custer stat function.
    uniform_c_mu=.985;
    uniform_c_sd=.05;

    % the null hypothesis is that p values are uniformly distributed;
    % earlier versions of monte_carlo_cluster_stat would fail this test,
    % with a lower correlation value as a result. The correlation value
    % is converted to a z-score
    %
    pass_min_z=-1;
    fail_max_z=-5;

    min_pass_or_fail_count=2;
    count_pass=0;
    count_fail=0;

    ps_cell=cell(1,max_attempts);

    niter=20;
    for attempt=1:max_attempts
        ps_cell{attempt}=helper_mccs_get_pvalues(niter,show_progress);
        ps=sort(cat(1,ps_cell{:}));

        % compute correlation with expected p-values
        n_ps=numel(ps);
        ps_uniform=(.5:n_ps)'/n_ps;
        c=cosmo_corr(ps,ps_uniform);

        z=sqrt(niter)*(c-uniform_c_mu)/uniform_c_sd;

        if z>pass_min_z
            count_pass=count_pass+1;
            count_fail=0;

        elseif z<fail_max_z
            count_fail=count_fail+1;
            count_pass=0;
        else
            count_fail=0;
            count_pass=0;
        end

        if count_pass>=min_pass_or_fail_count
            finalize_test_helper(show_progress);

            % test passes
            return;

        elseif count_fail>=min_pass_or_fail_count
            % enough evidence that p values are non-uniform, fail
            finalize_test_helper(show_progress);

            error(['Found z=%d, indicating that probability values '...
                        'are probably not uniform'],z);
        end

        % not enough evidence for either uniform or non-uniform, redo the
        % test with more iterations
        niter=ceil(niter*grow_niter);
        progress_helper('#');

    end

    finalize_test_helper(show_progress);
    error('Maximum number of attempts reached');

function finalize_test_helper(show_progress)
    if show_progress
        fprintf('\n');
    end

function ps=helper_mccs_get_pvalues(niter,show_progress)
    % output: correlation between expected uniform distribution of p values
    % and those obtained from monte_carl_cluster_stat

    niter_tfce=25;
    nsubj=10;

    ps=zeros(niter,1);

    % dataset with single features
    ds=struct();
    ds.samples=randn(nsubj,1);
    ds.sa.targets=ones(nsubj,1);
    ds.sa.chunks=(1:nsubj)';
    ds.fa=struct();
    ds.a=struct();

    % trivial (singleton) neighborhood
    nh=struct();
    nh.neighbors={1};
    nh.fa=struct();
    nh.fa.sizes=1;
    nh.a=struct();
    nh.origin.fa=ds.fa;
    nh.origin.a=ds.a;

    for iter=1:niter
        opt=struct();
        opt.niter=niter_tfce;
        opt.progress=false;
        opt.h0_mean=0;
        opt.dh=.1;

        ds.samples=randn(nsubj,1);

        z=cosmo_montecarlo_cluster_stat(ds,nh,opt);

        ps(iter)=normcdf(z.samples);

        if show_progress
            progress_helper(':');
        end
    end

function progress_helper(what)
    % helper to show progress during the test, which then flushes at the
    % end
    persistent delete_count;

    if isempty(delete_count)
        delete_count=0;
    end

    if strcmp(what,'-clear')
        to_print=repmat(sprintf('\b'),1,delete_count);
        delete_count=0;
    else
        to_print=what;
        delete_count=delete_count+numel(what);
    end

    fprintf(to_print);


% QUATERNION CONJUGATE
function [qCon] = qConjugate(q)
% This function defines the conjugate of the given quaternion.
% Associated block:
% "Quaternion Conjugate"
qCon = zeros(4,1);
qCon(2) = -q(2);
qCon(3) = -q(3);
qCon(4) = -q(4);
end


function stroud_test22 ( )

%*****************************************************************************80
%
%% TEST22 tests OCTAHEDRON_UNIT_ND.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 April 2009
%
%  Author:
%
%    John Burkardt
%
  global FUNC_ND_INDEX;

  n_max = 3;

  num = function_2d_num ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST22\n' );
  fprintf ( 1, '  OCTAHEDRON_UNIT_ND approximates integrals in a unit\n' );
  fprintf ( 1, '    octahedron in N dimensions.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '      F(X)       N = 1         N = 2         N = 3\n' );
  fprintf ( 1, '\n' );

  for i = 1 : num

    FUNC_ND_INDEX = i;

    for n = 1 : n_max
      result(n) = octahedron_unit_nd ( 'function_nd', n );
    end

    fname = function_nd_name ( i );

    fprintf ( 1, '  %s', fname );
    for n = 1 : n_max
      fprintf ( 1, '  %12f', result(n) );
    end
    fprintf ( 1, '\n' );

  end

  return
end


function varargout = boundingbox(F,ops,x,fun_eval)
%BOUNDINGBOX Computes bounding box of a constraint
%
% If only one output is requested, only the symbolic model is returned
%  B = boundingbox(F)
%
% If three outputs are requested, numerical values are returned too
%  [B,L,U] = boundingbox(F)
%
% A second argument can be used to specificy solver settings
%  B = boundingbox(F,sdpsettings('solver','cplex'))
%
% A third argument can (should!) be used to obtain a bounding box in a
% particular set of variables, i.e. the bounding box of a projection.
% Unless you specify which variables you are computing the bounding box
% w.r.t, it will be very hard for you to understand which variables the
% values in L and U relate to
%  [B,L,U] = boundingbox(F,[],x)
% B will now be the box [L <= x <= U] (infinite bounds not included)

if nargin < 3 | isempty(x)
    x = recover(depends(F));
else
    x = x(:);
    if ~isa(x,'sdpvar')
        error('The third argument should be an SDPVAR obeject');
    end
end

if nargin < 2
    ops = sdpsettings('verbose',0);
end
if isempty(ops)
    ops = sdpsettings('verbose',0);
end
if ~isa(ops,'struct')
    error('The second argument should be an SDPSETTINGS struct (or empty)');
end

sol = solvesdp(F,[x;-x],ops);
n = length(x);
sols = {};
vals = {};
for i = 1:n
    xi = x(i);
    if isa(xi,'sdpvar')
        if sol.problem(i)==0
            L(i,1) = double(xi,i);
            if nargin > 3
              sols{end+1} = double(x,i);
              vals{end+1} = double(fun_eval,i);
            end
        else
            L(i,1) = -inf;
        end
        if sol.problem(n+i)==0
            U(i,1) = double(xi,n+i);
            if nargin > 3
              sols{end+1} = double(x,n+i);
              vals{end+1} = double(fun_eval,n+i);
            end
        else
            U(i,1) = inf;
        end
    else
        L(i,1) = xi;
        U(i,1) = xi;
    end
end

% Only add finite bounds
Lf = find(~isinf(L));
Uf = find(~isinf(U));
B = [];
if ~isempty(Lf)
    xLf = x(Lf);
    if isa(xLf,'sdpvar')
        B = [B, (xLf >= L(Lf)):'Finite lower bounds'];
    end
end
if ~isempty(Uf)
    xUf = x(Uf);
    if isa(xUf,'sdpvar')
        B = [B, (xUf <= U(Uf)):'Finite upper bounds'];
    end
end
varargout{1} = B;
varargout{2} = L;
varargout{3} = U;
varargout{4} = sols;
varargout{5} = vals;


function PsiDraw = samplePsi_DK(YData,YsData,B,H,V,G,CD,meanTS,kappa,dataValues,KFSmatrices)
% This function takes a draw from the conditional posterior distribution of
% Psi (local mean).
% B=Bdraw;
% H=Hdraw;
% V=Vdraw;
% G=Gdraw;
% CD=CDdraw;
% kappa=priorValues.kappa
%% Initialize
yData=YData;
zData=YsData;

[T,n] = size(yData);
Mz = size(zData,2); %number of survey forecasts
p=size(B,1)/n;     %lags
na=n*(p+1);        %number of variables in state space

%% Matrices of state space representation
Zmatrix=KFSmatrices.Zmatrix; %(matrix for measurement equation)
Tmatrix=KFSmatrices.Tmatrix; %(matrix for state equation)
Tmatrix(n+1:2*n,n+1:end) = B'; %put the VAR coefficients in
Rmatrix=KFSmatrices.R;        %scaling in front of errors for transition equation
Lmatrix=KFSmatrices.L;        %scaling in front of errors for measurement equation

%% Data vector and KF initialisation
ZYcol = [zData';yData']; %concatenate surveydata and var data

psiInit    = mean(ZYcol(Mz+1:end,1:p),2); %rowwhise mean
y_PsiStart = reshape(ZYcol(Mz+1:end,p:-1:1),n*p,1)-repmat(psiInit,p,1); %initial values in deviation from mean
aStart=[meanTS;  y_PsiStart]; %start values for transition equation (RHS) with mean followed by lags of yt in deviation from mean

Pstart=kappa*eye(na); %variance for the initial state

aplus = nan(na,T-p); %matrix storing all the period specific for transition equation
QQ = nan(na,na,T-p);
LL = nan(Mz+n,Mz+n,T-p);
yplus = nan(n+Mz,T-p);
aplus(:,1) = aStart+mvnrnd(zeros(na,1),Pstart,1)'; %initialiye RHS of transition equation equation
yplus(:,1) = Zmatrix*aplus(:,1)+[sqrt(G(p+1,:)').*randn(Mz,1);zeros(n,1)]; %initialize the RHS of measurement equation
QQ(:,:,1) = Rmatrix*blkdiag(diag(V(p+1,:)),H(:,:,p+1))*Rmatrix'; %initial VCV of transition equation
LL(:,:,1) = Lmatrix*diag(G(p+1,:))*Lmatrix';                     %initial VCV of measurement equation

%recursively simulate the matrices by drawing from multivariate normal
%using time period specific VCV where
%H is the VCV of the VAR residuals,
%V is the VCV of the state transition residuals and
%G is the VCV of the measurement equation for the survey data

%mean correction simulation smoother
for t = 2:T-p
    %simulate the aplus matrix (constant in state transition equation) by drawing from the period specific distribution of the transition equation and VAR residuals
    aplus(:,t) =  Tmatrix*aplus(:,t-1)+ [sqrt(V(t+p,:)').*randn(n,1);  mvnrnd(zeros(n,1),H(:,:,t+p),1)';zeros(na-2*n,1)];
    %simulate the yplus matrix (containing survey data and var data) by drawing from the period specific
    %distribution of the residuals from the measurement equation
    yplus(:,t) = Zmatrix*aplus(:,t)+[sqrt(G(t+p,:)').*randn(Mz,1);zeros(n,1)];
    %period specific VCV of transition equation
    QQ(:,:,t) = Rmatrix*blkdiag(diag(V(t+p,:)),H(:,:,t+p))*Rmatrix';
   %period specific VCV of measurement equation
    LL(:,:,t) = Lmatrix*diag(G(t+p,:))*Lmatrix';
end

ystar = ZYcol(:,p+1:T)-yplus; %
ahatstar = bear.runKF_DK(ystar, Tmatrix, Zmatrix, QQ, LL, zeros(na,1), Pstart);
atilda = ahatstar+aplus;
PsiDraw = [nan(p,n);atilda(1:n,:)'];

end


function [HF,psi,x,y] = feed_dist(F,z,TF,PF)

parameters_dist
c = length(z); % c includes all species
options = optimset('Display','iter','Diagnostics','on','Algorithm','interior-point');

% Bubble point calculation
xB = z'; % Bubble point requirement (together with PF)
yB = xB; % Initial guess
TB = TF; % Initial guess
x0 = [yB; TB];
r  = fmincon('1',x0,[],[],[],[],[],[],@gB,options,xB,PF,c);
yB = r(1:c);
TB = r(end);

% Dew point calculation
yD = z'; % Dew point requirement (together with PF)
xD = yD; % Initial guess
TD = TF; % Initial guess
x0 = [xD; TD];
r  = fmincon('1',x0,[],[],[],[],[],[],@gD,options,yD,PF,c);
xD = r(1:c);
TD = r(end);

if TF <= TB
    psi = 0;
    x   = xB;
    y   = yB;
    [~,~,~,~,~,HF,~,~] = prsrk(x,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'L',Thermo);
elseif TF >= TD
    psi = 1;
    x   = xD;
    y   = yD;
    [~,~,~,~,~,HF,~,~] = prsrk(y,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'V',Thermo);
else
    % Two-phase calculation
    x  = z';    % Initial guess
    y  = x;     % Initial guess
    V  = 0.5*F; % Initial guess
    L  = V;     % Initial guess
    x0 = [x; y; V; L]; d = [F; TF; PF; z'];
    r = fmincon('1',x0,[],[],[],[],[],[],@gF,options,d,c);
    x = r(1:c); y = r(c+1:2*c);
    [~,~,~,~,~,HL,~,~] = prsrk(x,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'L',Thermo);
    [~,~,~,~,~,HV,~,~] = prsrk(y,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'V',Thermo);
    V = r(end-1); L = r(end);
    HF = 1/F*(HV*V + HL*L); psi = r(end-1)/F;
end

function [c,ceq] = gB(x0,x,PF,c)

parameters_dist
y = x0(1:c);
T = x0(end);

[~,~,phiL,~,~,~,~,~] = prsrk(x,PF*1e5,T+273.15,pc,Tc,w,k,cpig,DHf,DGf,'L',Thermo);
[~,~,phiV,~,~,~,~,~] = prsrk(y,PF*1e5,T+273.15,pc,Tc,w,k,cpig,DHf,DGf,'V',Thermo);
K = phiL./phiV;

ceq = [y - K.*x; sum(y) - 1];
c   = [];

function [c,ceq] = gD(x0,y,PF,c)

parameters_dist
x = x0(1:c);
T = x0(end);

[~,~,phiL,~,~,~,~,~] = prsrk(x,PF*1e5,T+273.15,pc,Tc,w,k,cpig,DHf,DGf,'L',Thermo);
[~,~,phiV,~,~,~,~,~] = prsrk(y,PF*1e5,T+273.15,pc,Tc,w,k,cpig,DHf,DGf,'V',Thermo);
K = phiL./phiV;

ceq = [y - K.*x; sum(x) - 1];
c   = [];

function [c,ceq] = gF(x0,d,c)

parameters_dist
x = x0(1:c);
y = x0(c+1:2*c);
V = x0(end-1);
L = x0(end);

F  = d(1);
TF = d(2);
PF = d(3);
z  = d(4:end);

[~,~,phiL,~,~,~,~,~] = prsrk(x,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'L',Thermo);
[~,~,phiV,~,~,~,~,~] = prsrk(y,PF*1e5,TF+273.15,pc,Tc,w,k,cpig,DHf,DGf,'V',Thermo);
K = phiL./phiV;

ceq = [y - K.*x; F*z - V*y - L*x; sum(x) - 1; sum(y) - 1];
c   = [];


function c = ttv(a,v,dims)
%TTV Tensor times vector for ktensor.
%
%   Y = TTV(X,A,N) computes the product of Kruskal tensor X with a
%   (column) vector A.  The integer N specifies the dimension in X
%   along which A is multiplied.  If size(A) = [I,1], then X must have
%   size(X,N) = I.  Note that ndims(Y) = ndims(X) - 1 because the N-th
%   dimension is removed.
%
%   Y = TTV(X,{A1,A2,...}) computes the product of tensor X with a
%   sequence of vectors in the cell array.  The products are computed
%   sequentially along all dimensions (or modes) of X. The cell array
%   contains ndims(X) vectors.
%
%   Y = TTV(X,{A1,A2,...},DIMS) computes the sequence tensor-vector
%   products along the dimensions specified by DIMS.
%
%   See also TENSOR/TTV, KTENSOR, KTENSOR/TTM.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

%%%%%%%%%%%%%%%%%%%%%%
%%% ERROR CHECKING %%%
%%%%%%%%%%%%%%%%%%%%%%

% Check the number of arguments
if (nargin < 2)
    error('TTV requires at least two arguments.');
end

% Check for 3rd argument
if ~exist('dims','var')
    dims = [];
end

% Check that 2nd argument is cell array. If not, recall with v as a
% cell array with one element.
if ~iscell(v)
    c = ttv(a,{v},dims);
    return;
end

% Get sorted dims and index for multiplicands
[dims,vidx] = tt_dimscheck(dims,ndims(a),numel(v));

% Check that each multiplicand is the right size.
for i = 1:numel(dims)
    if ~isequal(size(v{vidx(i)}),[size(a,dims(i)) 1])
        error('Multiplicand is wrong size');
    end
end

% Figure out which dimensions will be left when we're done
remdims = setdiff(1:ndims(a),dims);

% Collapse dimensions that are being multiplied out
newlambda = a.lambda;
for i = 1:numel(dims)
    newlambda = newlambda .* ( a.u{dims(i)}' * v{vidx(i)} );
end

% Create final result
if isempty(remdims)
    c = sum(newlambda);
else
    c = ktensor(newlambda,a.u{remdims});
end


% StackExchange Signal Processing Q52760
% https://dsp.stackexchange.com/questions/52760
% Convolution Strategy / Method for the Fastest 1D Convolution
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     27/04/2020
%   *   First release.

%% General Parameters

subStreamNumberDefault = 79;

run('InitScript.m');

figureIdx           = 0;
figureCounterSpec   = '%04d';

generateFigures = ON;

CONVOLUTION_METHOD_DFT          = 2;
CONVOLUTION_METHOD_OVERLAP_SAVE = 3;

CONVOLUTION_SHAPE_FULL         = 1;
CONVOLUTION_SHAPE_SAME         = 2;
CONVOLUTION_SHAPE_VALID        = 3;

vConvMethod = [CONVOLUTION_METHOD_DFT, CONVOLUTION_METHOD_OVERLAP_SAVE];
vConvShape  = [CONVOLUTION_SHAPE_FULL, CONVOLUTION_SHAPE_SAME, CONVOLUTION_SHAPE_VALID];

%% Simulation Parameters

vNumSamplesSignal = 2 * (10 .^ [2:0.5:6]);
vNumSamplesKernel = 10 .^ [1:0.5:6];
convShape   = CONVOLUTION_SHAPE_SAME;

%% Generate / Load Data

numSamplesSteps = length(vNumSamples);
numMethods      = length(vConvMethod);

vS = randn(vNumSamples(numSamplesSteps), 1);
vK = randn(vNumSamples(numSamplesSteps), 1);

%% Run Time Analysis

switch(convShape)
    case(CONVOLUTION_SHAPE_FULL)
        convString = 'full';
    case(CONVOLUTION_SHAPE_SAME)
        convString = 'same';
    case(CONVOLUTION_SHAPE_VALID)
        convString = 'valid';
end

mRunTime = zeros(numSamplesSteps, numSamplesSteps, numMethods);

for jj = 1:numSamplesSteps
    % Kernel Length
    numSamplesKernel = vNumSamples(jj);
    vKK = vK(1:numSamplesKernel);
    for ii = jj:numSamplesSteps
        % Signal Length
        numSamplesSignal = vNumSamples(ii);
        vSS = vS(1:numSamplesSignal);
        for kk = 1:numMethods
            switch(vConvMethod(kk))
                case(CONVOLUTION_METHOD_DIRECT)
                    hF = @() conv2(vSS, vKK, convString);
                case(CONVOLUTION_METHOD_OVERLAP_SAVE)
                    hF = @() ConvolutionOverlapSave(vSS, vKK, convShape);
                case(CONVOLUTION_METHOD_DFT)
                    hF = @() ConvolutionDft(vSS, vKK, convShape);
            end

            mRunTime(ii, jj, kk) = timeit(hF);

        end
    end
end

[~, mBestMethod] = min(mRunTime, [], 3);
for jj = 1:numSamplesSteps
    for ii = 1:numSamplesSteps
        if(jj > ii)
            mBestMethod(ii, jj) = 0;
        end
    end
end

%% Display Results

figureIdx = figureIdx + 1;

hFigure     = figure('Position', figPosLarge); %<! [x, y, width, height]
hAxes       = axes(); %<! [x, y, width, height]
hImageObj   = imagesc(vNumSamples, vNumSamples, mBestMethod);
set(hAxes, 'DataAspectRatio', [1, 1, 1]);
set(get(hAxes, 'Title'), 'String', {['Linear Convolution Run Time Comparison']}, ...
    'FontSize', fontSizeTitle);
set(get(hAxes, 'XLabel'), 'String', {['Kernel Length']}, ...
    'FontSize', fontSizeTitle);
set(get(hAxes, 'YLabel'), 'String', {['Signal Length']}, ...
    'FontSize', fontSizeTitle);
set(hAxes, 'LooseInset', [0.05, 0.05, 0.05, 0.05]);

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

%% Restore Defaults

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


function partition_problem_test02 ( n, w )

%*****************************************************************************80
%
%% PARTITION_PROBLEM_TEST02 tests PARTITION_COUNT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 May 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of weights.
%
%    Input, integer W(N), a set of weights.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'PARTITION_PROBLEM_TEST02:\n' );
  fprintf ( 1, '  PARTITION_COUNT counts the number of exact solutions\n' );
  fprintf ( 1, '  of the partition problem.\n' );

  count = partition_count ( n, w );

  fprintf ( 1, '\n' );
  fprintf ( 1, '     I        W\n' );
  fprintf ( 1, '\n' );
  for i = 1 : n
    fprintf ( 1, '  %4d  %8d\n', i, w(i) );
  end
  fprintf ( 1, '\n' );
  fprintf ( 1, 'Number of solutions = %d\n', count );

  return
end


function seq = prtUtilTopographicalSort(adj)
% [seq] = toposort(adj)  A Topological ordering of nodes in a directed graph
% INPUT:  adj  -  adjacency matrix
% OUTPUT: seq  -  a topological ordered sequence of nodes
%                 or an empty matrix if graph contains cycles
%
% Taken from Bayesian Network Toolbox by Minka

N = size(adj);
indeg = sum(adj,1);
outdeg = sum(adj,2);
seq = [];
for i = 1:N,
    idx = find(indeg==0);    % Find nodes with indegree 0
    if isempty(idx),   % If can't find than graph contains a cycle
        seq = [];
        break;
    end;
    [dummy, idx2] = max(outdeg(idx)); % Remove the node with the max number of connections
    indx = idx(idx2);
    seq = [seq, indx];
    indeg(indx) = -1;
    idx = find(adj(indx,:));
    indeg(idx) = indeg(idx)-1;
end


function kts = ftps2kts(ftps)
%FTPS2KTS Convert speed from feet per second to knots
%
%  kts = FTPS2KTS(ftps) converts speeds from feet per second to knots.
%
%  See also FTPS2KMPH, FTPS2MPH, FTPS2MPS, KTS2FTPS.

% Jonathan Sullivan
% Original: May 2011
% jonathan.sullivan@ll.mit.edu

kts = ftps*1.687810;


function [ x, w ] = rule01 ( n )

%*****************************************************************************80
%
%% RULE01 returns the rule of degree 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 July 2014
%
%  Author:
%
%    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
%    This MATLAB version by John Burkardt.
%
%  Reference:
%
%    Hong Xiao, Zydrunas Gimbutas,
%    A numerical algorithm for the construction of efficient quadrature
%    rules in two and higher dimensions,
%    Computers and Mathematics with Applications,
%    Volume 59, 2010, pages 663-676.
%
%  Parameters:
%
%    Input, integer N, the number of nodes.
%
%    Output, real X(2,N), the coordinates of the nodes.
%
%    Output, real W(N), the weights.
%
  xs = [ ...
       0.00000000000000000E+00 ];
  ys = [ ...
       0.00000000000000000E+00 ];
  ws = [ ...
       0.28284271247461904E+01 ];

  x(1,1:n) = xs(1:n);
  x(2,1:n) = ys(1:n);
  w(1:n) = ws(1:n);

  return
end


function [kN] = dyn2kN(dyn)
% Convert force from dyne to kilonewtons.
% Chad A. Greene 2012
kN = dyn*1e-8;
%
% C'mon, help me with this conversion--I'm dyne over here!


function [x,state] = struct_cell2mat(z,task)
%STRUCT_CELL2MAT Convert the contents of a cell array into a matrix.
%   [x,state] = struct_cell2mat(z) generates the matrix x as the function
%   cell2mat applied to the cell array z. The structure state stores
%   information which is reused in computing the right and left
%   Jacobian-vector products.
%
%   struct_cell2mat(z,task) computes the right or left Jacobian-vector
%   product of this transformation, depending on the structure task. Use
%   the structure state and add the field 'r' of the same shape as z or the
%   field 'l' of the same shape as x to obtain the structure task for
%   computing the right and left Jacobian-vector products
%
%      (dF(:)/dz(:).')*task.r(:) and
%      (dF(:)/dz(:).')'*task.l(:) + conj((dF(:)/dconj(z(:)).')'*task.l(:)),
%
%   respectively. Here, F(z) represents this transormation, (:) signifies
%   vectorization and the derivative w.r.t. z (conj(z)) is a partial
%   derivative which treats conj(z) (z) as constant. The output has the
%   same shape as x or z for the right and left Jacobian-vector products,
%   respectively.

%   Authors: Laurent Sorber (Laurent.Sorber@cs.kuleuven.be)
%            Marc Van Barel (Marc.VanBarel@cs.kuleuven.be)
%            Lieven De Lathauwer (Lieven.DeLathauwer@kuleuven-kulak.be)
%
%   References:
%   [1] L. Sorber, M. Van Barel, L. De Lathauwer, "Structured data fusion,"
%       ESAT-SISTA Internal Report 13-177, KU Leuven, 2013.

if nargin < 2, task = []; end

if isempty(task) || (isempty(task.l) && isempty(task.r))
    tmp = cellfun(@size,z,'UniformOutput',false);
    N = max(cellfun(@length,tmp));
    state.dim = cell(1,N);
    for n = 1:N
        s = size(tmp,n);
        idx = mat2cell([ones(s,n-1) (1:s)' ones(s,N-n)],s,ones(1,N));
        idx = sub2ind(size(tmp),idx{:});
        state.dim{n} = cellfun(@(s)s(n),tmp(idx));
    end
    x = cell2mat(z);
elseif ~isempty(task.r)
    x = cell2mat(task.r);
    state = [];
elseif ~isempty(task.l)
    x = mat2cell(task.l,task.dim{:});
    state = [];
end

end


function COV = UnTangent_space(T,C)
NTrial = size(T,2);
N_elec = (sqrt(1+8*size(T,1))-1)/2;
COV = zeros(N_elec,N_elec,NTrial);

if nargin<2
    C = riemann_mean(COV);
end

index = reshape(triu(ones(N_elec)),N_elec*N_elec,1)==0;

Out = zeros(N_elec*N_elec,NTrial);

Out(not(index),:) = T;
P = C^0.5;
for i=1:NTrial
  tmp = reshape(Out(:,i),N_elec,N_elec,[]);
  tmp =  diag(diag(tmp))+triu(tmp,1)/sqrt(2) + triu(tmp,1)'/sqrt(2);
  tmp = P*tmp*P;
  COV(:,:,i) = RiemannExpMap(C,tmp);
end


function dataout=modeDR_AEC_BSS(nummics, numrefs, datain)
%
% Perform dr, aec, and bss.
% nummics:              no. of mic channels
% numrefs:              no. of reference channels
% datain:               input data
% dataout:              output data
%

%% perform stft
addpath('stft2');
% fft size
fftsize=512;
stftshift=fftsize/2;

M=nummics;
R=numrefs;
N=M;

Xtf=cell(M+R, 1);
for m=1:M+R
    Xtf{m}=stft(datain(:, m), stftshift, fftsize, false);
end
[K, T]=size(Xtf{1});

Ytf=cell(M, 1);
for m=1:M
    Ytf{m}=zeros(K, T);
end

%% params
% dr filter length
DR_FLEN=5;
% forgetting factor for dr and aec
DRAEC_FORGET=0.999;
% forgetting factor for bss
BF_FORGET=0.999;
% the shape parameter of the source prior
GAMMA=0.2;
%
% used to keep stable
%
VAR_BIAS=0.01;
STABLE_EPS=1e-3;
DRAEC_DIAGLOAD=1e-6;
BF_DIAGLOAD=1e-6;

%% space for dr
% current mic data backup
Miccurrent=zeros(K, M);
% delayed mic data
drfsize=M*DR_FLEN;
Micdelay=zeros(K, drfsize);

% mic and delay correlation
Cmd=cell(K, 1);
for k=1:K
    Cmd{k}=zeros(M, drfsize);
end

% delay auto correlation
Cdd=cell(K, 1);
for k=1:K
    Cdd{k}=zeros(drfsize, drfsize);
end

% reverb path
Reverbpath=cell(K, 1);
for k=1:K
    Reverbpath{k}=zeros(M, drfsize);
end

%% space for aec
% mic-reference correlation
Cmr=cell(K, 1);
for k=1:K
    Cmr{k}=zeros(M, R);
end

% reference auto correlation
Crr=cell(K, 1);
for k=1:K
    Crr{k}=zeros(R, R);
end

% echo path
Echopath=cell(K, 1);
for k=1:K
    Echopath{k}=zeros(M, R);
end

%% space for bss
% the weighted correlation matrices
C1=cell(K, 1);
C2=cell(K, 1);
for k=1:K
    C1{k}=STABLE_EPS*eye(M, M);
    C2{k}=STABLE_EPS*eye(M, M);
end

% demixing matrices
Demix=cell(K, 1);
for k=1:K
    Demix{k}=eye(N, M);
end

%% perform iteration
for tau=1:T
    %% perform dr
    % direct and early reverberation
    Early=zeros(K, M);

    %
    % shift in new data
    %
    % shift old mic data back
    Micdelay=circshift(Micdelay, M, 2);
    % shift in delayed mic data
    Micdelay(:, 1:M)=Miccurrent;

    % mic data backup
    for m=1:M
        Miccurrent(:, m)=Xtf{m}(:, tau);
    end

    for k=1:K
        % calculate late reverberation
        ref=Micdelay(k, :).';
        late=Reverbpath{k}*ref;

        % direct and early reverberation
        mic=Miccurrent(k, :).';
        early=mic-late;
        % output data
        Early(k, :)=early.';

        %
        % calculate nonlinearity
        %
        xsq=abs(mic).^2;
        ysq=abs(early).^2;

        phi=0;
        for m=1:M
            if ysq(m)<=xsq(m)
                phi=phi+ysq(m);
            else
                phi=phi+xsq(m);
            end
        end

        phi=(1-DRAEC_FORGET)*(phi+VAR_BIAS)^((GAMMA-2)/2);

        % update mic ref correlation
        Cmd{k}=DRAEC_FORGET*Cmd{k}+phi*(mic*ref');

        % update ref auto-correlation
        Cdd{k}=DRAEC_FORGET*Cdd{k}+phi*(ref*ref');

        % update reverb path
        Reverbpath{k}=Cmd{k}/(Cdd{k}+DRAEC_DIAGLOAD*eye(drfsize, drfsize));
    end

    %% perform aec
    % nearend data
    Nearend=zeros(K, M);

    for k=1:K
        % reference data
        ref=zeros(R, 1);
        for r=1:R
            ref(r)=Xtf{M+r}(k, tau);
        end

        % echo
        echo=Echopath{k}*ref;

        % nearend
        mic=Early(k, :).';
        nearend=mic-echo;
        % output data
        Nearend(k, :)=nearend.';

        %
        % calculate nonlinearity
        %
        xsq=abs(mic).^2;
        ysq=abs(nearend).^2;

        phi=0;
        for m=1:M
            if ysq(m)<=xsq(m)
                phi=phi+ysq(m);
            else
                phi=phi+xsq(m);
            end
        end

        phi=(1-DRAEC_FORGET)*(phi+VAR_BIAS)^((GAMMA-2)/2);

        % update mic ref correlation
        Cmr{k}=DRAEC_FORGET*Cmr{k}+phi*(mic*ref');

        % update ref auto-correlation
        Crr{k}=DRAEC_FORGET*Crr{k}+phi*(ref*ref');

        % update echo path
        Echopath{k}=Cmr{k}/(Crr{k}+DRAEC_DIAGLOAD*eye(R, R));
    end

    %% perform bss
    Bssout=zeros(K, M);

    %
    % calculate nonlinearity
    %
    phi1=0;
    phi2=0;

    for k=1:K
        x=Nearend(k, :).';
        y=Demix{k}*x;
        % output data
        Bssout(k, :)=y.';

        phi1=phi1+abs(y(1))^2;
        phi2=phi2+abs(y(2))^2;
    end

    phi1=(1-BF_FORGET)*(phi1+VAR_BIAS)^((GAMMA-2)/2);
    phi2=(1-BF_FORGET)*(phi2+VAR_BIAS)^((GAMMA-2)/2);

    % update the demixing matrices
    for k=1:K
        %
        % accumulate the weighted correlation
        %
        x=Nearend(k, :).';
        C1{k}=BF_FORGET*C1{k}+phi1*(x*x');
        C2{k}=BF_FORGET*C2{k}+phi2*(x*x');

        % solve gev problem
        D=heig2(BF_DIAGLOAD, C2{k}, C1{k});
        Demix{k}=D;
    end

    for m=1:M
        Ytf{m}(:, tau)=Bssout(:, m);
    end
end

%% perform istft and output signal
dataout=zeros(dataLength(T, stftshift, fftsize ), N);
for n=1:N
    dataout(:, n)=istft(Ytf{n}, stftshift, false);
end

end


% Fixed budget quantized kernel least-mean-square algorithm
%
% S. Zhao, B. Chen, P. Zhu, J. C. Principe, "Fixed budget quantized kernel
% least-mean-square algorithm", Signal Processing, Volume 93, Issue 9,
% September 2013, Pages 2759-2770,
% http://dx.doi.org/10.1016/j.sigpro.2013.02.012.
%
% Remark: significance calculation only implemented for Gaussian kernel.
%
% This file is part of the Kernel Adaptive Filtering Toolbox for Matlab.
% https://github.com/steven2358/kafbox/

classdef qklms_fb < kernel_adaptive_filter

    properties (GetAccess = 'public', SetAccess = 'private')
        eta = .9; % learning rate
        epsu = .1; % quantization threshold
        beta = .95; % forgetting factor for influence
        M = 500; % dictionary size (K in publication)
        kerneltype = 'gauss'; % kernel type
        kernelpar = 1; % kernel parameter
    end

    properties (GetAccess = 'public', SetAccess = 'private')
        dict = []; % codebook
        alpha = []; % expansion coefficients
        E = []; % significance vector (~ importance)
        lambda = []; % influence vector (~ how many samples are quantized
        % to each centre)
    end

    methods
        function kaf = qklms_fb(parameters) % constructor
            if (nargin > 0) % copy valid parameters
                for fn = fieldnames(parameters)'
                    if ismember(fn,fieldnames(kaf))
                        kaf.(fn{1}) = parameters.(fn{1});
                    end
                end
            end
        end

        function y_est = evaluate(kaf,x) % evaluate the algorithm
            if size(kaf.dict,1)>0
                k = kernel(kaf.dict,x,kaf.kerneltype,kaf.kernelpar);
                y_est = k'*kaf.alpha;
            else
                y_est = zeros(size(x,1),1);
            end
        end

        function train(kaf,x,y) % train the algorithm
            y_est = kaf.evaluate(x);
            err = y - y_est;

            m = size(kaf.dict,1);
            if m==0
                d2 = kaf.epsu^2 + 1; % force dictionary growth
            else
                [d2,j] = min(sum((kaf.dict - repmat(x,m,1)).^2,2));
            end

            c1 = pi*kaf.kernelpar^2/2; % pre-calculate

            if d2 <= kaf.epsu^2 % new basis under quantization threshold
                kaf.alpha(j) = kaf.alpha(j) + kaf.eta*err;

                % update significance for quantizing y to j-th centre (16)
                if m>1
                    inds = 1:m;
                    inds(j) = [];
                    kaf.E(inds) = kaf.beta*kaf.E(inds) + c1*abs(kaf.alpha(inds)).* ...
                        kernel(kaf.dict(inds,:),kaf.dict(j,:),kaf.kerneltype,kaf.kernelpar);
                end
                kaf.E(j) = abs(1 + kaf.eta*err/kaf.alpha(j)) * ...
                    kaf.beta*kaf.E(j) + ...
                    abs(kaf.alpha(j) + kaf.eta*err) * ...
                    c1*kernel(kaf.dict(j,:),kaf.dict(j,:),kaf.kerneltype,kaf.kernelpar);

                % update influence
                kaf.lambda = kaf.beta*kaf.lambda;
                kaf.lambda(j) = kaf.lambda(j) + 1;

            else % new basis not under quantization threshold
                if m < kaf.M % still room for extra centres
                    kaf.dict = [kaf.dict; x]; % add to codebook
                    kaf.alpha = [kaf.alpha; kaf.eta*err];

                    % update significance for addition of m+1-th centre (15)
                    kaf.E(m+1,1) = 0;
                    kaf.E = kaf.beta*kaf.E + abs(kaf.alpha(m+1)) * ...
                        kernel(kaf.dict,kaf.dict(m+1,:),kaf.kerneltype,kaf.kernelpar);

                    % update influence
                    kaf.lambda = kaf.beta*kaf.lambda;
                    % initial influence
                    kaf.lambda(m+1) = 1;

                else % no room for extra centres
                    [~,L] = min(kaf.E); % centre with lowest significance

                    % update significance for removing L-th centre (17)
                    kaf.E = kaf.E - kaf.lambda(L) * c1*abs(kaf.alpha) .* ...
                        kernel(kaf.dict,kaf.dict(L,:),kaf.kerneltype,kaf.kernelpar);

                    % prune
                    kaf.dict(L,:) = [];
                    kaf.alpha(L) = [];
                    kaf.E(L) = [];
                    kaf.lambda(L) = [];

                    % re-calculate error
                    y_est = kaf.evaluate(x);
                    err = y - y_est;

                    % grow
                    kaf.dict = [kaf.dict; x];
                    kaf.alpha = [kaf.alpha; kaf.eta*err];

                    % update significance for addition of m-th centre (15)
                    kaf.E(m,1) = 0;
                    kaf.E = kaf.beta*kaf.E + abs(kaf.alpha(m)) * ...
                        kernel(kaf.dict,kaf.dict(m,:),kaf.kerneltype,kaf.kernelpar);

                    % update influence
                    kaf.lambda = kaf.beta*kaf.lambda;
                    % initial influence
                    kaf.lambda(m) = 1;
                end
            end
        end
    end
end


Afun2=@(x) (x+1)*(x<1)+(1+1/x)*(x>=1);
fplot(Afun2,[-3,3])


% REJKURT  - calculation of kutosis of a 1D, 2D or 3D array and
%              rejection of outliers values of the input data array
%              using the discrete kutosis of the values in that dimension.
%
% Usage:
%   >>  [kurtosis rej] = rejkurt( signal, threshold, kurtosis, normalize);
%
% Inputs:
%   signal     - one dimensional column vector of data values, two
%                dimensional column vector of values of size
%                sweeps x frames or three dimensional array of size
%                component x sweeps x frames. If three dimensional,
%                all components are treated independently.
%   threshold  - Absolute threshold. If normalization is used then the
%                threshold is expressed in standard deviation of the
%                mean. 0 means no threshold.
%   kurtosis   - pre-computed kurtosis (only perform thresholding). Default
%                is the empty array [].
%   normalize  - 0 = do not not normalize kurtosis. 1 = normalize kurtosis.
%                2 is 20% trimming (10% low and 10% high) kurtosis before
%                normalizing. Default is 0.
%
% Outputs:
%   kurtosis    - normalized joint probability  of the single trials
%                (same size as signal without the last dimension)
%   rej         - rejected matrix (0 and 1, size: 1 x sweeps)
%
% Remarks:
%   The exact values of kurtosis depend on the size of a time
%   step and thus cannot be considered as absolute.
%   This function uses the kurtosis function from the statistival
%   matlab toolbox. If the statistical toolbox is not installed,
%   it uses the 'kurt' function of the ICA/EEG toolbox.
%
% See also: KURT, KURTOSIS

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function [kurto, rej] = rejkurt( signal, threshold, oldkurtosis, normalize);

if nargin < 1
	help rejkurt;
	return;
end;
if nargin < 2
	threshold = 0;
end;
if nargin < 4
	normalize = 0;
end;
if nargin < 3
	oldkurtosis = [];
end;

if size(signal,2) == 1 % transpose if necessary
	signal = signal';
end

nbchan = size(signal,1);
pnts = size(signal,2);
sweeps = size(signal,3);
kurto = zeros(nbchan,sweeps);

if ~isempty( oldkurtosis ) % speed up the computation
	kurto = oldkurtosis;
else
	for rc = 1:nbchan
		% compute all kurtosis
		% --------------------
		for index=1:sweeps
			try
			    kurto(rc, index) = kurtosis(signal(rc,:,index));
			catch
				kurto(rc, index) = kurt(signal(rc,:,index));
			end;
		end
	end

	% normalize the last dimension
	% ----------------------------
	if normalize
        tmpkurt = kurto;
        if normalize == 2,
            tmpkurt = sort(tmpkurt);
            minind  = max(round(length(tmpkurt)*0.1),1);
            maxind  = round(length(tmpkurt)-round(length(tmpkurt)*0.1));
            if size(tmpkurt,2) == 1
                 tmpkurt = tmpkurt(minind:maxind);
            else tmpkurt = tmpkurt(:,minind:maxind);
            end
        end
	    switch ndims( signal )
	    	case 2,	kurto = (kurto-mean(tmpkurt)) / std(tmpkurt);
	    	case 3,	kurto = (kurto-mean(tmpkurt,2)*ones(1,size(kurto,2)))./ ...
				        (std(tmpkurt,0,2)*ones(1,size(kurto,2)));
		end
	end
end

% reject
% ------
if threshold(1) ~= 0
    if length(threshold) > 1
    	rej = (threshold(1) > kurto) | (kurto > threshold(2));
    else
    	rej = abs(kurto) > threshold;
    end
else
	rej = zeros(size(kurto));
end;

return;


function value = sdot ( n, dx, incx, dy, incy )

%*****************************************************************************80
%
%% SDOT forms the dot product of two vectors.
%
%  Discussion:
%
%    This routine uses unrolled loops for increments equal to one.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 May 2006
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979.
%
%    Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
%    Basic Linear Algebra Subprograms for Fortran Usage,
%    Algorithm 539,
%    ACM Transactions on Mathematical Software,
%    Volume 5, Number 3, September 1979, pages 308-323.
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vectors.
%
%    Input, real DX(*), the first vector.
%
%    Input, integer INCX, the increment between successive entries in DX.
%
%    Input, real DY(*), the second vector.
%
%    Input, integer INCY, the increment between successive entries in DY.
%
%    Output, real VALUE, the sum of the product of the
%    corresponding entries of DX and DY.
%
  value = 0.0;

  if ( n <= 0 )
    return
  end
%
%  Code for unequal increments or equal increments
%  not equal to 1.
%
  if ( incx ~= 1 | incy ~= 1 )

    if ( 0 <= incx )
      ix = 1;
    else
      ix = ( - n + 1 ) * incx + 1;
    end

    if ( 0 <= incy )
      iy = 1;
    else
      iy = ( - n + 1 ) * incy + 1;
    end

    for i = 1 : n
      value = value + dx(ix) * dy(iy);
      ix = ix + incx;
      iy = iy + incy;
    end
%
%  Code for both increments equal to 1.
%
  else

    m = mod ( n, 5 );

    for i = 1 : m
      value = value + dx(i) * dy(i);
    end

    for i = m+1 : 5 : n

      value = value + dx(i  ) * dy(i  ) ...
                    + dx(i+1) * dy(i+1) ...
                    + dx(i+2) * dy(i+2) ...
                    + dx(i+3) * dy(i+3) ...
                    + dx(i+4) * dy(i+4);
    end

  end

  return
end


function[] = hindawi()
%
% Simulation code for [1],
%
% [1] Paul Rodriguez "Review: Total Variation Regularization Algorithms for
%  		      Images Corrupted With Different Noise Models"
%
%
%
% Legal:
%
% Authors
%   Paul Rodriguez    prodrig@pucp.edu.pe
%

l2TV         = 1;
l2TV_nqp     = 2;
l1TV         = 3;
l1TV_adapt   = 4;
poiTV_denoi  = 5;
poiTV_deconv = 6;
gammaTV      = 7;
mixTV        = 8;
nTV          = mixTV;

% Test Images (for each case)

l2Imgs = {'goldhl', 'Clena'};           % To be corrupted with Gaussian noise
l1Imgs = {'Cbarb', 'boats'};            % To be corrupted with Salt & Pepper noise
poiImgs = {'cman512', 'cpeppers'};     % To be corrupted with Poisson noise
gammaImgs = {'tank', 'Clena'};          % To be corrupted with Gamma noise
mixImgs = {'cman512'};                  % To be corrupted with mixed Gaussian + Impulse noise

Tests = cell(nTV-1, 1);

Tests{l2TV} = l2Imgs;
Tests{l2TV_nqp} = l2Imgs;
Tests{l1TV} = l1Imgs;
Tests{l1TV_adapt} = l1Imgs;
Tests{poiTV_denoi} = poiImgs;
Tests{poiTV_deconv} = poiImgs;

%  Tests{gammaTV} = gammaImgs;
%  Tests{mixTV} = mixImgs;

% kernel

  kernel = fspecial('disk',3.2);

  K = @(x) imfilter(x, kernel, 'symmetric','conv');

  KT = @(x) K(x);
  KC = {K, KT};

% Noise level (define the noise level to corrupt images)

l2Noise = [0.1 0.2];
l1Noise = [0.3 0.5 0.8];
randomNoise = [0.1 0.2 0.3];
poiNoise = [5 30 100 255];

Noise = cell(nTV-1, 1);

Noise{l2TV} = l2Noise;
Noise{l2TV_nqp} = l2Noise;
Noise{l1TV} = l1Noise;
Noise{l1TV_adapt} = l1Noise;
Noise{poiTV_denoi} = poiNoise;
Noise{poiTV_deconv} = poiNoise;

% TV Noise Model (to corrupt imput images)

NoiseModel = cell(nTV-1, 1);

NoiseModel{l2TV} = @(Img, sigma) imnoise(K(Img),'gaussian', 0, (sigma^2) );
NoiseModel{l2TV_nqp} = @(Img, sigma) imnoise(K(Img),'gaussian', 0, (sigma^2) );
NoiseModel{l1TV} = @(Img, spnoise) imnoise(Img, 'salt & pepper', spnoise);
NoiseModel{l1TV_adapt} = @(Img, spnoise) imnoise(Img, 'salt & pepper', spnoise);

NoiseModel{poiTV_denoi} = @(Img, M) poissrnd( M*NormalizeMax(Img) );
NoiseModel{poiTV_deconv} = @(Img, M) poissrnd( M*NormalizeMax(K(Img)) );

% ----------------------
% Define TV parameters
% ----------------------

% Loops

TVLoops = zeros(nTV-1, 1);

TVLoops(l2TV)           = 5;
TVLoops(l2TV_nqp)       = 5;
TVLoops(l1TV)           = 4;
TVLoops(l1TV_adapt)     = 4;

TVLoops(poiTV_denoi)    = 6;
TVLoops(poiTV_deconv)   = 6;

% regularization parameters

TVLambda = zeros(nTV-1, 5);

TVLambda(l2TV,1) = 0.05; TVLambda(l2TV,2) = 0.1;
TVLambda(l2TV_nqp,1) = 0.05; TVLambda(l2TV_nqp,2) = 0.1;

TVLambda(l1TV,1) = 1.2; TVLambda(l1TV,2) = 1.4; TVLambda(l1TV,3) = 1.5;
TVLambda(l1TV_adapt,1) = 1.0; TVLambda(l1TV_adapt,2) = 1.0; TVLambda(l1TV_adapt,3) = 1.0;

TVLambda(poiTV_denoi,1:4) = 2./[0.35, 0.15, 0.075, 0.025 ];

%  Wrappers to TV functions)

RestoreTV = cell(nTV-1, 1);

RestoreTV{l2TV} = @(b, lambda, loops, KC) runl2TV(b, lambda, loops, KC);
RestoreTV{l2TV_nqp} = @(b, lambda, loops, KC) runl2TV_nqp(b, lambda, loops, KC);
RestoreTV{l1TV} = @(b, lambda, loops, dummy) runl1TV(b, lambda, loops, []);
RestoreTV{l1TV_adapt} = @(b, lambda, loops, dummy) runl1TV_Adapt(b, lambda, loops);

RestoreTV{poiTV_denoi} = @(b, lambda, loops, dummy) run_poiTV(b, lambda, loops, {});
RestoreTV{poiTV_deconv} = @(b, lambda, loops, KC) run_poiTV(b, lambda, loops, KC);

% additional vars

t1 = zeros(nTV-1, 2, 2);
t2 = zeros(nTV-1, 2, 2);

nmpdef;

%%%%%%%%%%%%%%%%%%%%%%%%
%        Setup         %
%%%%%%%%%%%%%%%%%%%%%%%%

SSIM_CODE = exist('ssim_index');
if( SSIM_CODE == 0 )
  disp('NOTE:');
  disp('  The function ssim_index (code for [SSIM]) is not in your path...');
  disp('  You may download it from:');
  disp('  http://www.ece.uwaterloo.ca/~z70wang/research/ssim/');
  disp('  ');
  disp('  Disabling SSIM reports');
  disp('  ');
  disp('  [SSIM]  Z. Wang, A. Bovik, H. Sheikh and E. Simoncelli, ');
  disp('         "Image quality assessment: From error visibility to');
  disp('         structural similarity " ');
  disp('         IEEE Transactions on Image Processing, 2004, 13:4(600-612).');

end

t=5;

str_all = sprintf(' \n');

while( iscell(Tests{t}) )

  str = sprintf(' \n'); str_all = [ str_all str ];
  str = sprintf(' Img \t\t Noise \t\t SNR (db) \t\t Time (s) \t\t SSIM \n');
  str_all = [ str_all str ];

  NImgs = length( Tests{t} );

  for k = 1: NImgs,

  switch lower( Tests{t}{k} )

    case{'lena'}
      I = double( imread('gray_imgs/lena_gray_512.png') ) / 255;
      SSIM_COLOR = 1;

    case{'peppers'}
      I = double( imread('gray_imgs/peppers_gray.png') ) / 255;
      SSIM_COLOR = 1;

    case{'boats'}
      I = double( imread('gray_imgs/boats_gray.png') ) / 255;
      SSIM_COLOR = 1;

    case{'goldhl'}
      I = double( imread('gray_imgs/goldhill_gray.png') ) / 255;
      SSIM_COLOR = 1;

    case{'cman'}
      I = double( imread('gray_imgs/cameraman_256x256.tiff') ) / 255;
      SSIM_COLOR = 1;

    case{'cman512'}
      I = double( imread('gray_imgs/cameraman_512x512.tiff') ) / 255;
      SSIM_COLOR = 1;

    case{'clena'}
      I = double( imread('color_imgs/lena_color_512.png') ) / 255;
      SSIM_COLOR = 0;

    case{'cbarb'}
      I = double( imread('color_imgs/barbara_color.png') ) / 255;
      SSIM_COLOR = 0;

    case{'cpeppers'}
      I = double( imread('color_imgs/peppers_color.png') ) / 255;
      SSIM_COLOR = 0;

    case{'cmandrill'}
      I = double( imread('color_imgs/mandrill_color.png') ) / 255;
      SSIM_COLOR = 0;

  end % --- END (switch) ---

  for n = 1:length(Noise{t})

    % add noise
    b = NoiseModel{t}( I, Noise{t}(n) );
    figure; imagesc( Normalize(b) );  colormap gray; axis image; axis off;

    % Restore via TV
    [u t1(t,k,n) t2(t,k,n)] = RestoreTV{t}(b, TVLambda(t,n), TVLoops(t), KC );

    % Restore performance
    [snrRec(t,k,n), ssimRec(t,k,n)] = computePerf(I, u, SSIM_CODE*SSIM_COLOR, 0);

    if(n==1)
      str = sprintf('%s \t\t %1.2f \t\t %2.2f \t\t %2.2f (%2.2f) \t\t %1.3f \n', ...
                    lower( Tests{t}{k} ), Noise{t}(n), snrRec(t,k,n), t1(t,k,n), t2(t,k,n), ssimRec(t,k,n) );
    else
      str = sprintf('     \t\t %1.2f \t\t %2.2f \t\t %2.2f (%2.2f) \t\t %1.3f \n', ...
                     Noise{t}(n), snrRec(t,k,n), t1(t,k,n), t2(t,k,n), ssimRec(t,k,n) );
    end
    str_all = [ str_all str ];

  end % --- END (FOR(n)) ---

  end % --- END (FOR(k)) ---

  disp(str_all);

 t = t + 1;

 if(t==6) break; end

end

end

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

%%%%%%%%%%%%%%%%%%%%%%%%
%     Normalize        %
%%%%%%%%%%%%%%%%%%%%%%%%

function[u] = Normalize(x)

u = (x - min(x(:)))/(max(x(:)) - min(x(:)));

end

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

function[u] = NormalizeMax(x)

u = x/max(abs(x(:)));

end

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

function[u, timePerf, t2] = runl2TV(b, lambda, loops, KC)

    pars = irntvInputPars('l2tv');

    pars.pcgtol_ini = 1e-4;
    pars.loops      = loops;
%      pars.U0         = b;

    pars.adapt_epsR   = 1;
    pars.epsR_cutoff  = 0.01;
    pars.adapt_epsF   = 1;
    pars.epsF_cutoff  = 0.05;

    tic;
    u = irntv(b, KC, lambda, pars);
    timePerf = toc;

    t2 = 0;

end

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

function[u, timePerf, t2] = runl2TV_nqp(b, lambda, loops, KC)

    pars = irntvInputPars('l2tv_nqp');

    pars.pcgtol_ini = 1e-4;
    pars.loops      = loops;
%      pars.U0         = b;

    pars.adapt_epsR   = 1;
    pars.epsR_cutoff  = 0.01;
    pars.adapt_epsF   = 1;
    pars.epsF_cutoff  = 0.1;

    pars.loops_NQP    = 15;
    pars.gamma_NQP    = 0.5e-3;
    pars.alpha_NQP    = 5e-1;
    pars.vmax_NQP     = 1+1;            % maximum value of output image

    tic;
    u = irntv(b+1, KC, lambda, pars)-1;
    timePerf = toc;

    t2 = 0;

end

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

function[u, timePerf, t2] = runl1TV(b, lambda, loops, KC)

    if(nargin < 6)
      flagTitle = 0;
    end

    pars = irntvInputPars('l1tv');

    pars.pcgtol_ini = 1e-4;
    pars.epsF       = 1e-2;
    pars.epsR       = 1e-4;
    pars.loops      = loops;

    tic;
    u = irntv(b, KC, lambda, pars);
    timePerf = toc;

    t2 = 0;

end

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

function[u, timePerf, t2] = runl1TV_Adapt(b, lambda, loops)

tic;

S0 = adaptMedian(b);

t2 = toc;

InputDims = size(S0);

if(length(InputDims) == 2)

    lambda_adapt  = 1e-6*(S0 == 0) + lambda*5*(S0 ~= 0);

else

    for d=1:3,
      lambda_adapt(:,:,d)  = 1e-6*(S0(:,:,d) == 0) + lambda*5.0*(S0(:,:,d) ~= 0);
    end

end

% ---------- Setup for IRN_adapt  ------------------

pars_irn_adapt = irntvInputPars('l1tv_adapt');

pars_irn_adapt.adapt_epsR   = 1;
pars_irn_adapt.epsR_cutoff  = 0.01;
pars_irn_adapt.adapt_epsF   = 1;
pars_irn_adapt.epsF_cutoff  = 0.1;

pars_irn_adapt.pcgtol_ini = 1e-4;

pars_irn_adapt.loops      = 1;

pars_irn_adapt.U0      = b;   % necessary the for adapt case

  tic;
  u = irntv(b, [], lambda_adapt, pars_irn_adapt);

  for m = 2:loops

    pars_irn_adapt.U0 = u;
    lambda_adapt = lambda_adapt*1.2;

    u = irntv(b, [], lambda_adapt, pars_irn_adapt);

  end

  timePerf = toc;

end

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

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

function[u, timePerf, t2] = run_poiTV(b, lambda, loops, KC)

    pars = irntvInputPars('tv_poisson_adapt');

    pars.pcgtol_ini = 1e-4;
    pars.loops      = 1;
%      pars.U0         = b;

    pars.adapt_epsR   = 1;
    pars.epsR_cutoff  = 0.1;
    pars.adapt_epsF   = 1;
    pars.epsF_cutoff  = 0.15;

    pars.loops_NQP    = 35;
    pars.gamma_NQP    = 5e-3;
    pars.alpha_NQP    = 5e-1;
    pars.vmax_NQP     = 1+1;            % maximum value of output image

    T = lambda;

    tic;
    u = irntv(b+0.01, KC, lambda, pars)-0.01;

    for ln=2:loops,

      [sig1, cv1, mu1, siginv1, cvinv1, S1, lmu1] = estNoise(u, 2*3+1, 100, 1);
      [sig2, cv2, mu2, siginv2, cvinv2, S2, lmu2] = estNoise(lmu1, 2*3+1, 100, 1);

      pars.U0 = u;
      vmin = min( pars.U0(:) );
      if(vmin < 0) pars.U0 = pars.U0 - vmin + 0.01; end

      alpha = 1.0;
      [Nrows Ncols Ndims] = size(u);

      mask = zeros(size(S2));

      for d = 1:Ndims,
        maskTmp = zeros(Nrows*Ncols,1);

        vS1 = S2(:,:,d); vS1 = vS1(:);

        tau = unimodal(S1(:,:,d));
        p2 = find( vS1 < alpha*tau );
        maskTmp(p2) = (1 - Normalize( vS1(p2) ) )*(1-0.85) + 0.85;

        p3 = find(vS1 >= alpha*tau);
        maskTmp(p3) = 1.0;

        mask(:,:,d) = reshape(maskTmp, [Nrows Ncols]);

      end % _END_ FOR(d)

      T = T.*mask;

      u = irntv(b+0.1, KC, T, pars)-0.1;

    end

    % ====================================
    timePerf = toc;

    t2 = 0;

end

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

function[snrRec, ssimRec] = computePerf(Img, u, flagSSIM, flagTitle)

    snrRec = snr(Img, u);
    if(flagSSIM)
      ssimRec = ssim_index(255*Normalize(Img), 255*Normalize(u));
    else
      ssimRec = NaN;
    end

    figure; imagesc( Normalize(u) );  colormap gray; axis image; axis off;
    if(flagTitle)
      title(sprintf('Restored Image\n SNR: %4.1fdB. SSIM: %1.2f ', ...
               snrRec, ssimRec));
    end

end


function Y = SurfStatSmooth( Y, surf, FWHM );

%Smooths surface data by repeatedly averaging over edges.
%
% Usage: Y = SurfStatSmooth( Y, sv, FWHM );
%
% Y        = n x v or n x v x k matrix of surface data, v=#vertices;
%            n=#observations; k=#variates, or memory map of same.
% surf.tri = t x 3 matrix of triangle indices, 1-based, t=#triangles.
% or
% surf.lat = nx x ny x nz matrix, 1=in, 0=out, [nx,ny,nz]=size(volume).
% FWHM     = approximate FWHM of Gaussian smoothing filter, in mesh units.
%
% Note that if the data is memory mapped, then the data is overwriten by
% the smoothed data.

niter=ceil(FWHM^2/(2*log(2)));

if isnumeric(Y)
    [n,v,k]=size(Y);
    isnum=true;
else
    Ym=Y;
    s=Ym.Format{2};
    if length(s)==2
        s=s([2 1]);
        k=1;
    else
        s=s([3 1 2]);
        k=s(3);
    end
    n=s(1);
    v=s(2);
    isnum=false;
end

edg=SurfStatEdg(surf);

Y1=accumarray(edg(:,1),2,[v 1])'+accumarray(edg(:,2),2,[v 1])';

if n>1
    fprintf(1,'%s',[num2str(n) ' x ' num2str(k) ' surfaces to smooth, % remaining: 100 ']);
end
n10=floor(n/10);
for i=1:n
    if rem(i,n10)==0
        fprintf(1,'%s',[num2str(100-i/n10*10) ' ']);
    end
    for j=1:k
        if isnum
            Ys=squeeze(Y(i,:,j));
            for iter=1:niter
                Yedg=Ys(edg(:,1))+Ys(edg(:,2));
                Ys=(accumarray(edg(:,1),Yedg',[v 1]) + ...
                    accumarray(edg(:,2),Yedg',[v 1]))'./Y1;
            end
            Y(i,:,j)=Ys;
        else
            if length(s)==2
                Y=Ym.Data(1).Data(:,i);
            else
                Y=Ym.Data(1).Data(:,j,i);
            end
            for iter=1:niter
                Yedg=Y(edg(:,1))+Y(edg(:,2));
                Y=(accumarray(edg(:,1),Yedg',[v 1]) + ...
                    accumarray(edg(:,2),Yedg',[v 1]))'./Y1;
            end
            if length(s)==2
                Ym.Data(1).Data(:,i)=Y;
            else
                Ym.Data(1).Data(:,j,i)=Y;
            end
        end
    end
end
if n>1
    fprintf(1,'%s\n','Done');
end
if ~isnum
    Y=Ym;
end

return
end


% Fig. 5.12   Feedback Control of Dynamic Systems, 6e
%             Franklin, Powell, Emami

clf
np=[1 1];
dp=[1 4 0 0];
rlocus(np,dp)
axis([-6 2 -3 3])
grid on
title('Root locus for Figure 5.12')
z=0:.1:.9;
 wn= .5:.5:6;
 sgrid(z, wn)
 hold off


%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software
%  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
%function tfrbudt
%TFRBUDT Unit test for the function TFRBUD.

%       F. Auger, Dec. 1995 - O. Lemoine, March 1996.

% We test each property of the corresponding TFR :

N=128;

% Covariance by translation in time
t1=55; t2=70; f=0.3;
sig1=amgauss(N,t1).*fmconst(N,f,t1);
sig2=amgauss(N,t2).*fmconst(N,f,t2);
tfr1=tfrbud(sig1);
tfr2=tfrbud(sig2);
[tr,tc]=size(tfr1);
tfr=tfr1-tfr2(:,modulo((1:tc)-t1+t2,tc));
if any(any(abs(tfr)>sqrt(eps))),
 error('tfrbud test 1 failed');
end

% Reality of the TFR
sig=noisecg(N);
tfr=tfrbud(sig);
if sum(any(abs(imag(tfr))>sqrt(eps)))~=0,
 error('tfrbud test 2 failed');
end

% Energy conservation
sig=noisecg(N);
tfr=tfrbud(sig);
Es=norm(sig)^2;
Etfr=sum(mean(tfr));
if abs(Es-Etfr)>sqrt(eps),
 error('tfrbud test 3 failed');
end

% Time-marginal
sig=noisecg(N);
tfr=tfrbud(sig);
ip1=abs(sig).^2;
ip2=mean(tfr)';
if any(abs(ip1-ip2)>sqrt(eps)),
 error('tfrbud test 4 failed');
end

% Frequency-marginal
sig=noisecg(N);
tfr=tfrbud(sig,1:N,N,[1],ones(N-1,1));
FFT=fft(sig);
psd1=abs(FFT(2:N/2)).^2/(2*N);
psd2=mean(tfr(1:2:N,:)')';
if any(abs(psd1-psd2(2:N/2))>sqrt(eps)),
 error('tfrbud test 5 failed');
end

% Conservation of the time support (wide-sense)
sig=[zeros(N/4,1);fmlin(N/2);zeros(N/4,1)];
tfr=tfrbud(sig,1:N,N,[1],ones(N-1,1));
if sum(any(abs(tfr(:,1:N/4-1))>sqrt(eps))) | ...
   sum(any(abs(tfr(:,(3*N/4+1):N))>sqrt(eps))),
 error('tfrbud test 6 failed');
end

% time localization
t0=30; sig=((1:N)'==t0);
tfr=tfrbud(sig);
[ik,jk]=find(tfr~=0.0);
if any(jk~=t0)|any(ik'-(1:N)),
 error('tfrbud test 7 failed');
end;

% frequency localization
f0=10;
sig=fmconst(N+6,f0/N);
tfr=tfrbud(sig,N/2+2,N,tftb_window(11,'rect'),tftb_window(N+1,'rect'),1.2);
if (find(tfr>1/N)~=2*f0+1)|(abs(mean(tfr)-1.0)>2.0*eps),
 error('tfrbud test 8 failed');
end;

N=127;

% Covariance by translation in time
t1=55; t2=70; f=0.3;
sig1=amgauss(N,t1).*fmconst(N,f,t1);
sig2=amgauss(N,t2).*fmconst(N,f,t2);
tfr1=tfrbud(sig1);
tfr2=tfrbud(sig2);
[tr,tc]=size(tfr1);
tfr=tfr1-tfr2(:,modulo((1:tc)-t1+t2,tc));
if any(any(abs(tfr)>sqrt(eps))),
 error('tfrbud test 9 failed');
end

% Reality of the TFR
sig=noisecg(N);
tfr=tfrbud(sig);
if sum(any(abs(imag(tfr))>sqrt(eps)))~=0,
 error('tfrbud test 10 failed');
end

% Energy conservation
sig=noisecg(N);
tfr=tfrbud(sig);
Es=norm(sig)^2;
Etfr=sum(mean(tfr));
if abs(Es-Etfr)>sqrt(eps),
 error('tfrbud test 11 failed');
end

% Time-marginal
sig=noisecg(N);
tfr=tfrbud(sig);
ip1=abs(sig).^2;
ip2=mean(tfr)';
if any(abs(ip1-ip2)>sqrt(eps)),
 error('tfrbud test 12 failed');
end

% Frequency-marginal
sig=noisecg(N);
tfr=tfrbud(sig,1:N,N,[1],ones(N,1));
FFT=fft(sig);
psd1=abs(FFT(2:fix(N/2))).^2/(2*N);
psd2=mean(tfr(1:2:N,:)')';
if any(abs(psd1-psd2(2:fix(N/2)))>5e-2),
 error('tfrbud test 13 failed');
end

% Conservation of the time support (wide-sense)
sig=[zeros(round(N/4),1);fmlin(round(N/2));zeros(round(N/4),1)];
tfr=tfrbud(sig,1:N,N,[1],ones(N,1));
if sum(any(abs(tfr(:,1:round(N/4)-1))>sqrt(eps))) | ...
   sum(any(abs(tfr(:,(round(3*N/4)+2):N))>sqrt(eps))),
 error('tfrbud test 14 failed');
end

% time localization
t0=30; sig=((1:N)'==t0);
tfr=tfrbud(sig);
[ik,jk]=find(tfr~=0.0);
if any(jk~=t0)|any(ik'-(1:N)),
 error('tfrbud test 15 failed');
end;

% frequency localization
f0=10;
sig=fmconst(N+6,f0/N);
tfr=tfrbud(sig,ceil(N/2)+2,N,tftb_window(11,'rect'),tftb_window(N,'rect'),1.2);
if (find(tfr>1/N)~=2*f0+1)|(abs(mean(tfr)-1.0)>sqrt(eps)),
 error('tfrbud test 16 failed');
end;


function [mu,isig] = spm_affine_priors(typ)
% Distribution of the priors used in affine registration
%
% The parameters for this distribution were derived empirically from 227
% scans, that were matched to the ICBM space.
%_______________________________________________________________________
% Copyright (C) 2003-2011 Wellcome Trust Centre for Neuroimaging

% John Ashburner
% $Id: spm_affine_priors.m 4155 2011-01-11 15:22:39Z guillaume $

%% Values can be derived by...
%sn = spm_select(Inf,'.*seg_inv_sn.mat$');
%X  = zeros(size(sn,1),12);
%for i=1:size(sn,1),
%    p  = load(deblank(sn(i,:)));
%    M  = p.VF(1).mat*p.Affine/p.VG(1).mat;
%    J  = M(1:3,1:3);
%    V  = sqrtm(J*J');
%    R  = V\J;
%    lV      =  logm(V);
%    lR      = -logm(R);
%    P       = zeros(12,1);
%    P(1:3)  = M(1:3,4);
%    P(4:6)  = lR([2 3 6]);
%    P(7:12) = lV([1 2 3 5 6 9]);
%    X(i,:)  = P';
%end;
%mu   = mean(X(:,7:12));
%XR   = X(:,7:12) - repmat(mu,[size(X,1),1]);
%isig = inv(XR'*XR/(size(X,1)-1))

switch deblank(lower(typ))

case 'mni', % For registering with MNI templates...
    mu   = [0.0667 0.0039 0.0008 0.0333 0.0071 0.1071]';
    isig = 1e4 * [
        0.0902   -0.0345   -0.0106   -0.0025   -0.0005   -0.0163
       -0.0345    0.7901    0.3883    0.0041   -0.0103   -0.0116
       -0.0106    0.3883    2.2599    0.0113    0.0396   -0.0060
       -0.0025    0.0041    0.0113    0.0925    0.0471   -0.0440
       -0.0005   -0.0103    0.0396    0.0471    0.2964   -0.0062
       -0.0163   -0.0116   -0.0060   -0.0440   -0.0062    0.1144];

case 'imni', % For registering with MNI templates...
    mu   = -[0.0667 0.0039 0.0008 0.0333 0.0071 0.1071]';
    isig = 1e4 * [
        0.0902   -0.0345   -0.0106   -0.0025   -0.0005   -0.0163
       -0.0345    0.7901    0.3883    0.0041   -0.0103   -0.0116
       -0.0106    0.3883    2.2599    0.0113    0.0396   -0.0060
       -0.0025    0.0041    0.0113    0.0925    0.0471   -0.0440
       -0.0005   -0.0103    0.0396    0.0471    0.2964   -0.0062
       -0.0163   -0.0116   -0.0060   -0.0440   -0.0062    0.1144];

case 'rigid', % Constrained to be almost rigid...
    mu   = zeros(6,1);
    isig = eye(6)*1e8; % spm_affreg used 1e9

case 'subj', % For inter-subject registration...
    mu   = zeros(6,1);
    isig = 1e3 * [
        0.8876    0.0784    0.0784   -0.1749    0.0784   -0.1749
        0.0784    5.3894    0.2655    0.0784    0.2655    0.0784
        0.0784    0.2655    5.3894    0.0784    0.2655    0.0784
       -0.1749    0.0784    0.0784    0.8876    0.0784   -0.1749
        0.0784    0.2655    0.2655    0.0784    5.3894    0.0784
       -0.1749    0.0784    0.0784   -0.1749    0.0784    0.8876];

case 'eastern', % For East Asian brains to MNI...
    mu   = [0.0719   -0.0040   -0.0032    0.1416    0.0601    0.2578]';
    isig = 1e4 * [
        0.0757    0.0220   -0.0224   -0.0049    0.0304   -0.0327
        0.0220    0.3125   -0.1555    0.0280   -0.0012   -0.0284
       -0.0224   -0.1555    1.9727    0.0196   -0.0019    0.0122
       -0.0049    0.0280    0.0196    0.0576   -0.0282   -0.0200
        0.0304   -0.0012   -0.0019   -0.0282    0.2128   -0.0275
       -0.0327   -0.0284    0.0122   -0.0200   -0.0275    0.0511];

case 'none', % No regularisation...
    mu   = zeros(6,1);
    isig = zeros(6);

otherwise
    error(['"' typ '" not recognised as type of regularisation.']);
end


function sumsq = sumsqcomp(dpixc, res, peval)
ROIx=peval.ROIx(1):peval.ROIx(2);
ROIy=peval.ROIy(1):peval.ROIy(2);
ROIz=peval.ROIz(1):peval.ROIz(2);
dpixcs = dpixc(ROIx,ROIy,ROIz);
dveccs = reshape(dpixcs, peval.numpix, peval.nt);
htr =res.htrace;
for ii=1:size(htr,1)
    htr(ii,3,:)=res.h(3,:);
    itmp=res.w*squeeze(htr(ii,:,:));
    isq=(dveccs-itmp).^2;
    sumsq(ii)=sum(isq(:));
end


function r82poly2_print ( a, b, c, d, e, f )

%*****************************************************************************80
%
%% R82POLY2_PRINT prints a second order polynomial in two variables.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 October 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, C, D, E, F, the coefficients.
%
  fprintf ( 1, '  p(x,y) = %g * x^2 + %g * y^2 + %g * xy\n', a, b, c );
  fprintf ( 1, '         + %g * x + %g * y + %g\n', d, e, f );

  return
end


function x = NormL1NN_project(x,weights,tau)
% Projection onto the non-negative part of the L1 ball

%idx = (x > 0);
%x(idx) = NormL1_project(x(idx),weights(idx),tau);
x(x < 0) = 0;
x = NormL1_project(x,weights,tau);


function u_est = CG_MultiScale_LAP3D_Fast(I1, I2, FilterSizes, PreFilt, MedFilt, uin)
% The function implements a fast multi-scale framework for the 3D version
% of the LAP optical flow algorithm. Instead of downsampling the images, the
% framework changes the size of the all-pass filters used in the LAP
% algorithm. The filter basis used in the LAP algorithm spans the
% derivatives of a Gaussian filter.
%
% Function uses faster interpolation (but less accurate).
%
% Note that this implementation is for greyscale images only.
%
% Input parameters:
%       I1 and I2   -> Input images of size M by N (Greyscale)
%       FilterSizes -> Controls the size of the filters (vector with
%                      values for R
%                      i.e. filter size is [2R + 1] by [2R + 1]
%       PreFilt     -> Optional parameter to decide whether to highpass
%                       filter the images. (Default = 1 (Yes), 0 = (No))
%       MedFilt     -> Optional parameter to decide whether to median
%                       filter the flow at fine scales. (Default = 1 (Yes), 0 = (No))
%
% Outputs:
%       u_est       -> Estimate of the optical flow
%
%
% Date: 08/07/2015, Author: Chris Gilliam
%
% modifications for MRI application:
% - different input parameter: Filter size instead of upper parameter R
% - initialization in single precision (except filter kernel)
% 26.08.2015, Verena Neumann/Thomas Kuestner

if nargin <= 3,
    PreFilt = 1;
    MedFilt = 1;
elseif nargin <= 4,
    MedFilt = 1;
end

% Obtain the dimensions of the images:
[M, N, P] = size(I1);

% Initialise filter functions:
funs = Filter_Functions;

% Local Gaussian filter (used in high pass filtering)
h = exp(-(-2:2).^2/2);
h = h./sum(h(:));

% Initial optical flow estimate
if(nargin < 6)
    u_holder = repmat({zeros(M,N,P,'single')}, 1, 3);
else
    u_holder = uin;
end

% define half support of filters (i.e. R)
amp_array = FilterSizes;

% Initialise local counter:
num_level = 0;

% Local I1 variable:
if PreFilt == 1,
    im1 = I1 - funs.Filter_General(I1, h); % High pass filtering using gaussian filter h
%       im1 = funs.Filter_Laplacian(im1);  % high-pass using generalised Laplacian filter
else
    im1 = I1;
end

% Start estimating the optical flow
for l = 1:length(amp_array),
    num_level = num_level + 1;
    disp(['Level ', int2str(num_level), '/', int2str(size(amp_array,2))]);

    % Define filter parameter R at each iteration
    amp_size = amp_array(l);

    % Load Filter Basis:
    Basis_Set = loadbasis(3,amp_size);

    tic;
    if l == 1,
        % No warping for first iteration:
        if PreFilt == 1,
            I2_shift = I2 - funs.Filter_General(I2, h); % High pass filtering using gaussian filter h
%             I2_shift = funs.Filter_Laplacian(I2);       % high-pass using generalised Laplacian filter
        else
            I2_shift = I2;
        end
    else
        % Warp I2 closer to I1 using current optical flow estimate
%         I2_shift = imshift_3D(I2,{-u_holder{1}, -u_holder{2}, -u_holder{3}}, 'shiftedlinear');
        I2_shift = ShiftedLinear_Interp_3D(-u_holder{1},-u_holder{2},-u_holder{3},I2);
        if PreFilt == 1,
            I2_shift = I2_shift - funs.Filter_General(I2_shift, h); % High pass filtering using gaussian filter h
%           I2_shift = funs.Filter_Laplacian(I2_shift); % high-pass using generalised Laplacian filter
        end
    end

    disp(['Filter size = ', num2str(2*amp_size+1), ', Image Warping time = ', num2str(toc,3)]);

    % Using basis functions estimate optical flow on a local scale:
    tic;
    [uest_Orig, ~] = optiflowFilter3D(im1, I2_shift, Basis_Set);
    disp(['Filter size = ', num2str(2*amp_size+1), ', LAP Algorithm time = ', num2str(toc,3)]);

    % Clean optical flow
    % Stage 1: Remove nan's in the optical flow using inpainting:
    if sum(isnan(uest_Orig{1}(:))) >= M*N*P,
        error('All NaN. Suggest reduce Level_Num');
    end
    tic;
    [uest_Clean, ~] = cleanOF3D(uest_Orig);

    % Stage 2: Remove flow elements that corresponding to large warping
    % errors.
    R = round(2*amp_size);
    k1 = -R:R;
    uest_Clean = cellfun(@funs.Filter_Gauss, uest_Clean, {R,R,R}, {k1,k1,k1}, 'uni',false);

    disp(['Filter size = ', num2str(2*amp_size+1), ', Post-Processing time = ', num2str(toc,3)]);

    % Rescale optical flow and add to estimate
    u_holder = cellfun(@plus,u_holder,uest_Clean,'uniformoutput',false);

    % Refinement of OF at highest level based on errors in shifted
    %           images
    if amp_size <= 2 && MedFilt == 1,
        u_holder = Cleaning_Procedure(u_holder);
    end

end

u_est = u_holder;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% Embedded functions %%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function u_out = Cleaning_Procedure(u_in)
% function cleans the estimate of the optical flow. The cleaning process
% comprises a robust smoothing stage using two Median filters (of different
% sizes)
%

% Define size of median filters
B1 = 11;
B2 = 3;

% Two part median filtering:
% fine scale
u_out = cellfun(@medfilt3, u_in, {B2,B2,B2}, {'symmetric','symmetric','symmetric'},'uni',false);
% coarse scale
u_out = cellfun(@medfilt3, u_out, {B1,B1,B1}, {'symmetric','symmetric','symmetric'},'uni',false);
end


function xferOrbits = getMultiFlybyXferOrbits(x, numRev, r1Sc, r2Sc, v1Sc, v2Sc, bodiesInfo, celBodyData)
%getMultiFlybyXferOrbits Summary of this function goes here
%   Detailed explanation goes here

%     [~, ~, secInDay, ~] = getSecondsInVariousTimeUnits();

    flybyBodies = bodiesInfo(2:end-1);
    numFB = length(flybyBodies);
    numBodies = length(bodiesInfo);
    numREVS = length(bodiesInfo) - 1;

    if(numFB == 0)
        tm = x(:,3);
        numRevInds = x(:,4);
    else
        tm = x(:,numBodies+1:numBodies+numREVS);
        numRevInds = x(:,numBodies+1+numREVS:end);
    end

    tm = round(tm);
    tm(tm==2) = -1;
    numTM = size(tm,2);

%     x = x(:,1:end-numTM);
%     daTimes = cumsum(x,2);
    x = x(:,1:end-numTM-numREVS);
    daTimes = cumsum(x,2);

    parentBodyInfo = bodiesInfo{1}.getParBodyInfo(celBodyData);
    gmu = parentBodyInfo.gm;

    xferOrbits = zeros(length(bodiesInfo)-1,10);
    for(i=1:length(bodiesInfo)-1) %#ok<*NO4LP>
        b1Info = bodiesInfo{i};
        b2Info = bodiesInfo{i+1};

        t1 = daTimes(i);
        t2 = daTimes(i+1);
        dt = t2 - t1;

        [r1, ~] = getStateAtTime(b1Info, t1, getParentGM(b1Info, celBodyData));
        [r2, ~] = getStateAtTime(b2Info, t2, getParentGM(b2Info, celBodyData));
        [v1, v2] = orbit.lambert(r1', r2', tm(i)*dt/86400, numRev(i), gmu);

        if(any(isnan(v1)) || any(isnan(v2))) %failsafe incase the solver does something dumb
            v1 = v1Sc(:,i)';
            v2 = v2Sc(:,i)';
        end

        [sma, ecc, inc, raan, arg, tru] = vect_getKeplerFromState(r1,v1',gmu);
        [~, ~, ~, ~, ~, tru2] = vect_getKeplerFromState(r2,v2',gmu);

        if(inc >= pi/2)
            [v1, v2] = orbit.lambert(r1', r2', -tm(i)*dt/86400, numRev(i), gmu);

            [sma, ecc, inc, raan, arg, tru] = vect_getKeplerFromState(r1,v1',gmu);
            [~, ~, ~, ~, ~, tru2] = vect_getKeplerFromState(r2,v2',gmu);
        end

        orbitData = [sma ecc inc raan arg tru tru2 t1 t2 gmu];
        xferOrbits(i,:) = orbitData;
    end
end


function layer = genNetworkIvectorMeanPool(inputDim, hiddenSize, outputDim, bottleneckLayerIdx, useMeanPool, useSigmoidBeforeMeanPool)
% inputDim = 440;
% hiddenSize = [2048 2048 400 2048];
% outputDim = 3000;
% bottleneckLayerIdx = 3;

layer{1}.name = 'Input';        % this is an input layer
layer{end}.inputIdx = 1;    % specifies the index of GCC in Visible_tr
layer{end}.dim = [1 1]*inputDim;             % [input dim; output dim];

for i=1:bottleneckLayerIdx
    layer{end+1}.name = 'Affine';
    layer{end}.prev = -1;   % this is the index of GCC features in Visible_tr; It is the offset to be added to current layer index
    layer{end}.W = []; % to be initialized randomly or by pretraining
    layer{end}.b = [];
    if i==1
        layer{end}.dim = [hiddenSize(i) inputDim];
    else
        layer{end}.dim = [hiddenSize(i) hiddenSize(i-1)];
    end
    layer{end}.update = 1;

    layer{end+1}.name = 'sigmoid';
    layer{end}.prev = -1;
    layer{end}.dim = [1 1]*hiddenSize(i);
end

if useMeanPool
    if useSigmoidBeforeMeanPool==0
        layer = layer(1:end-1);
    end
    layer{end+1}.name = 'mean';
    layer{end}.prev = -1;
end

for i=bottleneckLayerIdx+1:length(hiddenSize)
    layer{end+1}.name = 'Affine';
    layer{end}.prev = -1;   % this is the index of GCC features in Visible_tr; It is the offset to be added to current layer index
    layer{end}.W = []; % to be initialized randomly or by pretraining
    layer{end}.b = [];
    layer{end}.dim = [hiddenSize(i) hiddenSize(i-1)];
    layer{end}.update = 1;

    layer{end+1}.name = 'sigmoid';
    layer{end}.prev = -1;
    layer{end}.dim = [1 1]*hiddenSize(i);
end

layer{end+1}.name = 'Affine';
layer{end}.prev = -1;   % this is the index of GCC features in Visible_tr; It is the offset to be added to current layer index
layer{end}.W = []; % to be initialized randomly or by pretraining
layer{end}.b = [];
layer{end}.dim = [outputDim hiddenSize(end)];
layer{end}.update = 1;

layer{end+1}.name = 'Softmax';
layer{end}.prev = -1;
layer{end}.dim = [1 1]*outputDim;

layer{end+1}.name = 'Input';
layer{end}.inputIdx = 2;
layer{end}.dim = [1 1]*outputDim;

layer{end+1}.name = 'Cross_Entropy';
layer{end}.prev = [-2 -1];
layer{end}.dim = [1 outputDim];

% automatically derive the list of layers that the output of the current layer goes.
for i=1:length(layer); layer{i}.next = []; end
for i=length(layer):-1:1
        if isfield(layer{i}, 'prev')
                for j=1:length(layer{i}.prev)
                        layer{i+layer{i}.prev(j)}.next(end+1) = -layer{i}.prev(j);
                end
        end
end

end


function V = LP10cvx(K, P, model, epsilon)
% CPLEX implementation of LP-9 for input sets K, P (see FASTCORE paper)
%
% USAGE:
%
%    V = LP9cvx(K, P, model, epsilon)
%
% .. Authors: - Nikos Vlassis, Maria Pires Pacheco, Thomas Sauter, 2013 LCSB / LSRU, University of Luxembourg

scalingfactor = 1e3;

V = [];
if isempty(P) || isempty(K)
    return;
end

np = numel(P);
nk = numel(K);
n = size(model.S,2);

cvx_begin

  variable v(n);
  variable z(np);

  minimize( ones(1,np) * z );

  z>=0;
  v(P)>=-z;
  v(P)<=z;

  v(K)>=epsilon*scalingfactor;

  model.S*v==0;

  v>=model.lb*scalingfactor;
  v<=model.ub*scalingfactor;

cvx_end

V = v;


function line_enhanced = EnhanceLine(band)
%ENHANCELINE enhance NDBI to light urban/built-up areas and dark other
%bright surface, such as desert, rock. ref Guindon et. RSE 2004

% also can see the details at
% https://homepages.inf.ed.ac.uk/rbf/HIPR2/linedet.htm.
%     band=data_toabt.BandGreen;
%
%     band=ndbi;

%% line with a length of three pixels
%     template1=[-1 1 0;
%                -1 1 0;
%                -1 1 0;];
%     template2=[0 1 -1;
%                0 1 -1;
%                0 1 -1;];
%     line_enhanced1 = imfilter(band,template1);
%     line_enhanced2 = imfilter(band,template2);
%     line_enhanced=max(line_enhanced1,line_enhanced2);
%
%     template1=[-1 -1 -1;
%                 1  1  1;
%                 0  0  0;];
%     template2=[0  0  0;
%                1  1  1;
%               -1 -1 -1;];
%     line_enhanced1 = imfilter(band,template1);
%     line_enhanced2 = imfilter(band,template2);
%     line_enhanced=max(line_enhanced1,line_enhanced);
%     line_enhanced=max(line_enhanced2,line_enhanced);
%
%     template1=[1 -1 -1;
%                0  1 -1;
%                0  0  1;];
%     template2=[1  0  0;
%               -1  1  0;
%               -1 -1  1;];
%     line_enhanced1 = imfilter(band,template1);
%     line_enhanced2 = imfilter(band,template2);
%     line_enhanced=max(line_enhanced1,line_enhanced);
%     line_enhanced=max(line_enhanced2,line_enhanced);
%
%     template1=[-1 -1  1;
%                -1  1  0;
%                 1  0  0;];
%     template2=[0  0  1;
%                0  1 -1;
%                1 -1 -1;];
%
%     line_enhanced1 = imfilter(band,template1);
%     line_enhanced2 = imfilter(band,template2);
%     line_enhanced=max(line_enhanced1,line_enhanced);
%     line_enhanced=max(line_enhanced2,line_enhanced);
% 	line_enhanced = line_enhanced./3;

    template=[-1 2 -1;
              -1 2 -1;
              -1 2 -1;];
	template = template./6;
    line_enhanced = imfilter(band,template);

    template=[-1 -1 -1;
               2  2  2;
              -1 -1 -1;];
	template = template./6;
    line_enhanced_new = imfilter(band,template);
    line_enhanced=max(line_enhanced_new,line_enhanced);

    template =[2 -1 -1;
               -1  2 -1;
               -1  -1  2;];
	template = template./6;
    line_enhanced_new = imfilter(band,template);
    line_enhanced=max(line_enhanced_new,line_enhanced);

    template =[-1  -1  2;
               -1  2 -1;
               2 -1 -1;];
	template = template./6;
    line_enhanced_new = imfilter(band,template);
    line_enhanced=max(line_enhanced_new,line_enhanced);
end


function [hklGrid,wGrid,id] = gridify(hkl,varargin)
% approximate a list of Miller indices with Miller indices on a grid
%
% Syntax
%   [hklGrid, weightsG, id] = gridify(vec)
%   [hklGrid, weightsG, id] = gridify(vec,'weights',weights)
%
% Input
%  vec - @vector3d
%
% Output
%  hklGrid - @Miller
%  weightsG - double
%  id    -
%
% Options
%  weights    -
%  resolution -

sR = hkl.CS.fundamentalSector;
hkl = project2FundamentalRegion(hkl);

[hklGrid,wGrid,id] = gridify@vector3d(hkl,sR,varargin{:});

hklGrid = Miller(hklGrid,hkl.CS);


function [c, acc] = compute_confusion(numClasses, gts, preds, areas, doNotNormalizePerClass)
if ~exist('doNotNormalizePerClass')
  doNotNormalizePerClass = false ;
end
if nargin <= 3, areas = ones(size(gts)) ; end
c = accumarray([gts(:), preds(:)], areas(:), numClasses*[1,1]) ;
if ~doNotNormalizePerClass
  c = bsxfun(@times, 1./sum(c,2), c) ;
  acc = mean(diag(c)) ;
else
  c = c / sum(c(:)) ;
  acc = sum(diag(c)) ;
end


% Small technical example.
% Shows how to call for the multiresolution decomposition of an image
% and shows the detailed bookkeeping.
%
disp('Small technical example.');
disp('Shows how to call for the multiresolution decomposition of an image');
disp('and shows the detailed bookkeeping.');
disp('FOR MORE INFORMATION:  help QLiftDec2');
disp(' ');
disp('See also the report http://repository.cwi.nl:8888/cwi_repository/docs/IV/04/04178D.pdf');
disp('Dr. Paul M. de Zeeuw <Paul.de.Zeeuw@cwi.nl>');
disp(' (C) 1998-2006 Stichting CWI, Amsterdam, The Netherlands');
disp(' ');
%---PARAMETERS-----------------------------------------------------------------
% How to execute, set parameters
N = 6;                   %  maximum level (even number) in lifting scheme
filtername = 'Neville4';
%
%---INSERT YOUR IMAGE HERE-----------------------------------------------------
if exist('imread','file') == 2
  Orig = double(imread('zenithgray.TIF','tiff'));
else
  load zenithgray; Orig = zenithgray; clear zenithgray;
end
%
disp([' Dimensions of original      ' int2str( size(Orig) )]);
%---DECOMPOSITION--------------------------------------------------------------
disp([' Filter type is ' filtername]);
[C,S] = QLiftDec2(Orig,N,filtername);
disp([' Dimensions of decomposition ' int2str( size(C) )]);
disp(' Contents of bookkeeping ');
disp(int2str(S));
%