function F = D2GaussFunctionRot(x,xdata)
%% x = [Amp, x0, wx, y0, wy, fi]
%[X,Y] = meshgrid(x,y)
%  xdata(:,:,1) = X
%  xdata(:,:,2) = Y
% Mrot = [cos(fi) -sin(fi); sin(fi) cos(fi)]
%%
xdatarot(:,:,1)= xdata(:,:,1)*cos(x(6)) - xdata(:,:,2)*sin(x(6));
xdatarot(:,:,2)= xdata(:,:,1)*sin(x(6)) + xdata(:,:,2)*cos(x(6));
x0rot = x(2)*cos(x(6)) - x(4)*sin(x(6));
y0rot = x(2)*sin(x(6)) + x(4)*cos(x(6));

F = x(1)*exp(   -((xdatarot(:,:,1)-x0rot).^2/(2*x(3)^2) + (xdatarot(:,:,2)-y0rot).^2/(2*x(5)^2) )    );

% figure(3)
% alpha(0)
% imagesc(F)
% colormap('gray')
% figure(gcf)%bring current figure to front
% drawnow
% beep
% pause %Wait for keystroke


function [VAD, logVAD]= apply_VAD( data, Nsamples)

global Downsample MINSPEECHLGTH JOINSPEECHLGTH

Nwindows= floor( Nsamples/ Downsample);
%number of 4ms window

VAD= zeros( 1, Nwindows);
for count= 1: Nwindows
    VAD( count)= sum( data( (count-1)* Downsample+ 1: ...
        count* Downsample).^ 2)/ Downsample;
end
%VAD is the power of each 4ms window

LevelThresh = sum( VAD)/ Nwindows;
%LevelThresh is set to mean value of VAD

LevelMin= max( VAD);
if( LevelMin > 0 )
    LevelMin= LevelMin* 1.0e-4;
else
    LevelMin = 1.0;
end
%fprintf( 1, 'LevelMin is %f\n', LevelMin);

VAD( find( VAD< LevelMin))= LevelMin;

for iteration= 1: 12
    LevelNoise= 0;
    len= 0;
    StDNoise= 0;

    VAD_lessthan_LevelThresh= VAD( find( VAD<= LevelThresh));
    len= length( VAD_lessthan_LevelThresh);
    LevelNoise= sum( VAD_lessthan_LevelThresh);
    if (len> 0)
        LevelNoise= LevelNoise/ len;
        StDNoise= sqrt( sum( ...
        (VAD_lessthan_LevelThresh- LevelNoise).^ 2)/ len);
    end
    LevelThresh= 1.001* (LevelNoise+ 2* StDNoise);
end
%fprintf( 1, 'LevelThresh is %f\n', LevelThresh);

LevelNoise= 0;
LevelSig= 0;
len= 0;
VAD_greaterthan_LevelThresh= VAD( find( VAD> LevelThresh));
len= length( VAD_greaterthan_LevelThresh);
LevelSig= sum( VAD_greaterthan_LevelThresh);

VAD_lessorequal_LevelThresh= VAD( find( VAD<= LevelThresh));
LevelNoise= sum( VAD_lessorequal_LevelThresh);

if (len> 0)
    LevelSig= LevelSig/ len;
else
    LevelThresh= -1;
end
%fprintf( 1, 'LevelSig is %f\n', LevelSig);

if (len< Nwindows)
    LevelNoise= LevelNoise/( Nwindows- len);
else
    LevelNoise= 1;
end
%fprintf( 1, 'LevelNoise is %f\n', LevelNoise);

VAD( find( VAD<= LevelThresh))= -VAD( find( VAD<= LevelThresh));
VAD(1)= -LevelMin;
VAD(Nwindows)= -LevelMin;

start= 0;
finish= 0;
for count= 2: Nwindows
    if( (VAD(count) > 0.0) && (VAD(count-1) <= 0.0) )
        start = count;
    end
    if( (VAD(count) <= 0.0) && (VAD(count-1) > 0.0) )
        finish = count;
        if( (finish - start)<= MINSPEECHLGTH )
            VAD( start: finish- 1)= -VAD( start: finish- 1);
        end
    end
end
%to make sure finish- start is more than 4

if( LevelSig >= (LevelNoise* 1000) )
    for count= 2: Nwindows
        if( (VAD(count)> 0) && (VAD(count-1)<= 0) )
            start= count;
        end
        if( (VAD(count)<= 0) && (VAD(count-1)> 0) )
            finish = count;
            g = sum( VAD( start: finish- 1));
            if( g< 3.0* LevelThresh* (finish - start) )
                VAD( start: finish- 1)= -VAD( start: finish- 1);
            end
        end
    end
end

start = 0;
finish = 0;
for count= 2: Nwindows
    if( (VAD(count) > 0.0) && (VAD(count-1) <= 0.0) )
        start = count;
        if( (finish > 0) && ((start - finish) <= JOINSPEECHLGTH) )
            VAD( finish: start- 1)= LevelMin;
        end
    end
    if( (VAD(count) <= 0.0) && (VAD(count-1) > 0.0) )
        finish = count;
    end
end

start= 0;
for count= 2: Nwindows
    if( (VAD(count)> 0) && (VAD(count-1)<= 0) )
        start= count;
    end
end
if( start== 0 )
    VAD= abs(VAD);
    VAD(1) = -LevelMin;
    VAD(Nwindows) = -LevelMin;
end

count = 4;
while( count< (Nwindows-1) )
    if( (VAD(count)> 0) && (VAD(count-2) <= 0) )
        VAD(count-2)= VAD(count)* 0.1;
        VAD(count-1)= VAD(count)* 0.3;
        count= count+ 1;
    end
    if( (VAD(count)<= 0) && (VAD(count-1)> 0) )
        VAD(count)= VAD(count-1)* 0.3;
        VAD(count+ 1)= VAD(count-1)* 0.1;
        count= count+ 3;
    end
    count= count+ 1;
end

VAD( find( VAD< 0))= 0;

% fid= fopen( 'mat_vad.txt', 'wt');
% fprintf( fid, '%f\n', VAD);
% fclose( fid);

if( LevelThresh<= 0 )
    LevelThresh= LevelMin;
end

logVAD( find( VAD<= LevelThresh))= 0;
VAD_greaterthan_LevelThresh= find( VAD> LevelThresh);
logVAD( VAD_greaterthan_LevelThresh)= log( VAD( ...
    VAD_greaterthan_LevelThresh)/ LevelThresh);


%==============================================================================
% This code is part of the Finite Element Method app for the Matlab-based toolbox
%  FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR/FAIRFEM
%==============================================================================
%
% function [Dx1,Dx2,Dx3] = getGradientMatrixFEM(Mesh)
%
% builds gradient operator for tetrahedral finite element discretization
% with piecewise linear basis functions
%
% Input:
%
% Mesh          - description of mesh, struct
%
% Output:
%
% [Dx1,Dx2,Dx3] - discrete partial derivative operators
%
%==============================================================================

function [Dx1,Dx2,Dx3] = getGradientMatrixFEM(Mesh,matrixFree)
if nargin==0, help(mfilename); runMinimalExample; return; end;

if not(exist('matrixFree','var'))||isempty(matrixFree),
    matrixFree=0;
end

Dx3 = [];

xn  = Mesh.xn;
vol = Mesh.vol;
dim = Mesh.dim;

flag = [num2str(dim) 'D'];
if matrixFree
    flag = [flag '-mf'];
else
    flag = [flag '-mb'];
end

switch flag
    case '2D-mb'
        % compute edges
        e1 =  Mesh.P1*xn - Mesh.P3*xn;
        e2 =  Mesh.P2*xn - Mesh.P3*xn;
        % compute gradients of basis functions
        dphi1 =   [ e2(:,2) -e2(:,1)]./[2*vol,2*vol];
        dphi2 =   [-e1(:,2)  e1(:,1)]./[2*vol,2*vol];
        dphi3 = -dphi1-dphi2;

        Dx1 = sdiag(dphi1(:,1))*Mesh.P1 +  sdiag(dphi2(:,1))*Mesh.P2  + sdiag(dphi3(:,1))*Mesh.P3;
        Dx2 = sdiag(dphi1(:,2))*Mesh.P1 +  sdiag(dphi2(:,2))*Mesh.P2  + sdiag(dphi3(:,2))*Mesh.P3;

        if nargout==1, % return gradient operator for vector field
            B = [Dx1;Dx2];
            Dx1 = blkdiag(B,B);
        end

    case '2D-mf'
        % compute edges
        x1 =  Mesh.mfPi(xn,1);
        x2 =  Mesh.mfPi(xn,2);
        x3 =  Mesh.mfPi(xn,3);
        e1 =  x1 - x3;
        e2 =  x2 - x3;

        % compute gradients of basis functions
        dphi1 =   [ e2(:,2) -e2(:,1)]./[2*vol,2*vol];
        dphi2 =   [-e1(:,2)  e1(:,1)]./[2*vol,2*vol];
        dphi3 = -dphi1 - dphi2;

        Dxi    = @(x,i)   dphi1(:,i).*Mesh.mfPi(x,1) ...
                        + dphi2(:,i).*Mesh.mfPi(x,2) ...
                        + dphi3(:,i).*Mesh.mfPi(x,3);

        Dxiadj = @(x,i)   Mesh.mfPi(dphi1(:,i).*x,1) ....
                        + Mesh.mfPi(dphi2(:,i).*x,2) ...
                        + Mesh.mfPi(dphi3(:,i).*x,3);
        if nargout==1
            % matrix free mode, return D*xc and operators
            Dx1.D    = @(x) getGradientMF(x,Dxi,dim,'Du');
            Dx1.Dadj = @(x) getGradientMF(x,Dxiadj,dim,'DTu');
        else
            Dx1.D    = @(x) Dxi(x,1);
            Dx1.Dadj = @(x) Dxiadj(x,1);
            Dx2.D    = @(x) Dxi(x,2);
            Dx2.Dadj = @(x) Dxiadj(x,2);
        end
    case '3D-mf'
        % compute edges
        v1   = Mesh.mfPi(xn,1);
        v2   = Mesh.mfPi(xn,2);
        v3   = Mesh.mfPi(xn,3);
        v4   = Mesh.mfPi(xn,4);
        e1   =  v1 - v4;
        e2   =  v2 - v4;
        e3   =  v3 - v4;
        % compute inverse transformation to reference element
        cofA =  [
              e2(:,2).*e3(:,3)-e2(:,3).*e3(:,2), ...
            -(e1(:,2).*e3(:,3)-e1(:,3).*e3(:,2)), ...
              e1(:,2).*e2(:,3)-e1(:,3).*e2(:,2), ...
            -(e2(:,1).*e3(:,3)-e2(:,3).*e3(:,1)), ...
              e1(:,1).*e3(:,3)-e1(:,3).*e3(:,1), ...
            -(e1(:,1).*e2(:,3)-e1(:,3).*e2(:,1)), ...
              e2(:,1).*e3(:,2)-e2(:,2).*e3(:,1), ...
            -(e1(:,1).*e3(:,2)-e1(:,2).*e3(:,1)), ...
              e1(:,1).*e2(:,2)-e1(:,2).*e2(:,1), ...
            ];
        detA = e1(:,1).*cofA(:,1) + e2(:,1).*cofA(:,2)+ e3(:,1).*cofA(:,3);

        % compute gradients of basis functions
         dphi1 =   cofA(:,[1 4 7])./repmat(detA,[1 3]);
        dphi2 =   cofA(:,[2 5 8])./repmat(detA,[1 3]);
        dphi3 =   cofA(:,[3 6 9])./repmat(detA,[1 3]);
       dphi4 =   -dphi1 - dphi2 - dphi3;

        Dxi    = @(x,i) dphi1(:,i).*Mesh.mfPi(x,1) + dphi2(:,i).*Mesh.mfPi(x,2) ...
            + dphi3(:,i).*Mesh.mfPi(x,3) + dphi4(:,i).*Mesh.mfPi(x,4);
        Dxiadj = @(x,i) Mesh.mfPi(dphi1(:,i).*x,1) + Mesh.mfPi(dphi2(:,i).*x,2) ...
            + Mesh.mfPi(dphi3(:,i).*x,3) + Mesh.mfPi(dphi4(:,i).*x,4);

        if nargout==1
            % matrix free mode, return D*xc and operators
            Dx1.D    = @(x) getGradientMF(x,Dxi,dim,'Du');
            Dx1.Dadj = @(x) getGradientMF(x,Dxiadj,dim,'DTu');
        else
            Dx1.D    = @(x) Dxi(x,1);
            Dx1.Dadj = @(x) Dxiadj(x,1);
            Dx2.D    = @(x) Dxi(x,2);
            Dx2.Dadj = @(x) Dxiadj(x,2);
            Dx3.D    = @(x) Dxi(x,3);
            Dx3.Dadj = @(x) Dxiadj(x,3);
        end

    case '3D-mb'
        % compute edges
        e1   =  Mesh.P1*xn - Mesh.P4*xn;
        e2   =  Mesh.P2*xn - Mesh.P4*xn;
        e3   =  Mesh.P3*xn - Mesh.P4*xn;
        % compute inverse transformation to reference element
        cofA =  [
            e2(:,2).*e3(:,3)-e2(:,3).*e3(:,2), ...
            -(e1(:,2).*e3(:,3)-e1(:,3).*e3(:,2)), ...
            e1(:,2).*e2(:,3)-e1(:,3).*e2(:,2), ...
            -(e2(:,1).*e3(:,3)-e2(:,3).*e3(:,1)), ...
            e1(:,1).*e3(:,3)-e1(:,3).*e3(:,1), ...
            -(e1(:,1).*e2(:,3)-e1(:,3).*e2(:,1)), ...
            e2(:,1).*e3(:,2)-e2(:,2).*e3(:,1), ...
            -(e1(:,1).*e3(:,2)-e1(:,2).*e3(:,1)), ...
            e1(:,1).*e2(:,2)-e1(:,2).*e2(:,1), ...
            ];
        detA = e1(:,1).*cofA(:,1) + e2(:,1).*cofA(:,2)+ e3(:,1).*cofA(:,3);

        % compute gradients of basis functions
        dphi1 =   cofA(:,[1 4 7])./repmat(detA,[1 3]);
        dphi2 =   cofA(:,[2 5 8])./repmat(detA,[1 3]);
        dphi3 =   cofA(:,[3 6 9])./repmat(detA,[1 3]);
        dphi4 =   - dphi1 - dphi2 - dphi3;

        Dxi = @(i) sdiag(dphi1(:,i))*Mesh.P1 +  sdiag(dphi2(:,i))*Mesh.P2  ...
            + sdiag(dphi3(:,i))*Mesh.P3 +  sdiag(dphi4(:,i))*Mesh.P4;

        Dx1 = Dxi(1); Dx2 = Dxi(2); Dx3 = Dxi(3);

        if nargout==1, % return gradient operator for vector field
            B = [Dx1;Dx2;Dx3];
            Dx1 = blkdiag(B,B,B);
        end

    otherwise
        error('unknown flag: %s',flag);
end

function Du = getGradientMF(x,Dxi,dim,flag)
flag = [num2str(dim) 'D-' flag];
switch flag
    case '2D-Du'
        x = reshape(x,[],dim);
        Du  = [  Dxi(x(:,1),1);  Dxi(x(:,1),2);  Dxi(x(:,2),1);  Dxi(x(:,2),2); ];
    case '2D-DTu'
        x = reshape(x,[],4);
        Du  =  [Dxi(x(:,1),1)+Dxi(x(:,2),2); Dxi(x(:,3),1)+Dxi(x(:,4),2)];
    case '3D-Du'
        x = reshape(x,[],dim);
        Du  = [
                Dxi(x(:,1),1);  Dxi(x(:,1),2);  Dxi(x(:,1),3);...
                Dxi(x(:,2),1);  Dxi(x(:,2),2);  Dxi(x(:,2),3);...
                Dxi(x(:,3),1);  Dxi(x(:,3),2);  Dxi(x(:,3),3);...
               ];
    case '3D-DTu'
        x = reshape(x,[],9);
        Du  =  [
                    Dxi(x(:,1),1)+Dxi(x(:,2),2)+Dxi(x(:,3),3);...
                    Dxi(x(:,4),1)+Dxi(x(:,5),2)+Dxi(x(:,6),3);...
                    Dxi(x(:,7),1)+Dxi(x(:,8),2)+Dxi(x(:,9),3);...
                ];
    otherwise
        error('nyi');
end

% shortcut for sparse diagonal matrices
function D = sdiag(v)
D = spdiags(v(:),0,numel(v),numel(v));

function runMinimalExample
omega = [0 1 0 3]; m = [ 3 5];
Mesh = TriMesh1(omega,m);
xn = Mesh.xn + 6*1e-2 * randn(size(Mesh.xn));

D = feval(mfilename,Mesh,0);

figure(1); clf;
subplot(1,3,1);
triplot(Mesh.tri,xn(:,1),xn(:,2)); axis(omega); hold on;
plot(xn(:,1),xn(:,2),'or');
title('discretization');
subplot(1,3,2); spy(D);
title('gradient operator B');
subplot(1,3,3); spy(D'*D);
title('Laplace operator B''*B');

Dmf = feval(mfilename,Mesh,1);

err1 = norm(D*xn(:)-Dmf.D(xn))/norm(D*xn(:));
x = randn(size(xn)); y=randn(4*size(Mesh.tri,1),1);
err2 = abs(x(:)'*Dmf.Dadj(y)-y(:)'*Dmf.D(x));
fprintf('MFerror: %1.3e;  AdjointError: %1.3e OK? %d\n',err1,err2,max(err1,err2)<1e-12);
%========= 3D ==========
omega = [0 1 0 3 0 3]; m = [ 3 5 4];
Mesh = getTriangleMesh(omega,m,'matrixFree',0);
xn = Mesh.xn + 6*1e-2 * randn(size(Mesh.xn));

D = feval(mfilename,Mesh);

figure(1); clf;
subplot(1,3,1);
tetramesh(Mesh.tri,Mesh.xn,'FaceAlpha',.3); hold on;
plot3(xn(:,1),xn(:,2),xn(:,3),'or');
title('discretization');
subplot(1,3,2); spy(D);
title('gradient operator B');
subplot(1,3,3); spy(D'*D);
title('Laplace operator B''*B');

MeshMF = getTriangleMesh(omega,m,'matrixFree',1);
Dmf = feval(mfilename,MeshMF);

err1 = norm(D*xn(:)-Dmf.D(xn))/norm(D*xn(:));
x = randn(size(xn)); y=randn(9*size(Mesh.tri,1),1);
err2 = abs(x(:)'*Dmf.Dadj(y)-y(:)'*Dmf.D(x));
fprintf('MFerror: %1.3e AdjointError: %1.3e OK? %d\n',err1,err2,max(err1,err2)<1e-12);


function y = tdist_unnorm(x, p, type)
%TDIST_UNNORM   Unnormalized t-distribution robust function.
%   TDIST_UNNORM(X, P, TYPE) evaluates the unnormalize t-distribution
%   robust function with parameters P at point(s) X.  P(1) corresponds to
%   the exponent alpha; P(2) corresponds to the scaling sigma.
%   TYPE selects the evaluation type:
%    - 0: function value
%    - 1: first derivative
%    - 2: second derivative
%
%   This is a private member function of the class 'robust_function'.
%
%   Author:  Stefan Roth, Department of Computer Science, TU Darmstadt
%   Contact: sroth@cs.tu-darmstadt.de
%   $Date:  $
%   $Revision: $

% Copyright 2004-2007, Brown University, Providence, RI. USA
% Copyright 2007-2010 TU Darmstadt, Darmstadt, Germany.
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

  r = p(1);
  s = p(2);

  switch (type)
   case 0
    y = r * log(1 + 0.5 * (x / s).^2);
   case 1
    y = r * x ./ (s^2 * (1 + 0.5 * (x / s).^2));
   case 2
    y = r ./ (s^2 * (1 + 0.5 * (x / s).^2));
  end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Y = OneLayerAGH_Test(X, Anchor, W, s, sigma, options)
%
% One-Layer Anchor Graph Hashing Test
% Written by Wei Liu (wliu@ee.columbia.edu)
% X = nXdim input data
% Anchor = mXdim anchor points (m<<n)
% W = mXr projection matrix in spectral space
% s = number of nearest anchors
% sigma: Gaussian RBF kernel width parameter
% Y = nXr binary codes (Y_ij in {1,0})
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[n,dim] = size(X);
m = size(Anchor,1);

%% get Z
Z = zeros(n,m);
Dis = sqdist(X',Anchor');
%clear X;
%clear Anchor;

val = zeros(n,s);
pos = val;
for i = 1:s
    [val(:,i),pos(:,i)] = min(Dis,[],2);
    tep = (pos(:,i)-1)*n+[1:n]';
    Dis(tep) = 1e60;
end
clear Dis;
clear tep;

switch lower(options.CodingMethod)
    case {lower('Cosine')}
        if isfield(options,'bNormalized') && options.bNormalized
        else
            X = NormalizeFea(X);
        end
        Anchor = NormalizeFea(Anchor);
        S = full(X*Anchor');
        linidx = [1:size(pos,1)]';
        val = S(sub2ind(size(S),linidx(:,ones(1,size(pos,2))),pos));
    case {lower('Gaussian')}
        val = exp(-val/(1/1*sigma^2));
    otherwise
        error('method does not exist!');
end

val = repmat(sum(val,2).^-1,1,s).*val; %% normalize
tep = (pos-1)*n+repmat([1:n]',1,s);
Z([tep]) = [val];
Z = sparse(Z);
clear tep;
clear val;
clear pos;

%% get binary codes
Y = (Z*W>0);  %% logical format
clear Z;


function legendre_function_q_test ( )

%*****************************************************************************80
%
%% LEGENDRE_FUNCTION_Q_TEST tests LEGENDRE_FUNCTION_Q.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 October 2008
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LEGENDRE_FUNCTION_Q_TEST:\n' );
  fprintf ( 1, '  LEGENDRE_FUNCTION_Q evaluates the Legendre Q function.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '     N      X        Exact F       Q(N)(X)\n' );
  fprintf ( 1, '\n' );

  n_data = 0;

  while ( 1 )

    [ n_data, n, x, fx ] = legendre_function_q_values ( n_data );

    if ( n_data == 0 )
      break
    end

    fx2 = legendre_function_q ( n, x );

    fprintf ( 1, '  %6d  %6f  %12f  %12f\n', n, x, fx, fx2(n+1) );

  end

  return
end


function p00_tan_test ( problem_num )

%*****************************************************************************80
%
%% P00_TAN_TEST computes and tests the tangent vector.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM_NUM, the number of problems.
%
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'P00_TAN_TEST\n' );
  fprintf ( 1, '  Compute the tangent vector TAN(X) at the starting point.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Verify that JAC(X) * TAN(X) = 0.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Verify that det ( JAC ) > 0\n' );
  fprintf ( 1, '                  ( TAN )    \n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   Problem    Option    ||Jac*Tan||     det(Jac|Tan)\n' );

  for problem = 1 : problem_num

    option_num = p00_option_num ( problem );

    fprintf ( 1, '\n' );

    for option = 1 : option_num

      nvar = p00_nvar ( problem, option );

      x0 = p00_start ( problem, option, nvar );

      jac = p00_jac ( problem, option, nvar, x0 );

      tan = p00_tan ( problem, option, nvar, x0 );

      jt = jac * tan;
      jtn = norm ( jt );

      jac(nvar,1:nvar) = tan(1:nvar);
      jtd = det ( jac );

      fprintf ( 1, '  %8d  %8d  %14e  %14e\n', problem, option, jtn, jtd );

    end
  end

  return
end


%  Figure 3.18      Feedback Control of Dynamic Systems, 5e
%                        Franklin, Powell, Emami
%script to generate Fig. 3.18
%% fig3_18.m
clf;
num=[1];          % form transfer function
den=[1 2*.2 1];
t=0:.01:30;       % define time vector
sys=tf(num,den);  % define system
y=impulse(sys,t); % compute impulse response
plot(t,y)
hold on
% compute e^(-.2t)
ne=1;
de=[1 .2];
syse=tf(ne,de);
ye=impulse(syse,t);
plot(t,ye,':r')
plot(t,-ye,':r'), grid
axis([0 30 -1 1])
hold off
title('Figure 3.18')
xlabel('Time (sec)')
ylabel('h(t)')
text(7,.3,'e^{-\sigma t}');
text(7,-.3,'-e^{-\sigma t}');


function [ps,params] = fused_sigmoid(w,input_data)
%
% Algorithm: ps = sigmoid( alpha'*input_data +beta)
%
%
% Inputs:
%  w: is [alpha; beta], where alpha is D-by-1 and beta is scalar.
%     Use w=[] to let output ps be an MV2DF function handle.
%     If w is a function handle to an MV2DF then ps is the function handle
%     to the composition of w and this function.
%
%  input_data: D-by-T matrix
%
%
% Outputs:
%   ps: function handle (if w=[], or w is handle), or numeric T-by-1
%   params.get_w0(ssat): returns w0 for optimization initialization,
%                        0<ssat<1 is required average sigmoid output.
%   params.tail: is tail of parameter w, which is not consumed by this
%                function.

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

[dim,n] = size(input_data);
wsz = dim+1;
[whead,wtail] = splitvec_fh(wsz,w);
params.get_w0 = @(ssat) init_w0(ssat,dim);
params.tail = wtail;

y = fusion_mv2df(whead,input_data);
ps = sigmoid_mv2df(y);

    function w0 = init_w0(ssat,dim)
    alpha = zeros(dim,1);
    beta = logit(ssat);
    w0 = [alpha;beta];
    end

end

function test_this()

K = 5;
T = 10;
data = randn(K,T);

ssat = 0.99;
[sys,params] = fused_sigmoid([],data);

w0 = params.get_w0(ssat);
test_MV2DF(sys,w0);

ps = fused_sigmoid(w0,data),

end


% Zero-crossing Frequency Estimation
%
% Estimates the instantaneous frequency of the input signal using the
% zero-crossing instantaneous frequency estimation algorithm.
%
%
% Usage:
%
%     ife = zce( signal, window_length )
%
% Parameters:
%
%
%    signal
%
%	  Input one dimensional signal to be analysed.
%
%    window_length
%
%	  Moving window to count the average number of zero crossings each
%	  time it moves.
%
%
% TFSAP 7.0
% Copyright Prof. B. Boashash
% Qatar University, Doha
% email: tfsap.research@gmail.com


function [dz,vdz,Adz]=two_group_test_coherence(J1c1,J2c1,J1c2,J2c2,p,plt,f)
% function [dz,vdz,Adz]=two_group_test_coherence(J1c1,J2c1,J1c2,J2c2,p,plt,f)
% Test the null hypothesis (H0) that data sets J1c1,J2c1,J1c2,J2c2 in
% two conditions c1,c2 have equal population coherence
%
% Usage:
% [dz,vdz,Adz]=two_sample_test_coherence(J1c1,J2c1,J1c2,J2c2,p)
%
% Inputs:
% J1c1   tapered fourier transform of dataset 1 in condition 1
% J2c1   tapered fourier transform of dataset 1 in condition 1
% J1c2   tapered fourier transform of dataset 1 in condition 2
% J2c2   tapered fourier transform of dataset 1 in condition 2
% p      p value for test (default: 0.05)
% plt    'y' for plot and 'n' for no plot
% f      frequencies (useful for plotting)
%
%
% Dimensions: J1c1,J2c2: frequencies x number of samples in condition 1
%              J1c2,J2c2: frequencies x number of samples in condition 2
%              number of samples = number of trials x number of tapers
% Outputs:
% dz    test statistic (will be distributed as N(0,1) under H0
% vdz   Arvesen estimate of the variance of dz
% Adz   1/0 for accept/reject null hypothesis of equal population
%       coherences based dz ~ N(0,1)
%
% Note: all outputs are functions of frequency
%
% References: Arvesen, Jackkknifing U-statistics, Annals of Mathematical
% Statisitics, vol 40, no. 6, pg 2076-2100 (1969)

if nargin < 4; error('Need four sets of Fourier transforms'); end;
if nargin < 6 || isempty(plt); plt='n'; end;

%
% Test for matching dimensionalities
%
if size(J1c1)~=size(J2c1) | size(J1c2)~=size(J2c2) | size(J1c1,1)~=size(J1c2,1);
    error('Need matching dimensionalities for the Fourier transforms: Check the help file for correct dimensionalities');
else;
    m1=size(J1c1,2); % number of samples, condition 1
    m2=size(J1c2,2); % number of samples, condition 2
    dof1=2*m1; % number of degrees of freedom in the first condition estimates
    dof2=2*m2; % number of degrees of freedom in the second condition estimates
end;
if nargin < 7 || isempty(f); f=size(J1c1,1); end;
if nargin < 5 || isempty(p); p=0.05; end; % set the default p value

%
% Compute the individual condition spectra, coherences
%
S12c1=conj(J1c1).*J2c1; % individual sample cross-spectrum, condition 1
S12c2=conj(J1c2).*J2c2; % individual sample cross-spectrum, condition 2
S1c1=conj(J1c1).*J1c1; % individual sample spectrum, data 1, condition 1
S2c1=conj(J2c1).*J2c1; % individual sample spectrum, data 2, condition 1
S1c2=conj(J1c2).*J1c2; % individual sample spectrum, data 1, condition 2
S2c2=conj(J2c2).*J2c2; % individual sample spectrum, data 2, condition 2

Sm12c1=squeeze(mean(S12c1,2)); % mean cross spectrum, condition 1
Sm12c2=squeeze(mean(S12c2,2)); % mean cross spectrum, condition 2
Sm1c1=squeeze(mean(S1c1,2)); % mean spectrum, data 1, condition 1
Sm2c1=squeeze(mean(S2c1,2)); % mean spectrum, data 2, condition 1
Sm1c2=squeeze(mean(S1c2,2)); % mean spectrum, data 1, condition 1
Sm2c2=squeeze(mean(S2c2,2)); % mean spectrum, data 2, condition 1

Cm12c1=abs(Sm12c1./sqrt(Sm1c1.*Sm2c1)); % mean coherence, condition 1
Cm12c2=abs(Sm12c2./sqrt(Sm1c2.*Sm2c2)); % mean coherence, condition 2

Ccm12c1=Cm12c1; % mean coherence saved for output
Ccm12c2=Cm12c2; % mean coherence saved for output
%
% Compute the statistic dz, and the probability of observing the value dz
% given an N(0,1) distribution i.e. under the null hypothesis
%
z1=atanh(Cm12c1)-1/(dof1-2); % Bias-corrected Fisher z, condition 1
z2=atanh(Cm12c2)-1/(dof2-2); % Bias-corrected Fisher z, condition 2
dz=(z1-z2)/sqrt(1/(dof1-2)+1/(dof2-2)); % z statistic
%
% The remaining portion of the program computes Jackknife estimates of the mean (mdz) and variance (vdz) of dz
%
samples1=[1:m1];
samples2=[1:m2];
%
% Leave one out of one sample
%
for i=1:m1;
    ikeep=setdiff(samples1,i); % all samples except i
    Sm12c1=squeeze(mean(S12c1(:,ikeep),2)); % 1 drop mean cross-spectrum, condition 1
    Sm1c1=squeeze(mean(S1c1(:,ikeep),2)); % 1 drop mean spectrum, data 1, condition 1
    Sm2c1=squeeze(mean(S2c1(:,ikeep),2)); % 1 drop mean spectrum, data 2, condition 1
    Cm12c1(:,i)=abs(Sm12c1./sqrt(Sm1c1.*Sm2c1)); % 1 drop coherence, condition 1
    z1i(:,i)=atanh(Cm12c1(:,i))-1/(dof1-4); % 1 drop, bias-corrected Fisher z, condition 1
    dz1i(:,i)=(z1i(:,i)-z2)/sqrt(1/(dof1-4)+1/(dof2-2)); % 1 drop, z statistic, condition 1
    ps1(:,i)=m1*dz-(m1-1)*dz1i(:,i);
%      ps1(:,i)=dof1*dz-(dof1-2)*dz1i(:,i);
end;
ps1m=mean(ps1,2);
for j=1:m2;
    jkeep=setdiff(samples2,j); % all samples except j
    Sm12c2=squeeze(mean(S12c2(:,jkeep),2)); % 1 drop mean cross-spectrum, condition 2
    Sm1c2=squeeze(mean(S1c2(:,jkeep),2)); % 1 drop mean spectrum, data 1, condition 2
    Sm2c2=squeeze(mean(S2c2(:,jkeep),2)); % 1 drop mean spectrum, data 2, condition 2
    Cm12c2(:,j)=abs(Sm12c2./sqrt(Sm1c2.*Sm2c2)); % 1 drop coherence, condition 2
    z2j(:,j)=atanh(Cm12c2(:,j))-1/(dof2-4); % 1 drop, bias-corrected Fisher z, condition 2
    dz2j(:,j)=(z1-z2j(:,j))/sqrt(1/(dof1-2)+1/(dof2-4)); % 1 drop, z statistic, condition 2
    ps2(:,j)=m2*dz-(m2-1)*dz2j(:,j);
%      ps2(:,j)=dof2*dz-(dof2-2)*dz2j(:,j);
end;

%
% Leave one out, both samples
% and pseudo values
% for i=1:m1;
%     for j=1:m2;
%         dzij(:,i,j)=(z1i(:,i)-z2j(:,j))/sqrt(1/(dof1-4)+1/(dof2-4));
%         dzpseudoval(:,i,j)=m1*m2*dz-(m1-1)*m2*dz1i(:,i)-m1*(m2-1)*dz2j(:,j)+(m1-1)*(m2-1)*dzij(:,i,j);
% %         dzpseudoval(:,i,j)=dof1*dof2*dz-(dof1-2)*dof2*dz1i(:,i)-dof1*(dof2-2)*dz2j(:,j)+(dof1-2)*(dof2-2)*dzij(:,i,j);
%     end;
% end;
% dzah=sum(sum(dzpseudoval,3),2)/(m1*m2);
ps2m=mean(ps2,2);
% dzar=(sum(ps1,2)+sum(ps2,2))/(m1+m2);
vdz=sum((ps1-ps1m(:,ones(1,m1))).*(ps1-ps1m(:,ones(1,m1))),2)/(m1*(m1-1))+sum((ps2-ps2m(:,ones(1,m2))).*(ps2-ps2m(:,ones(1,m2))),2)/(m2*(m2-1));
% vdzah=sum(sum((dzpseudoval-dzah(:,ones(1,m1),ones(1,m2))).*(dzpseudoval-dzah(:,ones(1,m1),ones(1,m2))),3),2)/(m1*m2);
%
% Test whether H0 is accepted at the specified p value
%
Adz=zeros(size(dz));
x=norminv([p/2 1-p/2],0,1);
indx=find(dz>=x(1) & dz<=x(2));
Adz(indx)=1;

if strcmp(plt,'y');
    if isempty(f) || nargin < 6;
        f=linspace(0,1,length(dz));
    end;
    %
    % Compute the coherences
    %
    S121=mean(conj(J1c1).*J2c1,2);
    S122=mean(conj(J1c2).*J2c2,2);
    S111=mean(conj(J1c1).*J1c1,2);
    S221=mean(conj(J2c1).*J2c1,2);
    S112=mean(conj(J1c2).*J1c2,2);
    S222=mean(conj(J2c2).*J2c2,2);
    C121=abs(S121)./sqrt(S111.*S221);
    C122=abs(S122)./sqrt(S112.*S222);
    %
    % Plot the coherence
    %
    subplot(311);
    plot(f,C121,f,C122); legend('Data 1','Data 2');
    set(gca,'FontName','Times New Roman','Fontsize', 16);
    ylabel('Coherence');
    title('Two group test for coherence');
    subplot(312);
    plot(f,dz);
    set(gca,'FontName','Times New Roman','Fontsize', 16);
    ylabel('Test statistic');
    conf=norminv(1-p/2,0,1);
    line(get(gca,'xlim'),[conf conf]);
    line(get(gca,'xlim'),[-conf -conf]);
    subplot(313);
    plot(f,vdz);
    set(gca,'FontName','Times New Roman','Fontsize', 16);
    xlabel('frequency'); ylabel('Jackknifed variance');
end;
% Adzar=zeros(size(dzar));
% indx=find(dzar>=x(1) & dzar<=x(2));
% Adzar(indx)=1;
%
% Adzah=zeros(size(dzah));
% indx=find(dzah>=x(1) & dzah<=x(2));
% Adzah(indx)=1;


function M_sh2pv = beamWeightsPressureVelocity(basisType)
% BEAMWEIGHTSPRESSUREVELOCITY Convert from SH signals to pressure velocity
%
%   Returns the 4x4 matrix that converts first-order SH signals to pressure
%   velocity signals, with the ordering [p v_x v_y v_z], where v_xyz are the
%   cartesian components of the acoustic veclocity vector.
%
%   basisType:  'complex' or 'real' for the respective type of spherical
%       harmonics under use.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% BEAMWEIGHTSPRESSUREVELOCITY.M - 11/7/2013
% Archontis Politis, archontis.politis@aalto.fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

switch basisType
    case 'real'
        M_sh2pv = sqrt(4*pi)*[  1   0           0           0;
                                0   0           0           1/sqrt(3);
                                0   1/sqrt(3)   0           0;
                                0   0           1/sqrt(3)   0];
    case 'complex'
        M_sh2pv = sqrt(4*pi)*[  1   0           0           0;
                                0   1/sqrt(6)   0           -1/sqrt(6);
                                0   -1i/sqrt(6) 0           -1i/sqrt(6);
                                0   0           1/sqrt(3)   0];
end


function [x,k,res,negCurv] = cg(A,b,optTol,maxIter,verbose,precFunc,precArgs,matrixVectFunc,matrixVectArgs)
% [x,k,res,negCurv] =
% cg(A,b,optTol,maxIter,verbose,precFunc,precArgs,matrixVectFunc,matrixVect
% Args)
% Linear Conjugate Gradient, where optionally we use
% - preconditioner on vector v with precFunc(v,precArgs{:})
% - matrix multipled by vector with matrixVectFunc(v,matrixVectArgs{:})

x = zeros(size(b));
r = -b;

% Apply preconditioner (if supplied)
if nargin >= 7 && ~isempty(precFunc)
    y = precFunc(r,precArgs{:});
else
    y = r;
end

ry = r'*y;
p = -y;
k = 0;

res = norm(r);
done = 0;
negCurv = [];
while res > optTol & k < maxIter & ~done
    % Compute Matrix-vector product
    if nargin >= 9
        Ap = matrixVectFunc(p,matrixVectArgs{:});
    else
        Ap = A*p;
    end
    pAp = p'*Ap;

    % Check for negative Curvature
    if pAp <= 1e-16
        if verbose
            fprintf('Negative Curvature Detected!\n');
        end

        if nargout == 4
           if pAp < 0
              negCurv = p;
              return
           end
        end

        if k == 0
            if verbose
                fprintf('First-Iter, Proceeding...\n');
            end
            done = 1;
        else
            if verbose
                fprintf('Stopping\n');
            end
            break;
        end
    end

    % Conjugate Gradient
    alpha = ry/(pAp);
    x = x + alpha*p;
    r = r + alpha*Ap;

    % If supplied, apply preconditioner
    if nargin >= 7 && ~isempty(precFunc)
        y = precFunc(r,precArgs{:});
    else
        y = r;
    end

    ry_new = r'*y;
    beta = ry_new/ry;
    p = -y + beta*p;
    k = k + 1;

    % Update variables
    ry = ry_new;
    res = norm(r);
end
end


function [cscale, rscale] = gmscale(A, iprint, scltol)
% Geometric-Mean Scaling finds the scale values for the
% `m x n` sparse matrix `A`.
%
% USAGE:
%
%    [cscale, rscale] = gmscale(A, iprint, scltol)
%
% INPUTS:
%    A(i, j):           contains entries of `A`.
%    iprint:            > 0 requests messages to the screen (0 means no output).
%    scltol:            should be in the range (0.0, 1.0).
%                       Typically `scltol` = 0.9.  A bigger value like 0.99 asks
%                       `gmscale` to work a little harder (more passes).
%
% OUTPUTS:
%    cscale, rscale:    column vectors of column and row scales such that
%                       `R` (inverse) `A` `C` (inverse) should have entries near 1.0,
%                       where `R= diag(rscale)`, `C = diag(cscale)`.
%
% An iterative procedure based on geometric means is used,
% following a routine written by Robert Fourer, 1979.
% Several passes are made through the columns and rows of `A`.
% The main steps are:
%
%   1. Compute :math:`aratio = max_j (max_i Aij / min_i Aij)`.
%   2. Divide each row `i` by :math:`sqrt( max_j Aij * min_j Aij)`.
%   3. Divide each column `j` by :math:`sqrt( max_i Aij * min_i Aij)`.
%   4. Compute `sratio` as in Step 1.
%   5. If :math:`sratio < aratio * scltol`,
%      set :math:`aratio = sratio` and repeat from Step 2.
%
% To dampen the effect of very small elements, on each pass,
% a new row or column scale will not be smaller than sqrt(damp)
% times the largest (scaled) element in that row or column.
%
% Use of the scales:
% To apply the scales to a linear program,
% :math:`min c^T x` st :math:`A x = b`, :math:`l \leq x \leq u`,
% we need to define "barred" quantities by the following relations:
% `A = R Abar C`, `b = R bbar`, `C cbar = c`,
% `C l = lbar`, `C u = ubar`, `C x = xbar`.
%
% This gives the scaled problem
% :math:`min\ cbar^T xbar` st :math:`Abar\ xbar = bbar`, :math:`lbar \leq xbar \leq ubar`.
%
% .. Author: - Michael Saunders, Systems Optimization Laboratory, Stanford University.
% ..
%    07 Jun 1996: First f77 version, based on MINOS 5.5 routine m2scal.
%    24 Apr 1998: Added final pass to make column norms = 1.
%    18 Nov 1999: Fixed up documentation.
%    26 Mar 2006: (Leo Tenenblat) First Matlab version based on Fortran version.
%    21 Mar 2008: (MAS) Inner loops j = 1:n optimized.
%    09 Apr 2008: (MAS) All loops replaced by sparse-matrix operations.
%                 We can't find the biggest and smallest Aij
%                 on each scaling pass, so no longer print them.
%    24 Apr 2008: (MAS, Kaustuv) Allow for empty rows and columns.
%    13 Nov 2009: gmscal.m renamed gmscale.m.

  if iprint > 0
    fprintf('\ngmscale: Geometric-Mean scaling of matrix')
    fprintf('\n-------\n                 Max col ratio')
  end

  [m,n]   = size(A);
  A       = abs(A);    % Work with |Aij|
  maxpass = 10;
  aratio  = 1e+50;
  damp    = 1e-4;
  small   = 1e-8;
  rscale  = ones(m,1);
  cscale  = ones(n,1);

%---------------------------------------------------------------
% Main loop.
%---------------------------------------------------------------
  for npass = 0:maxpass

    % Find the largest column ratio.
    % Also set new column scales (except on pass 0).

    rscale(rscale==0) = 1;
    Rinv    = diag(sparse(1./rscale));
    SA      = Rinv*A;
    [I,J,V] = find(SA);
    invSA   = sparse(I,J,1./V,m,n);
    cmax    = full(max(   SA))';   % column vector
    cmin    = full(max(invSA))';   % column vector
    cmin    = 1./(cmin + eps);
    sratio  = max( cmax./cmin );   % Max col ratio
    if npass > 0
      cscale = sqrt( max(cmin, damp*cmax) .* cmax );
    end

    if iprint > 0
      fprintf('\n  After %2g %19.2f', npass, sratio)
    end

    if npass >= 2 && sratio >= aratio*scltol, break; end
    if npass == maxpass, break; end
    aratio  = sratio;

    % Set new row scales for the next pass.

    cscale(cscale==0) = 1;
    Cinv    = diag(sparse(1./cscale));
    SA      = A*Cinv;                  % Scaled A
    [I,J,V] = find(SA);
    invSA   = sparse(I,J,1./V,m,n);
    rmax    = full(max(   SA,[],2));   % column vector
    rmin    = full(max(invSA,[],2));   % column vector
    rmin    = 1./(rmin + eps);
    rscale  = sqrt( max(rmin, damp*rmax) .* rmax );
  end
%---------------------------------------------------------------
% End of main loop.
%---------------------------------------------------------------

% Reset column scales so the biggest element
% in each scaled column will be 1.
% Again, allow for empty rows and columns.

  rscale(rscale==0) = 1;
  Rinv    = diag(sparse(1./rscale));
  SA      = Rinv*A;
  [I,J,V] = find(SA);
  cscale  = full(max(SA))';   % column vector
  cscale(cscale==0) = 1;

% Find the min and max scales.

  if iprint>0
    [rmin,imin] = min(rscale);
    [rmax,imax] = max(rscale);
    [cmin,jmin] = min(cscale);
    [cmax,jmax] = max(cscale);

    fprintf('\n\n  Min scale               Max scale')
    fprintf('\n  Row %6g %9.1e    Row %6g %9.1e'  , imin, rmin, imax, rmax)
    fprintf('\n  Col %6g %9.1e    Col %6g %9.1e\n', jmin, cmin, jmax, cmax)
  end

% end of gmscale


function correct = check_doa_correctness(actual, est, tolerance)
%CHECK_DOA_CORRECTNESS Checks if estimated doa is reasonably close to the
%actual ones. Input must be in ascending order within range of
%(-pi/2, pi/2).
%More precisely, suppose the true DOAs are x_1, x_2, ..., x_k, the estimated
%DOAs must fall within the following regions:
% (-pi/2, x_1 + (x_2 - x_1) / 2),
% (x_1 + (x_2 - x_1) / 2, x_2 + (x_3 - x_2) / 2), ...
% (x_k - (x_k - x_{k-1}) / 2, pi/2)
%If tolerance is not inf, the estimated DOAs must also fall within the following
% regions:
% (x_1 - tolerance, x_1 + tolerance), ...
% (x_k - tolerance, x_k + tolerance)

if nargin == 2
    tolerance = inf;
end
n = length(actual);
if n ~= length(est)
    correct = false;
    return;
end
if n == 1
    correct = abs(actual(1) - est(1)) < tolerance;
elseif n > 1
    spaces = diff(actual);
    max_deviation = min(spaces/2, tolerance);
    correct = true;
    % first
    correct = correct && ...
        (est(1) >= max(-pi/2, actual(1)-tolerance) && ...
        est(1) < actual(1) + max_deviation(1));
    % last
    correct = correct && ...
        (est(end) <= min(pi/2, actual(end)+tolerance) && ...
        est(end) > actual(end) - max_deviation(end));
    % middle
    for ii = 2:(n-1)
        correct = correct && ...
        (est(ii) > actual(ii) - max_deviation(ii-1) && ...
        est(ii) < actual(ii) + max_deviation(ii));
    end
end

end


function rot = fit(r,l,varargin)
% find rotation rot such that l = rot * r
%
% Syntax
%
%   rot = rotation.fit(r,l)
%   rot = rotation.fit(r,l,'weights',w)
%
% Input
%  r, l - @vector3d
%
% Output
%  rot - @rotation
%
% Description
% Find the rotation that best maps all the vectors |r| onto the vectors |l|.
%
% See also
% rotation/rotation rotation/byMatrix rotation/byAxisAngle
% rotation/byEuler
%
% References
%
% * W. Kabsch, A solution for the best rotation to relate two sets of
% vectors, Acta Cryst. (1976). A32, 922.
%
% * B. K. P. Horn, Closed-form solution of absolute orientation using unit
% quaternions, Journal of the Optical Society of America A (1987), Vol, 4,
% 629.
%

if check_option(varargin,'antipodal') || r.antipodal || l.antipodal
  warning('antipodal symmetry not yet supported in rotation.fit');
end

w = get_option(varargin,'weights');
if ~isempty(w), r = r .* w; end

M = r.normalize * l.normalize;

switch lower(get_option(varargin,'method','horn'))

  case 'horn' % quaternion based method

    MS = M + M.';
    MA = M - M.';

    N = [trace(M) MA(2,3)             MA(3,1)              MA(1,2);
      MA(2,3)    M(1,1)-M(2,2)-M(3,3) MS(1,2)              MS(1,3);
      MA(3,1)    MS(1,2)              M(2,2)-M(1,1)-M(3,3) MS(2,3);
      MA(1,2)    MS(1,3)              MS(2,3)              M(3,3)-M(1,1)-M(2,2)];

    [V,d] = eig(N,'vector');
    [~, ind] = sort(d);

    rot = rotation(V(:,ind(4)).');

  case 'kabsch' % Kabsch algorithm

    [U,~,V] = svd(M);

    if length(r)<3
      S = ones(3);
      S(3,3) = det(V*U');
      rot = rotation.byMatrix(V*S*U');
    else
      rot = rotation.byMatrix(V*U');
      if r.antipodal || l.antipodal, rot.i = false; end
    end
end
end

function check

r = rotation.rand;
% u = [xvector;yvector;zvector];
u = vector3d.rand(randi(100,1));

v = (r * u).';

% add some noise
vn = v + 0.1 .* vector3d.rand(size(v));

% fit a rotation
%rec = rotation.fit(u,vn,'method','kabsch');
rec = rotation.fit(u,vn,'method','horn');

% the distance to the initial rotation
angle(r,rec)./degree

% the fit
f = sum(dot(rec * u,vn.'));

% check for local minimum
S3G = localOrientationGrid(specimenSymmetry,specimenSymmetry,1*degree,'resolution',0.5*degree);
all(f > sum(dot(rec * S3G * u,vn.'),2))

end


function y = pochhammer(x,n)
% pochhammer(x,n) returns the rising log-factorial log(gamma(x+n)/gamma(x))
% Named after the corresponding Mathematica function.
%
% pochhammer.c provides a faster implementation.

if 0 && length(x) == 1 && all(n < 100)
  nmax = full(max(max(n)));
  t(1) = 0;
  y = 0;
  for i = 1:nmax
    y = y + log(x);
    t(i+1) = y;
    x = x + 1;
  end
  y = t(n+1);
  % workaround matlab's silly rules for matrix indexing
  if cols(n) == 1 & rows(y) == 1
    y = y';
  end
  return
end
if issparse(n)
  y = sparse(rows(n),cols(n));
else
  y = zeros(size(n));
end
i = (n > 0);
if length(x) == 1
  y(i) = gammaln(x+n(i)) - gammaln(x);
else
  y(i) = gammaln(x(i)+n(i)) - gammaln(x(i));
end


function imgOut = KimKautzConsistentTMO(img, Ld_max, Ld_min, KK_c1, KK_c2)
%
%
%      imgOut = KimKautzConsistentTMO(img, Ld_max, Ld_min, KK_c1, KK_c2)
%
%
%       Input:
%           -img: input HDR image
%           -Ld_max: max luminance of the LDR monitor in cd/m^2
%           -Ld_min: max luminance of the LDR monitor in cd/m^2
%           -KK_c1: this parameter adjusts the shape of Gaussian fall-off
%           within the width of tis characteristic curve. It influcences
%           the resulting brightness and local details of the tone-mapped
%           image. A good value is 3.0 (tradeoff between compression and
%           lost details)
%           -KK_c2: the ratio between the dynamic range (in log10) of an
%           8-bit imag (2.4) and the dynamic range (in log10) of the
%           LDR monitor for visualization
%
%       Output:
%           -imgOut: output tone mapped image in linear domain
%
%     Copyright (C) 2013-15  Francesco Banterle
%
%     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 3 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/>.
%
%     The paper describing this technique is:
%     "Consistent Tone Reproduction"
% 	  by Min H. Kim, Jan Kautz
%     in CGIM '08 Proceedings of the Tenth IASTED
%     International Conference on Computer Graphics and Imaging  2008
%

checkNegative(img);

if(~exist('Ld_max', 'var'))
    Ld_max = 300; %300 cd/m^2
end

if(~exist('Ld_min', 'var'))
    Ld_min = 0.3; %0.3 cd/m^2
end

if(~exist('KK_c1', 'var'))
    KK_c1 = 3.0; %as in the original paper
end

if(~exist('KK_c2', 'var'))
    KK_c2 = 0.5; %as in the original paper
end

L = lum(img);

L_log = log(L + 1e-6);

mu = mean(L_log(:));

maxL = max(L_log(:));
minL = min(L_log(:));

maxLd = log(Ld_max);
minLd = log(Ld_min);

k1 = (maxLd - minLd) / (maxL - minL);

d0 = maxL - minL;
sigma = d0 / KK_c1;

sigma_sq_2 = (sigma^2) * 2;
w = exp(-(L_log - mu).^2 / sigma_sq_2);
k2 = (1 - k1) * w + k1;

Ld = exp(KK_c2 * k2 .* (L_log - mu) + mu);

%robust min and max
minLd = MaxQuart(Ld, 0.01);
maxLd = MaxQuart(Ld, 0.99);

Ld(Ld < minLd) = minLd;
Ld(Ld > maxLd) = maxLd;

Ld = (Ld - minLd) / (maxLd - minLd);

%change luminance
imgOut = ChangeLuminance(img, L, Ld);
imgOut = RemoveSpecials(imgOut);

end


%rf_dualBand.m
%Jamie Near, McGill University 2014.
%
% USAGE:
% [rf,AMPINT]=rf_dualBand(tp,df,n,bw,ph,shft)
%
% DESCRIPTION:
% creates an n-point dual banded gaussian inversion RF pulse with duration
% tp(ms).  The first band will be at f=0Hz and the second band will be at
% df Hz.  Bw is the bandwidth of the two selection bands in Hz.
%
% INPUTS:
% tp         = pulse duration in ms.
% df         = frequency of 2nd gaussian band [Hz].
% n          = number of points in rf waveform.
% bw         = bandwidth of both selection bands [Hz].
% ph         = phase of the second gaussian.
% shft       = frequency shift applied to both bands.
%
% OUTPUTS:
% rf         = Output rf waveform for a dual banded rf pulse, in FID-A rf
%              pulse structure format.
% AMPINT     = Calculated amplitude integral (for use in Siemens .pta files).

function [rf,AMPINT]=rf_dualBand(tp,df,n,bw,ph,shft)

%convert the pulse duration into seconds;
tps=tp/1000;

%Make a time-scale for the rf pulse.
t=[-tps/2+(tps/(2*n)):tps/n:tps/2-(tps/(2*n))]';

%Calculate the fwhm and c parameter for the first band
fwhmf1=bw;
fwhmt1=1/fwhmf1;
c1=fwhmt1/(2*sqrt(2*log(2)));

%calculate the fwhm and c parameter for the second band
fwhmf2=bw;
fwhmt2=1/fwhmf2;
c2=fwhmt2/(2*sqrt(2*log(2)));

%calculate the time-domain gaussian waveforms for the 1st and 2nd bands.
gauss1=exp((-t.^2)./(2*c1^2));
gauss2=  exp((-t.^2)./(2*c2^2)).*exp(-i*df*2*pi*t);  %shift second gauss by +df

%add phase to the second band
gauss2=addphase(gauss2,ph);

%Here we compute the Amplitude integral(AMPINT), which is used by magnetom
%to calculate the transmitter power that is required in order to achieve
%the desired flip angle.

gscaled=gauss1/max(gauss1);
AI=sum(gscaled);

dgauss=(gauss1+gauss2).*exp(-i*shft*2*pi*t);

dgauss_scaled=dgauss/max(abs(dgauss));
AMPINT=AI/max(abs(dgauss));

rfwaveform=zeros(n,3);
rfwaveform(:,1)=phase(dgauss_scaled)*180/pi;
rfwaveform(:,2)=abs(dgauss_scaled);
rfwaveform(:,3)=ones(n,1);

%Now find out the w1-max of the pulse:
[mv,sc]=bes(rfwaveform,tp,'b',0,0,5,40000);
plot(sc,mv(3,:));
xlabel('w1 (kHz)');
ylabel('mz');
w1max=input('Input desired w1max in kHz:  ');
w1max=w1max*1000; %convert w1max to [Hz]
tw1=tps*w1max;

%for the time bandwidth product, we can simply calculate:
tbw=2*tps*bw;

rf.waveform=rfwaveform;
rf.type='inv';
rf.tw1=tw1;
rf.tbw=tbw;


function samples=cosmo_sample_unique(k,n,count,varargin)
% sample without replacement from subsets of integers in balanced manner
%
% function samples=cosmo_sample_unique(k,n[,count,varargin])
%
% Inputs:
%   k           number of elements to return in each subset
%   n           size of integer range from which to sample
%   count       number of subsets to select (default: 1)
%   'seed', s   Use seed s for pseudo-random sampling (optional). If this
%               option is omitted, then different calls to this function
%               may (usually: will) return different results
%
%
% Output:
%   samples     k x count indices, all in the range 1:n, with the following
%               properties:
%               - each value is randomly sampled from the range 1:n
%               - each column forms a subset of 1:n (without repeats)
%               - across the entire matrix, each value in the range 1:n
%                 occurs approximately equally often
%
% Example:
%     % get 4 random subsets of 3 elements in range 1:7
%     % (in this example a seed is used to get the same result upon every
%     % function call)
%     cosmo_sample_unique(3,6,4,'seed',3)
%     %||      1     2     1     2
%     %||      3     5     3     4
%     %||      4     6     5     6
%
% Notes:
%   - this is a utility function; it does not work on dataset structures.
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #

    if nargin<3 || isempty(count)
        count=1;
    end

    ensure_scalar_nat({k,n,count});
    if k>n
        error(['First argument (%d) cannot be greater than '...
                    'second argument (%d)'],k,n);
    end

    opt=cosmo_structjoin(varargin{:});

    % random elements, each column is a permutation of 1:count
    rs_mat=random_permutations(n,count+1,opt);

    % vectorize
    rs=rs_mat(:);

    % allocate space for output
    samples=zeros(k,count);

    % keep track of which elements in rs were visited
    visited=false((k+1)*count,1);

    first_non_visited_pos=1;
    in_bin=false(n,k); % re-use this for each column
    for col=1:count
        % no elements added so far
        in_bin(:)=false;

        pos=first_non_visited_pos;
        for row=1:k
            % avoid duplicates in in_bin
            while visited(pos) || in_bin(rs(pos))
                pos=pos+1;
            end

            r=rs(pos);
            in_bin(r)=true;
            samples(row,col)=r;
            visited(pos)=true;
        end

        % update first_non_visited pos
        while visited(first_non_visited_pos)
            first_non_visited_pos=first_non_visited_pos+1;
        end
    end

    samples=sort(samples,1);

function r=random_permutations(n,count,opt)
    % output r has in each column the values 1:count in randomly permuted
    % order
    if isfield(opt,'seed') && ~isempty(opt.seed)
        args={'seed',opt.seed};
    else
        args={};
    end

    v=cosmo_rand(n,count,args{:});
    [unused,r]=sort(v,1);

function ensure_scalar_nat(vs)
    for k=1:numel(vs)
        v=vs{k};

        if ~(isnumeric(v) && isscalar(v) && v>0 && round(v)==v)
            error('Argument %d must be positive scalar integer',k);
        end
    end


function y = sinfun1(M)
%Sample function used in Chapter 2.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt
x = 0:M - 1;
for k = 1:numel(x)
   y(k) = sin(x(k)/(100*pi));
end


function fe2d_n_fast_test ( )

%*****************************************************************************80
%
%% FE2D_N_FAST_TEST tests the FE2D_N_FAST code.
%
%  Discussion:
%
%    This function sets all parameter values and initial condition information
%    necessary to execute the "fast" version of the fe2d_n algorithm.
%
%  Licensing:
%
%    Copyright (C) 2014 Marcus R. Garvie.
%    See 'mycopyright.txt' for details.
%
%  Modified:
%
%    28 April 2014
%
%  Author:
%
%    Marcus R. Garvie.
%
%  Reference:
%
%    Marcus R Garvie, John Burkardt, Jeff Morgan,
%    Simple Finite Element Methods for Approximating Predator-Prey Dynamics
%    in Two Dimensions using MATLAB,
%    Submitted to Bulletin of Mathematical Biology, 2014.
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FE2D_N_FAST_TEST:\n' );
  fprintf ( 1, '  Test the FE2D_N_FAST function\n' );
  fprintf ( 1, '  which applies Neumann boundary conditions as it\n' );
  fprintf ( 1, '  approximates a solution to a predator-prey system.\n' );
%
%  Set the parameters.
%
  alpha = 0.4;
  beta = 2.0;
  gamma = 0.6;
  delta = 1.0;
%
%  Use T=150.0 for normal run.
%  Use T=0.50 for a "quick" run that might take 15 minutes of computing.
%
% T = 150.0;
  T = 0.50;
  delt = 1.0 / 384.0;

  t = tic;
  fe2d_n_fast ( alpha, beta, gamma, delta, T, delt, @u0f, @v0f, @guf, @gvf );
  t = toc ( t );

  fprintf ( 1, '  Execution took %10.2g minutes \n', t / 60.0 );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FE2D_N_FAST_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end

function value = u0f ( x, y )

%*****************************************************************************80
%
%% U0F evaluates the initial condition for U.
%
%  Licensing:
%
%    Copyright (C) 2014 Marcus R. Garvie.
%    See 'mycopyright.txt' for details.
%
%  Modified:
%
%    26 April 2014
%
%  Author:
%
%    Marcus R. Garvie.
%
%  Parameters:
%
%    Input, real X, Y, a location in the region.
%
%    Output, real VALUE, the initial condition for U at (X,Y).
%
  value = 6.0 / 35.0 - 2.0E-07 * ( x - 0.1 * y - 225.0 ) * ( x - 0.1 * y - 675.0 );

  return
end

function value = v0f ( x, y )

%*****************************************************************************80
%
%% V0F evaluates the initial condition for V.
%
%  Licensing:
%
%    Copyright (C) 2014 Marcus R. Garvie.
%    See 'mycopyright.txt' for details.
%
%  Modified:
%
%    26 April 2014
%
%  Author:
%
%    Marcus R. Garvie.
%
%  Parameters:
%
%    Input, real X, Y, a location in the region.
%
%    Output, real VALUE, the initial condition for V at (X,Y).
%
  value = 116.0 / 245.0 - 3.0E-05 * ( x - 450.0 ) - 1.2E-04 * ( y - 150.0 );

  return
end

function value = guf ( x, y, t )

%*****************************************************************************80
%
%% GUF evaluates the Neumann boundary condition for U.
%
%  Licensing:
%
%    Copyright (C) 2014 Marcus R. Garvie.
%    See 'mycopyright.txt' for details.
%
%  Modified:
%
%    28 April 2014
%
%  Author:
%
%    Marcus R. Garvie.
%
%  Parameters:
%
%    Input, real X, Y, a location on the boundary.
%
%    Input, real T, the time.
%
%    Output, real VALUE, the prescribed value of dU/dn at (X,Y,T).
%
  value = 0.0;

  return
end
function value = gvf ( x, y, t )

%*****************************************************************************80
%
%% GVF evaluates the Neumann boundary condition for V.
%
%  Licensing:
%
%    Copyright (C) 2014 Marcus R. Garvie.
%    See 'mycopyright.txt' for details.
%
%  Modified:
%
%    28 April 2014
%
%  Author:
%
%    Marcus R. Garvie.
%
%  Parameters:
%
%    Input, real X, Y, a location on the boundary.
%
%    Input, real T, the time.
%
%    Output, real VALUE, the prescribed value of dV/dn at (X,Y,T).
%
  value = 0.0;

  return
end


function [mFMDC, mFMD] = calc_FMDMag(mCatalog)
% function [mFMDC, mFMD] = calc_FMD(mCatalog)
% -------------------------------------------
% Calculates the cumulative and non-cumulative frequency magnitude distribution
%   for given magnitudes of an earthquake catalog
%
% Input parameter:
%   vMagnitudes    Either EQ catalog in ZMAP format or vector of magnitudes of an earthquake catalog
%
% Output parameters:
%   mFMDC       cumulative frequency magnitude distribution
%               mFMDC(1,:) = magnitudes (x-axis)
%               mFMDC(2,:) = number of events (y-axis)
%   mFMD        non-cumulative frequency magnitude distribution
%
% J. Woessner; woessner@seismo.ifg.ethz.ch
% last update: 12.07.02

global bDebug;
if bDebug
  report_this_filefun(mfilename('fullpath'));
end

[nXSize, nYSize] = size(mCatalog);
if nXSize > 1
  % Use magnitude column from ZMAP data catalog format
  vMagnitudes = mCatalog(:,6);
else
  % Use one column magnitude vector
  vMagnitudes = mCatalog;
end

% Determine the magnitude range
fMaxMagnitude = ceil(10 * max(vMagnitudes)) / 10;
fMinMagnitude = floor(min(vMagnitudes));
if fMinMagnitude > 0
  fMinMagnitude = 0;
end

% Naming convention:
%   xxxxR : Reverse order
%   xxxxC : Cumulative number

% Do the calculation
[vNumberEvents] = hist(vMagnitudes, (fMinMagnitude:0.1:fMaxMagnitude));
vNumberEventsR  = vNumberEvents(length(vNumberEvents):-1:1);
vNumberEventsCR = cumsum(vNumberEvents(length(vNumberEvents):-1:1));

% Create the x-axis values
vXAxis = (fMaxMagnitude:-0.1:fMinMagnitude);

% Merge the x-axis values with the FMDs and return them
mFMD  = [vXAxis; vNumberEventsR];
mFMDC = [vXAxis; vNumberEventsCR];


function [grad,err,finaldelta] = gradest(fun,x0)
% gradest: estimate of the gradient vector of an analytical function of n variables
% usage: [grad,err,finaldelta] = gradest(fun,x0)
%
% Uses derivest to provide both derivative estimates
% and error estimates. fun needs not be vectorized.
%
% arguments: (input)
%  fun - analytical function to differentiate. fun must
%        be a function of the vector or array x0.
%
%  x0  - vector location at which to differentiate fun
%        If x0 is an nxm array, then fun is assumed to be
%        a function of n*m variables.
%
% arguments: (output)
%  grad - vector of first partial derivatives of fun.
%        grad will be a row vector of length numel(x0).
%
%  err - vector of error estimates corresponding to
%        each partial derivative in grad.
%
%  finaldelta - vector of final step sizes chosen for
%        each partial derivative.
%
%
% Example:
%  [grad,err] = gradest(@(x) sum(x.^2),[1 2 3])
%  grad =
%      2     4     6
%  err =
%      5.8899e-15    1.178e-14            0
%
%
% Example:
%  At [x,y] = [1,1], compute the numerical gradient
%  of the function sin(x-y) + y*exp(x)
%
%  z = @(xy) sin(diff(xy)) + xy(2)*exp(xy(1))
%
%  [grad,err ] = gradest(z,[1 1])
%  grad =
%       1.7183       3.7183
%  err =
%    7.537e-14   1.1846e-13
%
%
% Example:
%  At the global minimizer (1,1) of the Rosenbrock function,
%  compute the gradient. It should be essentially zero.
%
%  rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
%  [g,err] = gradest(rosen,[1 1])
%  g =
%    1.0843e-20            0
%  err =
%    1.9075e-18            0
%
%
% See also: derivest, gradient
%
%
% Author: John D'Errico
% e-mail: woodchips@rochester.rr.com
% Release: 1.0
% Release date: 2/9/2007

% get the size of x0 so we can reshape
% later.
sx = size(x0);

% total number of derivatives we will need to take
nx = numel(x0);

grad = zeros(1,nx);
err = grad;
finaldelta = grad;
for ind = 1:nx
  [grad(ind),err(ind),finaldelta(ind)] = derivest( ...
    @(xi) fun(swapelement(x0,ind,xi)), ...
    x0(ind),'deriv',1,'vectorized','no', ...
    'methodorder',2);
end

end % mainline function end

% =======================================
%      sub-functions
% =======================================
function vec = swapelement(vec,ind,val)
% swaps val as element ind, into the vector vec
vec(ind) = val;

end % sub-function end


function [z, sd, m] = cellzscore(x, dim, flag)

% [Z, SD] = CELLZSCORE(X, DIM, FLAG) computes the zscore, across all cells in x along
% the dimension dim, normalising by the total number of samples
%
% X should be an linear cell-array of matrices for which the size in at
% least one of the dimensions should be the same for all cells. If flag==1, the mean will
% be subtracted first (default behavior, but to save time on already demeaned data, it
% can be set to 0). SD is a vector containing the standard deviations, used for the normalisation.

nx = size(x);
if ~iscell(x) || length(nx)>2 || all(nx>1),
  error('incorrect input for cellstd');
end

if nargin<2,
  scx1 = cellfun('size', x, 1);
  scx2 = cellfun('size', x, 2);
  if     all(scx2==scx2(1)), dim = 2; %let second dimension prevail
  elseif all(scx1==scx1(1)), dim = 1;
  else   error('no dimension to compute mean for');
  end
elseif nargin==2,
  flag = 1;
end

if flag,
  m    = cellmean(x, dim);
  x    = cellvecadd(x, -m);
end

sd   = cellstd(x, dim, 0);
z    = cellvecmult(x, 1./sd);


clear all
close all

Nobs=40;

[M,U] = mci_approach_struct (Nobs);

rand_params=1;
if rand_params
    P = spm_normrnd(M.pE,M.pC,1);
else
    V = 30;
    tau = 8;
    P = [log(V),log(tau)]';
end

yhat = mci_approach_gen (P,M,U);
Y = yhat + sqrt(M.Ce)*randn(Nobs,1);

% Check analytic gradients using finite differences
%dLdp = approach_deriv (P,M,U,Y);
%dLdp = spm_diff(M.L,P,M,U,Y,1);

% figure
% plot(U.X,Y);
% hold on
% plot(U.X,yhat,'r');

%mcmc.inference='vl';
mcmc.inference='langevin';

mcmc.verbose=0;
mcmc.maxits=1024;

post = spm_mci_post (mcmc,M,U,Y,P);

disp('Prior Mean (circle):');
disp(M.pE);

disp('Posterior Mean from MCI (cross)');
disp(post.Ep)

disp('True (plus)');
disp(P)

% Plot posterior surface
S.Nbins=100;
S.pxy(1,:)=linspace(2,4,S.Nbins);
S.pxy(2,:)=linspace(0.5,3.5,S.Nbins);
S.param{1}='P(1)';
S.param{2}='P(2)';
S.name={'log V_a','log \tau'};
%[L,S] = mci_plot_surface (P,M,U,Y,S,'prior');
%[L,S] = mci_plot_surface (P,M,U,Y,S,'like');
[L,S] = mci_plot_surface (P,M,U,Y,S,'post');
hold on
ms=10;
plot(M.pE(1),M.pE(2),'wo','MarkerSize',ms);
plot(post.Ep(1),post.Ep(2),'wx','MarkerSize',ms);
plot(P(1),P(2),'w+','MarkerSize',ms);
j=post.ind;
plot(post.P(1,j),post.P(2,j),'w.');

diag.essplot=1
diag.ind=j;
mess=spm_mci_diag(post,diag);

stats = spm_mci_mvnpost (post,'ESS')
stats = spm_mci_mvnpost (post,'thinning')


function geometry_test203235 ( )

%*****************************************************************************80
%
%% TEST203235 tests TETRAHEDRON_RHOMBIC_SIZE_3D and TETRAHEDRON_RHOMBIC_SHAPE_3D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 July 2007
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST203235\n' );
  fprintf ( 1, '  For the cube,\n' );
  fprintf ( 1, '  TETRAHEDRON_RHOMBIC_SIZE_3D returns dimension information;\n' );
  fprintf ( 1, '  TETRAHEDRON_RHOMBIC_SHAPE_3D returns face and order information.\n' );
  fprintf ( 1, '  SHAPE_PRINT_3D prints this information.\n' );
%
%  Get the data sizes.
%
  [ point_num, edge_num, face_num, face_order_max ] = ...
    tetrahedron_rhombic_size_3d ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of points =   %d\n', point_num );
  fprintf ( 1, '  Number of edges =    %d\n', edge_num );
  fprintf ( 1, '  Number of faces =    %d\n', face_num );
  fprintf ( 1, '  Maximum face order = %d\n', face_order_max );
%
%  Get the data.
%
  [ point_coord, face_order, face_point ] = ...
    tetrahedron_rhombic_shape_3d ( point_num, face_num, face_order_max );
%
%  Print the data.
%
  shape_print_3d ( point_num, face_num, face_order_max, ...
    point_coord, face_order, face_point );

  return
end


function basis_mn_t6_test ( )

%*****************************************************************************80
%
%% BASIS_MN_T6_TEST verifies BASIS_MN_T6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    None
%
  node_num = 6;

  t = [ ...
    2.0, 0.0; ...
    4.0, 3.0; ...
    0.0, 4.0; ...
    3.0, 1.5; ...
    2.0, 3.5; ...
    1.0, 2.0 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'BASIS_MN_T6_TEST\n' );
  fprintf ( 1, '  Verify basis functions for element T6.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of nodes = %d\n', node_num );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Physical Nodes:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '       I    X         Y\n' );
  fprintf ( 1, '\n' );

  for j = 1 : node_num
    fprintf ( 1, '  %6d  %7f  %7f\n', j, t(1:2,j) );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The basis function values at basis nodes\n' );
  fprintf ( 1, '  should form the identity matrix.\n' );
  fprintf ( 1, '\n' );

  [ phi, dphidx, dphidy ] = basis_mn_t6 ( t, node_num, t );

  for i = 1 : node_num
    for j = 1 : node_num
      fprintf ( 1, '  %7f', phi(i,j) );
    end
    fprintf ( 1, '\n' );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The X and Y derivatives should sum to 0.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '      dPhidX sum      dPhidY sum\n' );
  fprintf ( 1, '\n' );
  for j = 1 : node_num
    sum_x = sum ( dphidx(1:node_num,j) );
    sum_y = sum ( dphidy(1:node_num,j) );
    fprintf ( 1, '  %14f  %14f\n', sum_x, sum_y );
  end

  return
end


function rouderFigure2
% Runs the simulations of Rouder et al. 2009 in Figure 2,
% Shows the relationship between T test results, the Bayes Factor and
% sample size.
T = 1:0.05:10;
N = round(logspace(log10(5),log10(5000),100));
criticalT = nan(numel(N),3);
cntr =0;
for n=N
    cntr= cntr+1;
    for t= T
        % We call the bf.ttest function directly with
        % the results of a t-test (e.g. as returned by ttest.m)
        stats.tstat = t;
        stats.df    = n-1;
        stats.N     = n;
        stats.tail  = 'both';
        stats.p     = NaN; % no tused
        % Call the class member
        bf10 = bf.ttest([],'stats',stats);
        % Check whether we;ve reach any of the thresholds.
        % If so, store.
        if bf10>3 && isnan(criticalT(cntr,1))
            criticalT(cntr,1) = t;
        end
         if bf10>10 && isnan(criticalT(cntr,2))
            criticalT(cntr,2) = t;
         end
         if bf10>30 && isnan(criticalT(cntr,3))
            criticalT(cntr,3) = t;
            break; % Goto next n
         end
    end
end

%%
figure(2);
clf;
plot(N,criticalT)
xlabel 'Sample Size'
ylabel 'Critical t-value'
legend('BF=3','BF=10','BF=30')
set(gca,'XScale','Log','YLim',[1 6],'YTick',2:6,'XTick',[5 20 50 200 1000 5000],'XLim',[4 6000])
end


function test_2D
%TEST_2D Test 2D Plot with DRAGZOOM

x = -pi*4:0.1:pi*4;
y1 = sin(x);
y1n = y1 + 0.5 * randn(1, length(x));
y2 = cos(x);
y2n = y2 + 0.5 * randn(1, length(x));

figure();
hax = axes();
plot(hax, x, y1, '.-b', x, y1n, '*g', x, y2, '.-r', x, y2n, 'om');
legend('plot 1', 'plot 2', 'plot 3', 'plot 4')

dragzoom();


function lcvt_test02 ( )

%*****************************************************************************80
%
%% TEST02 tests CVT, R8MAT_LATINIZE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 September 2006
%
%  Author:
%
%    John Burkardt
%
  m = 2;
  n = 25;
  latin_steps = 3;
  sample_function_cvt = 0;
  sample_function_init = 3;
  sample_num_cvt = 100000;
  sample_num_steps = 50;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST02\n' );
  fprintf ( 1, '  CVT computes a Centroidal Voronoi Tessellation.\n' );
  fprintf ( 1, '  R8MAT_LATINIZE makes it a Latin Hypersquare.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  In this test, we initialize the generators to\n' );
  fprintf ( 1, '  grid points; this is an unstable CVT solution.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial dimension M =        %d\n', m );
  fprintf ( 1, '  Number of generators N =     %d\n', n );
  fprintf ( 1, '  Initial random number seed = %d\n', seed );
  fprintf ( 1, '\n' );

  if ( sample_function_init == -1 )
    fprintf ( 1, '  Initialize using RAND (MATLAB intrinsic).\n' );
  elseif ( sample_function_init == 0 )
    fprintf ( 1, '  Initialize using UNIFORM.\n' );
  elseif ( sample_function_init == 1 )
    fprintf ( 1, '  Initialize using HALTON.\n' );
  elseif ( sample_function_init == 2 )
    fprintf ( 1, '  Initialize using GRID.\n' );
  elseif ( sample_function_init == 3 )
    fprintf ( 1, '  USER will initialize data.\n' );
  end

  if ( sample_function_cvt == -1 )
    fprintf ( 1, '  Sample using RAND (MATLAB intrinsic).\n' );
  elseif ( sample_function_cvt == 0 )
    fprintf ( 1, '  Sample using UNIFORM.\n' );
  elseif ( sample_function_cvt == 1 )
    fprintf ( 1, '  Sample using HALTON.\n' );
  elseif ( sample_function_cvt == 2 )
    fprintf ( 1, '  Sample using GRID.\n' );
  end

  fprintf ( 1, '  Number of sample points = %d\n', sample_num_cvt );
  fprintf ( 1, '  Number of sample steps =  %d\n', sample_num_steps );

  ngrid = 5;

  for rank = 0 : n-1
    tuple = tuple_next_fast ( ngrid, m, rank );
    generator(1:m,rank+1) = ( 2 * tuple(1:m)' - 1 ) / ( 2 * ngrid );
  end

  r8mat_transpose_print ( m, n, generator, '  Initial generators (rows):' );

  for i = 1 : latin_steps

    [ generator, seed ] = cvt ( m, n, sample_function_init, ...
      sample_function_cvt, sample_num_cvt, sample_num_steps, seed, generator );

    r8mat_transpose_print ( m, n, generator, '  After CVT steps:' );

    generator = r8mat_latinize ( m, n, generator );

    r8mat_transpose_print ( m, n, generator, '  After Latin step:' );

  end

  return
end


function spatial_dist_extrema = spatial_distance_extrema_light(virtual_topography, virtual_chanlocs)
% spatial_dist_extrema calculates the log of the 2-norm of the distance
% between the two electrodes with the highest and lowest activations
% as described in
% Automatic Classification of Artifactual ICA-Components for Artifact
% Removal in EEG Signals by Irene Winkler, Stefan Haufe and Michael
% Tangermann http://www.behavioralandbrainfunctions.com/content/7/1/30
%
% Input:
% eeg: EEGLab data structure with additional fields
% virtual_topography and virtual_chanlocs. See the readme file for the
% toolbox for details on these fields.
%
% Output:
% spatial_dist_extrema: A vector containing the log of the 2-norm of the
% distance between the electrodes with highest and lowest activation in the
% scalp map of each IC in the EEGLab data structure given as input.

% Copyright (C) 2013  Laura Froelich (laura.frolich@gmail.com)
%
% 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.

nics = size(virtual_topography, 1);
spatial_dist_extrema = NaN(nics,1);
for ic =1:nics
    channel_activation = virtual_topography(ic,:);
    [dummy, maxindex] = max(channel_activation);
    [dummy, minindex] = min(channel_activation);
    maxlocation = [virtual_chanlocs(maxindex).X virtual_chanlocs(maxindex).Y virtual_chanlocs(maxindex).Z];
    minlocation = [virtual_chanlocs(minindex).X virtual_chanlocs(minindex).Y virtual_chanlocs(minindex).Z];

    spatial_dist_extrema(ic) = log(norm(maxlocation-minlocation,2));
end

end


%% OPT09_RUN
%
%  Modified:
%
%    08 January 2008
%
   %---------------------------------------------------------------------
   %  Running the trigonometric function
   %  This is used to test globalization methods.
   %---------------------------------------------------------------------
   fprintf('---------------------------------------------------------\n')
   fprintf('Running testcase_9:  F(X*) = 0\n')
   fprintf('---------------------------------------------------------\n')
   fname = 'opt09_fgh';
   options = [];
   options.verbose            = 0;
   options.method             = 'newton';

   fprintf('Newton:\n')
   options.globalization      = 'line_search';
   x0 = [ .25; .25; .25; .25 ];
   x = entrust(fname, x0, options);
   fprintf('Line search produced  (%8.5e,%8.5e,%8.5e,%8.5e)\n\n',...
     x(1),x(2),x(3),x(4))
   f = opt09_fgh ( x, 'f' );

   fprintf('Value of F(X) = %f\n', f );
   fprintf('Newton:\n')
   options.globalization      = 'trust_region';
   x = entrust(fname, x0, options);
   fprintf('Trust-region produced (%8.5e,%8.5e,%8.5e,%8.5e)\n\n',...
     x(1),x(2),x(3),x(4))
   f = opt09_fgh ( x, 'f' );
   fprintf('Value of F(X) = %f\n', f );

   %---------------------------------------------------------------------
   %  Test Gauss-Newton strategies.
   %---------------------------------------------------------------------
   fprintf('---------------------------------------------------------\n')
   fprintf('Running testcase_9 as least squares problem: \n')
   fprintf(' ||RES(X*)|| = 0\n')
   fprintf('---------------------------------------------------------\n')
   fname = 'opt09_rj';
   options = [];
   options.verbose            = 0;
   options.method             = 'gauss_newton';
   options.step_tolerance     = 1.e-15;
   options.globalization      = 'none';
   options.gradient_tolerance = 1.e-10;
   options.max_iterations     = 800;

   x0 = [ .25; .25; .25; .25 ];
   x = entrust(fname, x0, options);

   fprintf('Gauss-Newton produced (%8.5e,%8.5e,%8.5e,%8.5e)\n\n',...
     x(1),x(2),x(3),x(4))
   [ res, jac ] = opt09_rj ( x, 'f' );
   fprintf('Norm of RES(X) = %f\n', norm ( res ) );


% Online Bayesian model selection demo.

% We generate data from the model A->B
% and compute the posterior prob of all 3 dags on 2 nodes:
%  (1) A B,  (2) A <- B , (3) A -> B
% Models 2 and 3 are Markov equivalent, and therefore indistinguishable from
% observational data alone.

% We control the dependence of B on A by setting
% P(B|A) = 0.5 - epislon and vary epsilon
% as in Koller & Friedman book p512

% ground truth
N = 2;
dag = zeros(N);
A = 1; B = 2;
dag(A,B) = 1;

ntrials = 100;
ns = 2*ones(1,N);
true_bnet = mk_bnet(dag, ns);
true_bnet.CPD{1} = tabular_CPD(true_bnet, 1, [0.5 0.5]);

% hypothesis space
G = mk_all_dags(N);
nhyp = length(G);
hyp_bnet = cell(1, nhyp);
for h=1:nhyp
  hyp_bnet{h} = mk_bnet(G{h}, ns);
  for i=1:N
    % We must set the CPTs to the mean of the prior for sequential log_marg_lik to be correct
    % The BDeu prior is score equivalent, so models 2,3 will be indistinguishable.
    % The uniform Dirichlet prior is not score equivalent...
    fam = family(G{h}, i);
    hyp_bnet{h}.CPD{i}= tabular_CPD(hyp_bnet{h}, i, 'prior_type', 'dirichlet', ...
				    'CPT', 'unif');
  end
end

clf
seeds = 1:3;
expt = 1;
for seedi=1:length(seeds)
  seed = seeds(seedi);
  rand('state', seed);
  randn('state', seed);

  es = [0.05 0.1 0.15 0.2];
  for ei=1:length(es)
    e = es(ei);
    true_bnet.CPD{2} = tabular_CPD(true_bnet, 2, [0.5+e 0.5-e; 0.5-e 0.5+e]);

    prior = normalise(ones(1, nhyp));
    hyp_w = zeros(ntrials+1, nhyp);
    hyp_w(1,:) = prior(:)';
    LL = zeros(1, nhyp);
    ll = zeros(1, nhyp);
    for t=1:ntrials
      ev = cell2num(sample_bnet(true_bnet));
      for i=1:nhyp
	ll(i) = log_marg_lik_complete(hyp_bnet{i}, ev);
	hyp_bnet{i} = bayes_update_params(hyp_bnet{i}, ev);
      end
      prior = normalise(prior .* exp(ll));
      LL = LL + ll;
      hyp_w(t+1,:) = prior;
    end

    % Plot posterior model probabilities
    % Red = model 1 (no arcs), blue/green = models 2/3 (1 arc)
    % Blue = model 2 (2->1)
    % Green = model 3 (1->2, "ground truth")

    subplot2(length(seeds), length(es), seedi, ei);
    m = size(hyp_w,1);
    h=plot(1:m, hyp_w(:,1), 'r-',  1:m, hyp_w(:,2), 'b-.', 1:m, hyp_w(:,3), 'g:');
    axis([0 m   0 1])
    %title('model posterior vs. time')
    title(sprintf('e=%3.2f, seed=%d', e, seed));
    drawnow
    expt = expt + 1;
  end
end


function [N,E] = rentian_scaling_2d(A,XY,n,tol)
% RENTIAN_SCALING_2D    Rentian scaling for networks embedded in two dimensions.
%
% [N,E] = rentian_scaling_2d(A,XY,n,tol)
%
% Physical Rentian scaling (or more simply Rentian scaling) is a property
% of systems that are cost-efficiently embedded into physical space. It is
% what is called a "topo-physical" property because it combines information
% regarding the topological organization of the graph with information
% about the physical placement of connections. Rentian scaling is present
% in very large scale integrated circuits, the C. elegans neuronal network,
% and morphometric and diffusion-based graphs of human anatomical networks.
% Rentian scaling is determined by partitioning the system into cubes,
% counting the number of nodes inside of each cube (N), and the number of
% edges traversing the boundary of each cube (E). If the system displays
% Rentian scaling, these two variables N and E will scale with one another
% in loglog space. The Rent's exponent is given by the slope of log10(E)
% vs. log10(N), and can be reported alone or can be compared to the
% theoretical minimum Rent's exponent to determine how cost efficiently the
% network has been embedded into physical space. Note: if a system displays
% Rentian scaling, it does not automatically mean that the system is
% cost-efficiently embedded (although it does suggest that). Validation
% occurs when comparing to the theoretical minimum Rent's exponent for that
% system.
%
% INPUTS:
%
% A:              MxM adjacency matrix.
%                 Must be unweighted, binary, and symmetric.
% XY:             Matrix of node placement coordinates.
%                 Must be in the form of an Mx2 matrix [x y], where M is the
%                 number of nodes and x and y are column vectors of node
%                 coordinates.
% n:              Number of partitions to compute. Each partition is a data
%                 point. You want a large enough number to adequately
%                 estimate the Rent's exponent.
% tol:            This should be a small value (for example 1e-6).
%                 In order to mitigate the effects of boundary conditions due
%                 to the finite size of the network, we only allow partitions
%                 that are contained within the boundary of the network. This
%                 is achieved by first computing the volume of the convex
%                 hull of the node coordinates (V). We then ensure that the
%                 volume of the convex hull computed on the original node
%                 coordinates plus the coordinates of the randomly generated
%                 partition (Vnew) is within a given tolerance of the
%                 original (i.e. check abs(V - Vnew) < tol). Thus tol, should
%                 be a small value in order to make sure the partitions are
%                 contained largely within the boundary of the network, and
%                 thus the number of nodes and edges within the box are not
%                 skewed by finite size effects.
%
% OUTPUTS:
%
% N:              nx1 vector of the number of nodes in each of the n partitions.
% E:              nx1 vector of the number of edges crossing the boundary of
%                 each partition.
%
% Subsequent Analysis:
%
%     Rentian scaling plots are created by: figure; loglog(E,N,'*');
%
%     To determine the Rent's exponent, p, we need to determine
%     the slope of E vs. N in loglog space, which is the Rent's
%     exponent. There are many ways of doing this with more or less
%     statistical rigor. Robustfit in MATLAB is one such option:
%
%         [b,stats] = robustfit(log10(N),log10(E))
%
%     Then the Rent's exponent is b(1,2) and the standard error of the
%     estimation is given by stats.se(1,2).
%
% Note: n=5000 was used in Bassett et al. 2010 in PLoS CB.
%
% Reference:
% Danielle S. Bassett, Daniel L. Greenfield, Andreas Meyer-Lindenberg,
% Daniel R. Weinberger, Simon W. Moore, Edward T. Bullmore. Efficient
% physical embedding of topologically complex information processing
% networks in brains and computer circuits. PLoS Comput Biol, 2010,
% 6(4):e1000748.
%
% Modification History:
%
%     2010:     Original (Dani Bassett)
%     Dec 2016: Updated code so that both partition centers and partition
%               sizes are chosen at random. Also added in a constraint on
%               partition placement that prevents boxes from being located
%               outside the edges of the network. This helps prevent skewed
%               results due to boundary effects arising from the finite size
%               of the network. (Lia Papadopoulos)

% determine the number of nodes in the system
M = numel(XY(:,1));

% rescale coordinates so that they are all greater than unity
XYn = XY - repmat(min(XY)-1,M,1);

% compute the area of convex hull (i.e. are of the boundary) of the network
[~,V] = convhull(XYn(:,1),XYn(:,2));

% min and max network coordinates
xmin = min(XYn(:,1));
xmax = max(XYn(:,1));
ymin = min(XYn(:,2));
ymax = max(XYn(:,2));

% initialize vectors of number of nodes in box and number of edges crossing
% box

N = zeros(n,1);
E = zeros(n,1);

% create partitions, and count the number of nodes inside the partition (N)
% and the number of edges traversing the boundary of the partition (E)

nPartitions = 0;

while nPartitions<(n+1)

    % variable to check if partition center is within network boundary
    % OK if inside == 1
    inside = 0;

    while inside == 0

        % pick a random (x,y) coordinate to be the center of the box
        randx = xmin+(xmax-xmin)*rand(1);
        randy = ymin+(ymax-ymin)*rand(1);

        % make sure the point is inside the convex hull of the network
        newCoords = [XYn; [randx randy]];
        [~,Vnew] = convhull(newCoords(:,1),newCoords(:,2));

        % if the old convex hull area and new convex hull area are equal
        % then the box center must be inside the network boundary.

        if isequal(V,Vnew)==0
            inside = 0;
        else
            inside = 1;
        end

    end

    % determine the approximate maximum distance the box can extend, given
    % the center point and the  bounds of the network
    deltaY = min(abs(ymax-randy),abs(ymin-randy));
    deltaX = min(abs(xmax-randx),abs(xmin-randx));
    deltaLmin = min(deltaY,deltaX);

    % variable to check if partition is within network boundary
    % OK if inside == 1
    inside = 0;

    while inside == 0

        % pick a random (side length)/2 that is between 0 and the
        % max possible
        deltaL = deltaLmin*rand(1);

        % (x,y) coordinates for corners of box
        boxCoords = [randx - deltaL randy - deltaL; ...
            randx - deltaL randy + deltaL; ...
            randx + deltaL randy - deltaL; ...
            randx + deltaL randy + deltaL];

        % check if all corners of box are inside the convex hull of the
        % network
        newCoords = [XYn; boxCoords];
        [~,Vnew] = convhull(newCoords(:,1),newCoords(:,2));

        % make sure the new convex hull that includes the partition corners
        % is within a certain tolerance of the original convex hull area.

        if abs(V-Vnew)>tol
            inside = 0;
        else
            inside = 1;
        end
    end

    % Find nodes inside the box, edges crossing the boundary

    L = find(XYn(:,1)>(randx-deltaL) & XYn(:,1)<(randx+deltaL) ...
        & XYn(:,2)>(randy-deltaL) & XYn(:,2)<(randy+deltaL));

    if ~isempty(L) == 1
        nPartitions = nPartitions+1;
        % count edges crossing the boundary of the box
        E(nPartitions,1) = sum(sum(A(L,setdiff(1:M,L))));
        % count nodes inside of the box
        N(nPartitions,1) = numel(L);

    end

end

return;


function [fFactorHi, fStdHi, fResHi, fPerHi, fFactorLow, fStdLow, fResLow, fPerLow, fMRateFit] = calc_ratefac(mCat1, mCat2, fPeriod1, fPeriod2, fMc1, fMc2)
% [fFactorHi, fStdHi, fResHi, fPerHi, fFactorLow, fStdLow, fResLow, fPerLow, fMRateFit] = calc_ratefac(mCat1, mCat2, fPeriod1, fPeriod2, fMc1, fMc2)
% --------------------------------------------------------------------------------------------------------------------------------------------------
% Determine rate factor between amount of events between two time periods, differentiated for EQ with M<Mc and M>=Mc.
% Mc = min(fMc1, fMc2);
% N(Per2) = fFac * N (Per1)
% fFac is determined as mean of the factors in the magnitude bins, using a binning of 0.1.A factor for
% magnitudes M<Mc and M>=Mc is determined to explore a difference.Magnitude bins with no earthquakes
% are not used.
%
% Incoming variables:
% mCat1 : EQ catalog period 1
% mCat2 : EQ catalog period 2
% fPeriod1 : Time length period 1 /[dec. year]
% fPeriod2 : Time length period 2 /[dec. year]
% fMc1 : Magnitude of completeness period 1
% fMc2 : Magnitude of completeness period 2
%
% Outgoing variable:
% fFactorHi : Mean rate factor for EQ with M>=Mc
% fStdLow   : Standard deviation of fFactorHi
% fResLow   : Residuum for model application
% fPerHi    : Total percentage of change for EQ with M>=Mc
% fFactorLow : Mean rate factor for EQ with M<Mc
% fStdHi   : Standard deviation offFactorLow
% fResHi   : Residuum for model application
% fPerLow  : Total percentage of change for EQ with M<Mc
% fMRateFit: Goodness of fit by modeling second period with rate factor multiplication of first period
%
% J. Woessner, woessner@seismo.ifg.ethz.ch
% last update: 09.10.02

% Track of changes:

% Initialization
vMaxMag = [max(mCat1(:,6)) max(mCat2(:,6))];
fMaxMag =  max(vMaxMag);
fMc = min([fMc1 fMc2]);

% Binning
%% EQ with M < Mc
vSel1 = (mCat1(:,6) < fMc);
vSel2 = (mCat2(:,6) < fMc);
mCat1Mc = mCat1(vSel1,:);
mCat2Mc = mCat2(vSel2,:);
[vMag1,vBin1]=histogram(mCat1Mc(:,6),0:0.1:fMaxMag);
[vMag1sort,vBin1sort]=sort(vMag1);
[vMag2,vBin2]=histogram(mCat2Mc(:,6),0:0.1:fMaxMag);
[vMag2sort,vBin2sort]=sort(vMag2);

%% EQ with M >= Mc
mCat1McHi = mCat1(~vSel1,:);
mCat2McHi = mCat2(~vSel2,:);
[vMag1Hi,vBin1Hi]=histogram(mCat1McHi(:,6),0:0.1:fMaxMag);
[vMag1Hisort,vBin1Hisort]=sort(vMag1Hi);
[vMag2Hi,vBin2Hi]=histogram(mCat2McHi(:,6),0:0.1:fMaxMag);
[vMag2Hisort,vBin2Hisort]=sort(vMag2Hi);

%% Overall percentage of change of EQs
fPerLow = length(mCat2Mc(:,1))/length(mCat1Mc(:,1));
fPerHi = length(mCat2McHi(:,1))/length(mCat1McHi(:,1));
fPerLow = 100*fPerLow-100;
fPerHi = 100*fPerHi-100;

% Estimate factor between rates
% Factor for values below Mc of Period 1
vMag1 = vMag1/fPeriod1; % Time normalization
vMag2 = vMag2/fPeriod2; % Time normalization
fRatioLow = vMag2./vMag1;
%vSelRat = 1 - (isnan(fRatioLow) + isinf(fRatioLow));
vSelRatLow = (~isnan(fRatioLow) & ~isinf(fRatioLow));
fFactorLow = mean(fRatioLow(vSelRatLow));
fStdLow = std(fRatioLow(vSelRatLow));
vMagModelow = vMag1*fFactorLow;
fResLow = sqrt(sum((vMag2-(vMagModelow)).^2)/length(vMag2)); % Residuum

% Factor for values above or equal Mc of background
vMag1Hi = vMag1Hi/fPeriod1; % Time normalization
vMag2Hi = vMag2Hi/fPeriod2; % Time normalization
fRatioHi = vMag2Hi./vMag1Hi;
%vSelRatHi = 1 - (isnan(fRatioHi) + isinf(fRatioHi));
vSelRatHi = (~isnan(fRatioHi) & ~isinf(fRatioHi));
fFactorHi = mean(fRatioHi(vSelRatHi));
fStdHi = std(fRatioHi(vSelRatHi));
% vSelStd = (fRatioHi <= (fFactorHi+fStdHi) & fRatioHi >= (fFactorHi-fStdHi));
% fFactorHi = mean(fRatioHi(vSelStd))
vMagModel = vMag1Hi*fFactorHi;
fResHi = sqrt(sum((vMag2Hi-(vMagModel)).^2)/length(vMag2Hi)); % Residuum

% Determine goodness fit of modeled activity or M>=Mc
vEventsum2 = cumsum(vMag2Hi);
vEventsumMod = cumsum(vMagModel);
fMRateFit  = sum(abs(vEventsum2-vEventsumMod))/sum(vEventsum2);
fMRateFit = 100-fMRateFit*100;


function [basis,gradbasis]=legs(x,dir,n,scale)
% usage: [basis,gradbasis]=legs(x,dir,n,scale)
%
% returns the values and directional derivatives  of (n+1)^2-1 basis functions
% constructed from spherical harmonics at locations given in x and, for the
% gradients, for (in general non-normalized) directions given in dir.
%
% input: x      set of N locations given as an Nx3 matrix
%        dir    set of N direction vectors given as an Nx3 matrix
%                  (dir is not normalized (it hence can be a dipole moment))
%        n       order of spherical harmonics
%
% output: basis: Nx((n+1)^2-1)  matrix containing in the j.th  row the real
%                and imaginary parts of r^kY_{kl}(theta,Phi)/(N_{kl}*scale^k) ( (r,theta,phi)
%                are the spherical coordinates corresponding to  the j.th row in x)
%                for k=1 to n and l=0 to k
%                the order is:
%                          real parts for k=1 and l=0,1 (2 terms)
%                  then    imaginary parts for k=1 and l=1 (1 term)
%                  then    real parts for k=2 and l=0,1,2 (3 terms)
%                  then    imaginary parts for k=2 and l=1,2 (2 term)
%                              etc.
%                   the spherical harmonics are normalized with
%                   N_{kl}=sqrt(4pi (k+l)!/((k-l)!(2k+1)))
%                    the phase does not contain the usual (-1)^l term !!!
%                   scale is constant preferably set to the avererage radius
%
%         gradbasis: Nx((n+1)^2-1) matrix containing in the j.th row the scalar
%                     product of the gradient of the former with the j.th row of dir

% Copyright (C) 2003, Guido Nolte
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip 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 FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

[n1,n2]=size(x);

comi=sqrt(-1);

normalize=ones(n,n+1);
facto=ones(2*n+2,1);for i=3:2*n+2,facto(i)=facto(i-1)*(i-1);end;
for i=1:n
    for j=1:i+1
        if j==1
            normalize(i,j)=scale^i*i*sqrt(2*facto(i+j-1+1)/facto(i-j+1+1)/(2*i+1));
        else
            normalize(i,j)=scale^i*i*sqrt(facto(i+j-1+1)/facto(i-j+1+1)/(2*i+1));
        end
    end
end
normalize=reshape(repmat(reshape(normalize,n*(n+1),1),1,n1),n,n+1,n1);

rad=sqrt(x(:,1).^2+x(:,2).^2+x(:,3).^2);
phi=angle(x(:,1)+comi*x(:,2));
costheta=x(:,3)./(rad+eps);

ms=0:n;
ns=1:n;

shiftfactors=zeros(n,n+1);
shiftminusfactors=zeros(n,n+1);
for in=1:n; for im=1:n+1
        shiftfactors(in,im)=in+im-1;
        shiftminusfactors(in,im)=(in+im-2)*(in+im-1);
    end;end;
for in=1:n
    shiftminusfactors(in,1)=1;
end

leg0=zeros(n,n+1,n1);

for i=1:n
 p=legendre(i,costheta);
 leg0(i,1:i+1,:)=p;
end
 leg0=leg0.*reshape(repmat((-1).^ms,n,n1),n,n+1,n1);
ephi=exp(comi*ms'*phi');

leg0=leg0.*reshape(repmat(reshape(ephi,1,(n+1)*n1),n,1),n,n+1,n1)...
         .*reshape(repmat((repmat(rad,1,n).^repmat(ns,n1,1))',n+1,1),n,n+1,n1);

     onesx=zeros(1,n+1,n1);
     onesx(1,1,:)=ones(1,1,n1);

legshift=[onesx;leg0(1:n-1,:,:)];
legshiftminus=[-conj(legshift(:,2,:)),legshift(:,1:n,:)].*reshape(repmat(reshape(shiftminusfactors,n*(n+1),1),n1,1),n,n+1,n1);
legshiftplus=-[legshift(:,2:n+1,:),zeros(n,1,n1)];
legshift=legshift.*reshape(repmat(reshape(shiftfactors,n*(n+1),1),n1,1),n,n+1,n1);

dirp=[(dir(:,1)+dir(:,2)/comi)/2,(dir(:,1)-dir(:,2)/comi)/2,dir(:,3)];

gradleg= reshape(repmat(transpose(dirp(:,1)),n*(n+1),1),n,n+1,n1).*legshiftplus...
        +reshape(repmat(transpose(dirp(:,2)),n*(n+1),1),n,n+1,n1).*legshiftminus...
        +reshape(repmat(transpose(dirp(:,3)),n*(n+1),1),n,n+1,n1).*legshift;

leg0=leg0./normalize;
gradleg=gradleg./normalize;

    basis=zeros(n1,(n+1)^2-1);gradbasis=zeros(n1,(n+1)^2-1);
 for i=1:n
     basis(:,i^2:i^2+i)=(reshape(real(leg0(i,1:i+1,:)),i+1,n1))';
     basis(:,i^2+i+1:(i+1)^2-1)=(reshape(imag(leg0(i,2:i+1,:)),i,n1))';
     gradbasis(:,i^2:i^2+i)=(reshape(real(gradleg(i,1:i+1,:)),i+1,n1))';
     gradbasis(:,i^2+i+1:(i+1)^2-1)=(reshape(imag(gradleg(i,2:i+1,:)),i,n1))';
 end

return;


function [V,C] = calcVoronoi(v,varargin)
% compute the area of the Voronoi decomposition
%
% Input
%  v - @vector3d
%
% Output
%  V - list of Voronoi--Vertices
%  C - cell array of Voronoi--Vertices per generator
%
% See also
% voronoin

n = length(v);
v = reshape(v,[],1);

[x,y,z] = double(v);
faces = convhulln([x(:) y(:) z(:)],{'Qt','Pp','QJ'}); % delauny triangulation on sphere

% voronoi-vertices
V = normalize(cross(v.subSet(faces(:,3))-v.subSet(faces(:,1)),...
  v.subSet(faces(:,2))-v.subSet(faces(:,1))));

% voronoi-vertices around generators
[center, vertices] = sort(faces(:));

v = v.subSet(center);
vert = repmat(V,3,1);
vert = vert.subSet(vertices);

% the azimuth of a voronoi-vertex relativ to its generator
[ignore,azimuth] = polar(hr2quat(v,zvector).*cross(v,vert));

% sort the vertices clockwise around with respect to its center
[ignore,left] = sortrows([center azimuth]); %#ok<*ASGLU>

left = mod(vertices(left)'-1,length(V))+1;

% now we delete duplicated voronoi vertices
eps = 10^-10; % machine precision
[ignore,first,ind] = unique(round(squeeze(double(V))/eps)/eps,'rows');
V = V.subSet(first);
left = ind(left)';

% erase duplicated vertices in the pointer list
dublicated = find([diff(left)==0,false]);

% check whether the duplicated is in the next cell // they shouldn't be
% deleted
last = [0;find(diff(center));length(center)];
dublicated(ismember(dublicated,last)) = [];

left(dublicated) = [];
center(dublicated) = [];

C = cell(n,1);
last = [0;find(diff(center));length(center)];
for k=1:numel(last)-1
  ndx = last(k)+1:last(k+1);
  C{center(ndx(1))} = left( ndx );
end


function tSeries = boxcarSmooth(tSeries,period);
% Detrend time series data by multiple boxcar smoothing.
%
% tSeries = boxcarSmooth(tSeries,period);
%
% Import of mrVista 1.0 removeBaseline2:
% Uses multiple boxcar smoothing operations (number given by
% numIterations, default is 3) to remove low-frequency baseline
% drift from the input time series (tSeries) using the input
% period in FRAMES (not seconds!). The input is assumed to be
% two-dimensional, with time as the low-order dimension.
%
% Original code by DBR,  5/00
% imported by ras, 08/05
kernel = ones([period 1]) / period;
numIterations = 2;

% Initialize the baseline array to the time with 1-period
% padding at beginning and end:
ntPoints = size(tSeries, 1);
nSeries = size(tSeries, 2);
mValues = mean(tSeries);
nBLine = ntPoints + 2*period;
bLine = zeros(nBLine, nSeries);
firstTrialMean = mean(tSeries(1:period, :));

for frame=1:period, bLine(frame, :) = firstTrialMean; end
bLine(period+1:period+ntPoints, :) = tSeries;
lastTrialMean = mean(tSeries(ntPoints-period+1:ntPoints, :));
for frame=period+ntPoints+1:nBLine, bLine(frame, :) = lastTrialMean; end

% Define indices for post-smoothing array "trim":
addPts = numIterations * (period - 1);
start = floor(addPts/2) + 1;
stop = nBLine + floor(addPts/2);

% Smoothing loop -- convolve with boxcar, then "trim" array:
for i=1:numIterations, bLine = conv2(bLine, kernel); end
bLine = bLine(start:stop, :);

% Remove baseline from time series:
tSeries = double(tSeries) - bLine(period+1:period+ntPoints, :);

return


function M = spm_eeg_morlet(Rtf, ST, f, ff)
% Generate Morlet wavelets
% FORMAT M = spm_eeg_morlet(Rtf, ST, f, ff)
%
% Rtf - 'wavelet factor', see [1]
% ST  - sample time [ms]
% f   - vector of frequencies [Hz]
% ff  - frequency to fix Gaussian envelope (sigma = Rtf/(2*pi*ff))
%       Default is ff = f, ie.e, a Morlet transform
%       NB: FWHM = sqrt(8*log(2))*sigma_t;
%
% M   - cell vector, where each element contains the filter for each
%       frequency in f
%__________________________________________________________________________
%
% spm_eeg_morlet generates morlet wavelets for specified frequencies f with
% a specified ratio Rtf, see [1], for sample time ST (ms). One obtains the
% wavelet coefficients by convolution of a data vector with the kernels in
% M. See spm_eeg_tf how one obtains instantaneous power and phase estimates
% from the wavelet coefficients.
%
% [1] C. Tallon-Baudry, O. Bertrand, F. Peronnet and J. Pernier, 1998.
% Induced gamma-Band Activity during the Delay of a Visual Short-term
% memory Task in Humans. The Journal of Neuroscience (18): 4244-4254.
%__________________________________________________________________________
% Copyright (C) 2005-2017 Wellcome Trust Centre for Neuroimaging

% Stefan Kiebel
% $Id: spm_eeg_morlet.m 7122 2017-06-22 14:54:01Z guillaume $

if nargin < 4
    ff = f;
else
    ff = repmat(ff,1,numel(f));
end

M = cell(1,numel(f));

for i = 1:numel(f)

    % fixed or scale-dependent window
    %----------------------------------------------------------------------
    sigma_t = Rtf/(2*pi*ff(i));

    % this scaling factor is proportional to (Tallon-Baudry, 1998):
    % (sigma_t*sqrt(pi))^(-1/2);
    %----------------------------------------------------------------------
    t = 0:ST*0.001:5*sigma_t;
    t = [-t(end:-1:2) t];
    M{i} = exp(-t.^2/(2*sigma_t^2)) .* exp(2 * 1i * pi * f(i) *t);
    M{i} = M{i} ./ (sqrt(0.5*sum(real(M{i}).^2 + imag(M{i}).^2)));
    M{i} = M{i} - mean(M{i});

end


clear all; close all;
m=256; n=256;
a=0.04;
k=-1/a;
I=k*log(1-rand(m, n));
figure;
subplot(121);  imshow(uint8(I));
subplot(122);  imhist(uint8(I));


function m=mapzo(x)
xmin=min(x);xmax=max(x);
for i=1:length(x)
    m(i)=(x(i)-xmin)/(xmax-xmin);
end


function featuresS = ngldmToScalarFeatures(s,numVoxels)
% function featuresS = ngldmToScalarFeatures(s,numVoxels)
%
% APA, 03/16/2017

% Coarseness
Ns = sum(s(:));
Nn = size(s,2);
Ng = size(s,1);
lenV = 1:Nn;
levV = 1:Ng;

% Low dependence emphasis
sLdeM = bsxfun(@rdivide,s,lenV.^2);
featuresS.LowDependenceEmphasis = sum(sLdeM(:))/Ns;

% High dependence emphasis
sHdeM = bsxfun(@times,s,lenV.^2);
featuresS.HighDependenceEmphasis = sum(sHdeM(:))/Ns;

% Low grey level count emphasis
sLgceM = bsxfun(@rdivide,s',(1:Ng).^2);
featuresS.LowGrayLevelCountEmphasis = sum(sLgceM(:))/Ns;

% High grey level count emphasis
sHgceM = bsxfun(@times,s',(1:Ng).^2);
featuresS.HighGrayLevelCountEmphasis = sum(sHgceM(:))/Ns;

% Low dependence low grey level emphasis
sLdlgeM = bsxfun(@rdivide,bsxfun(@rdivide,s,lenV.^2)',(1:Ng).^2);
featuresS.LowDependenceLowGrayLevelEmphasis = sum(sLdlgeM(:))/Ns;

% Low dependence high grey level emphasis
sLdhgeM = bsxfun(@times,bsxfun(@rdivide,s,lenV.^2)',(1:Ng).^2);
featuresS.LowDependenceHighGrayLevelEmphasis = sum(sLdhgeM(:))/Ns;

% High dependence low grey level emphasis
sHdlgeM = bsxfun(@rdivide,bsxfun(@times,s,lenV.^2)',(1:Ng).^2);
featuresS.HighDependenceLowGrayLevelEmphasis = sum(sHdlgeM(:))/Ns;

% High dependence high grey level emphasis
sHdhgeM = bsxfun(@times,bsxfun(@times,s,lenV.^2)',(1:Ng).^2);
featuresS.HighDependenceHighGrayLevelEmphasis = sum(sHdhgeM(:))/Ns;

% Grey level non-uniformity
featuresS.GrayLevelNonuniformity = sum(sum(s,2).^2)/Ns;

% Grey level non-uniformity normalised
featuresS.GrayLevelNonuniformityNorm = sum(sum(s,2).^2)/Ns^2;

% Dependence count non-uniformity
featuresS.DependenceCountNonuniformity = sum(sum(s,1).^2)/Ns;

% Dependence count non-uniformity normalised
featuresS.DependenceCountNonuniformityNorm = sum(sum(s,1).^2)/Ns^2;

% Dependence count percentage
featuresS.DependenceCountPercentage = Ns/numVoxels;

% Grey level variance
iPij = bsxfun(@times,s'/sum(s(:)),levV);
mu = sum(iPij(:));
iMinusMuPij = bsxfun(@times,s'/sum(s(:)),(levV-mu).^2);
featuresS.GrayLevelVariance = sum(iMinusMuPij(:));

% Dependence count variance
jPij = bsxfun(@times,s/sum(s(:)),lenV);
mu = sum(jPij(:));
jMinusMuPij = bsxfun(@times,s/sum(s(:)),(lenV-mu).^2);
featuresS.DependenceCountVariance = sum(jMinusMuPij(:));

% Dependence count entropy
p = s(:)/sum(s(:));
featuresS.Entropy = -sum(p .* log2(p+eps));

% Dependence count energy
p = s(:)/sum(s(:));
featuresS.Energy = sum(p .^2);


clear; close all; clc;

group1=[10 12 22 15 21];
group2=[22 16 28 23] ;

mwwtest(group1,group2)

ns=4; nb=5;

mu_t=ns*(ns+nb+1)/2;
std_t=sqrt(ns*nb*(ns+nb+1)/12);

T1=17.5; T2=27.5;

Z_T=(T2-mu_t)/std_t