function featAugm = get_augm_spatial_features_diff_neighbour_locref(feat)

% relative coord of 2 detections
delta = feat(:, 1:2);
a = compute_angle(delta(:,1), delta(:,2));

delta_forward = feat(:, 5:6);
a_forward = compute_angle(delta_forward(:,1), delta_forward(:,2));

delta1 = delta - delta_forward;
dist1 = sqrt(delta1(:,1).^2 + delta1(:,2).^2);
a1 = wrap_angle(a - a_forward);
abs_a1 = abs(a1);
%abs_a1(:) = 0;

% now the same for backward
delta = feat(:, 3:4);
a = compute_angle(-delta(:,1), -delta(:,2));

delta_backward = feat(:, 7:8);
a_backward = compute_angle(delta_backward(:,1), delta_backward(:,2));

delta2 = delta - delta_backward;
dist2 = sqrt(delta2(:,1).^2 + delta2(:,2).^2);
a2 = wrap_angle(a - a_backward);
abs_a2 = abs(a2);

%featAugm = cat(2, dist, exp(-dist), dx, dy, abs(dx), abs(dy), dxdy, dx.^2, dy.^2, abs_a, a.^2, exp(-abs_a));

featAugm = cat(2, dist1, abs_a1, dist2, abs_a2);
featAugm = cat(2, featAugm, exp(-featAugm));

end

function angle = compute_angle(deltaX, deltaY)
angle = atan2(deltaY,deltaX);
angle = wrapMinusPiPifast(angle);
assert(all(angle <= pi) && all(angle >= -pi));
end

function a = wrap_angle(a)
larger = a > pi;
smaller = a < -pi;
a(larger)  = a(larger) - 2*pi;
a(smaller) = a(smaller)+ 2*pi;
end


function hydro = radiationIRF(hydro,tEnd,nDt,nDw,wMin,wMax)
% Calculates the normalized radiation impulse response function. This is
% equivalent to the radiation IRF in the theory section normalized by
% :math:`\rho`:
%
%     :math:`\overline{K}_{r,i,j}(t) = {\frac{2}{\pi}}\intop_0^{\infty}{\frac{B_{i,j}(\omega)}{\rho}}\cos({\omega}t)d\omega`
%
% Default parameters can be used by inputting [].
% See ``WEC-Sim\examples\BEMIO`` for examples of usage.
%
% Parameters
% ----------
%     hydro : struct
%         Structure of hydro data
%
%     tEnd : float
%         Calculation range for the IRF, where the IRF is calculated from t
%         = 0 to tEnd, and the default is 100 s
%
%     nDt : float
%         Number of time steps in the IRF, the default is 1001
%
%     nDw : float
%         Number of frequency steps used in the IRF calculation
%         (hydrodynamic coefficients are interpolated to correspond), the
%         default is 1001
%
%     wMin : float
%         Minimum frequency to use in the IRF calculation, the default is
%         the minimum frequency from the BEM data
%
%     wMax : float
%         Maximum frequency to use in the IRF calculation, the default is
%         the maximum frequency from the BEM data
%
% Returns
% -------
%     hydro : struct
%         Structure of hydro data with radiation IRF
%

p = waitbar(0,'Calculating radiation IRFs...');  % Progress bar

% Set defaults if empty
if isempty(tEnd)==1;  tEnd = 100;           end
if isempty(nDt)==1;    nDt = 1001;            end
if isempty(nDw)==1;    nDw = 1001;            end
if isempty(wMin)==1;  wMin = min(hydro.w);  end
if isempty(wMax)==1;  wMax = max(hydro.w);  end

% Interpolate to the given t and w
t = linspace(0,tEnd,nDt);
w = linspace(wMin,wMax,nDw);
N = sum(hydro.dof) * sum(hydro.dof);

% Calculate the impulse response function for radiation
n = 0;
hydro.ra_K = nan(sum(hydro.dof), sum(hydro.dof), length(t));
for i = 1:sum(hydro.dof)
    for j = 1:sum(hydro.dof)
        ra_B = interp1(hydro.w,squeeze(hydro.B(i,j,:)),w);
        hydro.ra_K(i,j,:) = (2/pi)*trapz(w,ra_B.*(cos(w.*t(:)).*w), 2);
        n = n+1;
    end
    waitbar(n/N)
end

% Calculate the infinite frequency added mass
ra_Ainf_temp = zeros(length(hydro.w),1);                                    %Initialize the variable
[~,F] = size(hydro);                                                        %Last data set in
if strcmp(hydro(F).code,'WAMIT')==0
    for i = 1:sum(hydro.dof)
        for j = 1:sum(hydro.dof)
            ra_A            = squeeze(hydro.A(i,j,:));
            ra_K            = squeeze(hydro.ra_K(i,j,:));
            for k = 1:length(hydro.w)                                       %Calculate the infinite frequency added mass at each input frequency
                ra_Ainf_temp(k,1)  = ra_A(k) + (1./hydro.w(k))*trapz(t,ra_K.*sin(hydro.w(k).*t.'));
            end
            hydro.Ainf(i,j) = mean(ra_Ainf_temp);                           %Take the mean across the vector of infinite frequency added mass
        end
    end
end

hydro.ra_t = t;
hydro.ra_w = w;
close(p)

end


function [U,S,output] = lmlra_rnd(size_tens,size_core,options)
%LMLRA_RND Pseudorandom initialization for LMLRA.
%   [U,S] = lmlra_rnd(size_tens,size_core) generates pseudorandom
%   unitary factor matrices U{1}, ..., U{N} of dimensions size_tens(n)-by-
%   size_core(n) and a core tensor of dimensions size_core that can be used
%   to initialize algorithms that compute a low multilinear rank
%   approximation of an N-th order tensor.
%
%   lmlra_rnd(T,size_core) is shorthand for lmlra_rnd(size(T),size_core) if
%   T is real. If T is complex, then by default S and U{n} will be
%   generated as a complex tensor and matrices, respectively (cf. options).
%
%   lmlra_rnd(size_tens,size_core,options) and lmlra_rnd(T,size_core, ...
%   options) may be used to set the following options:
%
%      options.Real =         - The type of random number generator used to
%      [{@randn}|@rand|0]       generate the real part of the core tensor S
%                               and matrices U{n}. If 0, there is no real
%                               part.
%      options.Imag =         - The type of random number generator used to
%      [@randn|@rand|0|...      generate the imaginary part of the core
%       {'auto'}]               tensor S and matrices U{n}. If 0, there is
%                               no imaginary part. On 'auto', options.Imag
%                               is 0 unless the first argument is a complex
%                               tensor T, in which case it is equal to
%                               options.Real.
%      options.Unitary = true - Set equal to false to generate the factor
%                               matrices U{n} without converting them to
%                               unitary matrices afterwards.
%
%   See also btd_rnd, cpd_rnd, lmlragen.

%   Authors: Laurent Sorber (Laurent.Sorber@cs.kuleuven.be)
%            Marc Van Barel (Marc.VanBarel@cs.kuleuven.be)
%            Lieven De Lathauwer (Lieven.DeLathauwer@kuleuven-kulak.be)

% Process input.
isSizeVector = any(size(size_tens) == numel(size_tens));
if ~isSizeVector, T = size_tens; size_tens = size(size_tens); end
N = length(size_tens);
if N ~= length(size_core)
    error('lmlra_rnd:size_core', ...
         ['length(size_core) should be equal to ndims(T) or ' ...
          'length(size_tens).']);
end

% Check the options structure.
isfunc = @(f)isa(f,'function_handle');
if nargin < 3, options = struct; end
if ~isfield(options,'Real'), options.Real = @randn; end
if ~isfunc(options.Real), options.Real = @zeros; end
if ~isfield(options,'Imag'), options.Imag = 'auto'; end
if ~isfield(options,'Unitary'), options.Unitary = true; end
if ischar(options.Imag) && strcmpi(options.Imag,'auto')
    if ~isSizeVector && ~isreal(T)
        options.Imag = options.Real;
    else
        options.Imag = 0;
    end
end

% Generate factor matrices and core tensor.
U = arrayfun(@(n)options.Real(size_tens(n),size_core(n)),1:N, ...
        'UniformOutput',0);
if isfunc(options.Imag)
    Ui = arrayfun(@(n)options.Imag(size_tens(n),size_core(n)),1:N, ...
            'UniformOutput',0);
    U = cellfun(@(ur,ui)ur+ui*1i,U,Ui,'UniformOutput',0);
end
if options.Unitary
    for n = 1:N
        if size(U{n},1) >= size(U{n},2), [U{n},~] = qr(U{n},0);
        else [Q,~] = qr(U{n}.',0); U{n} = Q.'; end
    end
end
S = options.Real(size_core(:).');
if isfunc(options.Imag), S = S+1i*options.Imag(size_core(:).'); end
output = struct;


function [pos_dot, vel_dot] = satellite_motion_diff_eq(pos, vel, acc, a, GM, J2, Omegae_dot)

% SYNTAX:
%   [pos_dot, vel_dot] = satellite_motion_diff_eq(pos, vel, acc, a, GM, J2, Omegae_dot);
%
% INPUT:
%   pos = satellite position (XYZ)
%   vel = satellite velocity
%   acc = acceleration due to lunar-solar gravitational perturbation
%   a   = ellipsoid semi-major axis [m]
%   GM  = gravitational constant (mass of Earth) [m^3/s^2]
%   J2  = second zonal harmonic of the geopotential
%   Omegae_dot = angular velocity of the Earth rotation [rad/s]
%                (if provided, an Earth-fixed system will be used)
%
% OUTPUT:
%   pos_dot = differential position
%   vel_dot = differential velocity
%
% DESCRIPTION:
%   Computation of the differential equations of perturbed orbital motion.

%--- * --. --- --. .--. ... * ---------------------------------------------
%               ___ ___ ___
%     __ _ ___ / __| _ | __|
%    / _` / _ \ (_ |  _|__ \
%    \__, \___/\___|_| |___/
%    |___/                    v 1.0RC1
%
%--------------------------------------------------------------------------
%  Copyright (C) 2021 Geomatics Research & Development srl (GReD)
%  Written by:
%  Contributors:     ...
%  A list of all the historical goGPS contributors is in CREDITS.nfo
%--------------------------------------------------------------------------
%
%   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/>.
%
%--------------------------------------------------------------------------
% 01100111 01101111 01000111 01010000 01010011
%--------------------------------------------------------------------------

if (nargin < 6)
    %do the computation in an inertial system
    Omegae_dot = 0;
end

%differential position
pos_dot = vel;

%renaming variables for better readability
%
%position
x = pos(1);
y = pos(2);
z = pos(3);
%velocity
vx = vel(1);
vy = vel(2);
%acceleration (i.e. perturbation)
ax = acc(1);
ay = acc(2);
az = acc(3);

%parameters
r = sqrt(x^2 + y^2 + z^2);
g = -GM/r^3;
h = J2*1.5*(a/r)^2;
k = 5*z^2/r^2;

%differential velocity
vel_dot = zeros(size(vel));
vel_dot(1) = g*x*(1 - h*(k - 1)) + ax + Omegae_dot^2*x + 2*Omegae_dot*vy;
vel_dot(2) = g*y*(1 - h*(k - 1)) + ay + Omegae_dot^2*y - 2*Omegae_dot*vx;
vel_dot(3) = g*z*(1 - h*(k - 3)) + az;


classdef SwerlingIVSqLawD
%%SWERLINGIVSQLAWD This class implements various functions and detections
%                statistics related to the Swerling IV target model when
%                used with a square law detector. All methods are static
%                (the class holds no information and does not need to be
%                instantiated).
%
%Implemented methods are: mean, var, PDF, CDF, PD4Threshold, PD4PFA, rand
%
%Swerling models are given in [1] and in Chapter 11 of [2]. The Swerling IV
%model assumes that the observed power SNR of the target varies in terms of
%a central gamma distribution with shape parameter k=2 and scale parameter
%theta=avgSNR/2, that in a pulse train for detection the target SNR
%fluctuates from pulse to pulse, and that a square law detector is used to
%incoherently integrate multiple pulses The difference from a Swerling III
%model is the target amplitude fluctuations from pulse to pulse.

%The square law detector for N samples is
%y=sum_{i=1}^N r_i^2
%where r_i is the ith real amplitude. The model for the amplitude given a
%target amplitude or power is developed in Chapter 9 of [2]. The squared
%real amplitude is r^2_i=y_{I,i}^2+y_{Q,i}^2 where y_{I,i} and y_{Q,i} are
%the in-phase and quadrature components of the filter output. Define
%Rp=2*sampPowSNR, as in Equation 9.2-34. The sampled power SNR of the
%target in the Swerling IV model is different for each pulse. The sample
%power SNR is sampPowSNR=GammaD.rand(1,2,avgSNR/2) as mentioned in [1]. The
%value y=y_{I,i}+sqrt(-1)*y_{Q,i} conditioned on the sampled power SNR is
%modeled as being distributed circularly complex Gaussian with mean
%sqrt(Rp) and variance 2. (See, Equation 9.3-35a in [2]). The variance
%being 2 simply reflects having normalized the variance on the I and Q
%components each to 1.  As in Equation 10.4-13 of [2], the distribution of
%Y=y/2 conditioned on the target SNR values is noncentral chi-squared with
%a change of variables. The value y conditioned on the target SNR values is
%noncentral chi-squared with nu=2*N degrees of freedom and lambda=N*Rp as
%the noncentrality parameter. The expressions in [1] and [2] are in terms
%of Y and not y, so a transformation has to be performed to make things in
%terms of y.
%
%Under this model, for a given average power SNR value, one can generate a
%random sample from the distribution as
% sample=0;
% for curPulse=1:N
%     sampPowSNR=GammaD.rand(1,2,avgSNR/2);
%     Rp=2*sampPowSNR;%The peak power of the signal from the SNR, Equation
%                 %9.4-8 in [2].
%     A=sqrt(Rp);%Equation 9.4-8, the amplitude of the signal
%     sample=sample+sum(abs(ComplexGaussianD.rand(1,A,2)).^2);
% end
%
%REFERENCES:
%[1] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%[2] J. V. Di Franco and W. L. Rubin, Radar Detection. SciTech Publishing
%    Inc., Rayliegh, NC: 2004.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

methods(Static)
function val=mean(avgSNR,N)
%%MEAN Obtain the mean of the distribution of the detection power
%      (normalized to a noise variance of 1) under a Swerling IV model in a
%      square-law detector.
%
%INPUTS:avgSNR The average power signal to noise ratio of the target.
%        N The number of pulses that are to be incoherently added for
%          detection (in a square-law detector). In a Swerling IV model, a
%          different realization of the target power is used across each
%          pulse and the noise corrupting the pulses varies. If this
%          parameter is omitted or an empty matrix is passed, N=1 is used.
%
%OUTPUTS: val The value of the mean for the given parameters.
%
%The mean is given in Equation 11.5-20 of [1] where equation 11.4-8 relates
%the parameterization used there to an average squared amplitude. To
%relate the average squared amplitude ABar^2 to avgSNR as used in [2], we
%use avgSNR=ABar^2/2. However, the first moment from that expression has to
%be multiplied by 2, because as seen in Equation 10.4-4 of [1], the
%definition is in terms of a scaled version of the square law detector.
%
%EXAMPLE:
%Here, we validate the mean by generating random samples and comparing the
%computed mean to the sample mean.
% avgSNR=2;
% N=4;
% numSamples=1e5;
% meanVal=SwerlingIVSqLawD.mean(avgSNR,N)
% meanSampVal=mean(SwerlingIVSqLawD.rand([numSamples,1],avgSNR,N))
%One will see that both mean values are about 24.
%
%REFERENCES:
%[1] J. V. Di Franco and W. L. Rubin, Radar Detection. SciTech Publishing
%    Inc., Rayliegh, NC: 2004.
%[2] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<2||isempty(N))
        N=1;
    end

    val=2*N*(1+avgSNR);
end

function val=var(avgSNR,N)
%%VAR Obtain the variance of the distribution of the detection power
%     (normalized to a noise variance of 1) under a Swerling IV model in a
%     square-law detector.
%
%INPUTS:avgSNR The average power signal to noise ratio of the target.
%        N The number of pulses that are to be incoherently added for
%          detection (in a square-law detector). In a Swerling IV model, a
%          different realization of the target power is used across each
%          pulse and the noise corrupting the pulses varies. If this
%          parameter is omitted or an empty matrix is passed, N=1 is used.
%
%OUTPUTS: val The value of the variance for the given parameters.
%
%The variance is given in Equation 11.5-22b of [1] where equation 11.4-8
%relates the parameterization used there to an average squared amplitude.
%To relate the average squared amplitude ABar^2 to avgSNR as used in [2],
%we use avgSNR=ABar^2/2. However, the variance from that expression has to
%be multiplied by 4, because as seen in Equation 10.4-4 of [1], the
%definition in is in terms of a scaled version of the square law detector.'
%
%EXAMPLE:
%Here, we validate the variance by generating random samples and comparing
%the computed variance to the sample variance.
% avgSNR=2;
% N=4;
% numSamples=1e5;
% varVal=SwerlingIVSqLawD.var(avgSNR,N)
% varSampVal=var(SwerlingIVSqLawD.rand([numSamples,1],avgSNR,N))
%One will see that both variance values are about 112.
%
%REFERENCES:
%[1] J. V. Di Franco and W. L. Rubin, Radar Detection. SciTech Publishing
%    Inc., Rayliegh, NC: 2004.
%[2] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

    if(nargin<2||isempty(N))
        N=1;
    end

    val=4*N*(1+avgSNR.*(2+avgSNR/2));
end

function val=PDF(x,avgSNR,N)
%%PDF Evaluate the scalar probability density function (PDF) of the
%     distribution of the detection power (normalized to a noise variance
%     of 1) under a Swerling IV model in a square-law detector.
%
%INPUTS: x The point or points at which the PDF should be evaluated. v>=0
%          for nonzero PDF values.
%   avgSNR The average power signal to noise ratio of the target.
%        N The number of pulses that are to be incoherently added for
%          detection (in a square-law detector). In a Swerling IV model, a
%          different realization of the target power is used across each
%          pulse and the noise corrupting the pulses varies. If this
%          parameter is omitted or an empty matrix is passed, N=1 is used.
%
%OUTPUTS: val The values of the PDF evaluated at the given points.
%
%The PDF is given in Equation 11.5-14 where equation 11.4-8 relates the
%parameterization used there to an average squared amplitude. To relate the
%average squared amplitude ABar^2 to avgSNR as used in [2], we use
%avgSNR=ABar^2/2. However the PDF is derived is based on a scaled
%square-law detector, as in Equation 10.4-4 in [1]. Thus, in implementing
%the PDF, the scaling is removed.
%
%EXAMPLE:
%Here, we validate the PDF by generating random samples and comparing the
%PDF plot with a histogram of the random samples.
% avgSNR=2;
% N=4;
% numSamples=10e3;
%
% figure(1)
% clf
% histogram(SwerlingIVSqLawD.rand([numSamples,1],avgSNR,N),'Normalization','pdf')
% hold on
% numPoints=1000;
% x=linspace(0,80,numPoints);
% vals=SwerlingIVSqLawD.PDF(x,avgSNR,N);
% plot(x,vals,'linewidth',2)
% h1=xlabel('x');
% h2=ylabel('PDF(x)');
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%One will see that the histogram matches well with the plot.
%
%REFERENCES:
%[1] J. V. Di Franco and W. L. Rubin, Radar Detection. SciTech Publishing
%    Inc., Rayliegh, NC: 2004.
%[2] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    %Initial change of variable to undo the scaling from Equation 10.4-4 in
    %[1].
    x=x/2;

    xBar2=avgSNR/2;
    val=zeros(size(x));
    numEls=numel(x);

    for curEl=1:numEls
        v=x(curEl);

        if(v>0)
            val(curEl)=exp((N-1)*log(v)-v/(1+xBar2)-2*N*log(1+xBar2)-gammaln(N))*hypergeometric1F1(-N,N,-xBar2/(1+xBar2)*v);
        elseif(v==0&&N==1)
            val(curEl)=1/((1+xBar2)^(2*N)*factorial(N-1));
        end
    end

    %Adjust for the change of variable to undo the scaling from Equation
    %10.4-4 in [1].
    val=val/2;
end

function val=CDF(v,avgSNR,N)
%%CDF Evaluate the scalar cumulative distribution function (CDF) of the
%     distribution of the detection power (normalized to a noise variance
%     of 1) under a Swerling IV model in a square-law detector.
%
%INPUTS: v The point or points at which the CDF should be evaluated. v>0
%          for nonzero CDF values.
%   avgSNR The average power signal to noise ratio of the target.
%        N The number of pulses that are to be incoherently added for
%          detection (in a square-law detector). In a Swerling IV model, a
%          different realization of the target power is used across each
%          pulse and the noise corrupting the pulses varies. If this
%          parameter is omitted or an empty matrix is passed, N=1 is used.
%
%OUTPUTS: val The values of the CDF evaluated at the given points.
%
%The derivation of the detection probability in [1] is as 1-the value of
%the CDF. Thus, this function just evaluated
%1-SwerlingIVSqLawD.PD4Threshold(avgSNR,v,N).
%
%REFERENCES:
%[1] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    val=1-SwerlingIVSqLawD.PD4Threshold(avgSNR,v,N);
    val(v<=0)=0;
end

function PD=PD4Threshold(avgSNR,thresh,N)
%%PD4THRESHOLD Determine the detection probability of a Swerling IV target
%           given its signal to noise ratio and the value of the
%           detection threshold, assuming that a square-law detector is
%           used. The noise in each sample is assumed to be Gaussian with
%           variance 1 (normalized noise power).
%
%INPUTS: avgSNR A vector or matrix of average power signal to noise ratios
%               of the target at which one wishes to evaluate the detection
%               probability.
%        thresh The scalar normalized detection threshold to use. This is
%               the threshold to use if the noise variance is 1.
%             N The number of pulses that are to be incoherently added for
%               detection (in a square-law detector). In a Swerling IV
%               model, a different realization of the target power is used
%               across each pulse and the noise corrupting the pulses
%               varies. If this parameter is omitted or an empty matrix is
%               passed, N=1 is used.
%
%OUTPUTS: PD The detection probability of the target.
%
%This function implements the sum in Equations 11.5-19 in [1]. However, the
%expression used is derived based on a scaled square-law detector, as in
%Equation 10.4-4. Thus, the threshold in this function is scaled
%appropriately.
%
%EXAMPLE:
%Here, we validate the results by comparing the PD from this function to
%the PD computed using random samples.
% avgSNR=2;
% thresh=30;
% N=4;
% PD=SwerlingIVSqLawD.PD4Threshold(avgSNR,thresh,N)
% numSamples=1e5;
% PDSamp=mean(SwerlingIVSqLawD.rand([numSamples,1],avgSNR,N)>=thresh)
%One will see that both PD values are about 0.254.
%
%REFERENCES:
%[1] J. V. Di Franco and W. L. Rubin, Radar Detection. SciTech Publishing
%    Inc., Rayliegh, NC: 2004.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    thresh=thresh/2;

    R=2*avgSNR;

    logR4=log(R/4);
    logCoeff=gammaln(N+1)-N*log(1+R/4);
    sumVal=0;
    for k=0:N
        curTerm=exp(logCoeff+k*logR4+log(gammainc(thresh/(1+R/4),k+N))-gammaln(k+1)-gammaln(N-k+1));

        sumVal=sumVal+curTerm;
    end

    PD=1-sumVal;
end

function PD=PD4PFA(avgSNR,PFA,N)
%%PD4PFA Determine the detection probability of a Swerling IV target given
%        its signal to noise ratio and the probability of false alarm
%        implied by a particular unspecified detection threshold, assuming
%        that a square law detector is used.
%
%INPUTS: avgSNR A vector or matrix of average power signal to noise ratios
%               of the target at which one wishes to evaluate the detection
%               probability.
%           PFA The probability of false alarm, 0<=PFA<1.
%             N The number of pulses that are to be incoherently added for
%               detection (in a square-law detector). In a Swerling IV
%               model, a different realization of the target power is used
%               across each pulse and the noise corrupting the pulses
%               varies. If this parameter is omitted or an empty matrix is
%               passed, N=1 is used.
%
%OUTPUTS: PD The detection probability of the target, 0<=PD<=1.
%
%This function just calls PFA2SquareLawThreshold to convert the false alarm
%rate into a normalized detection threshold after which it calls
%SwerlingIVSqLawD.PD4Threshold.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    thresh=PFA2SquareLawThreshold(PFA,N);
    PD=SwerlingIVSqLawD.PD4Threshold(avgSNR,thresh,N);
end

function vals=rand(NDims,avgSNR,N)
%%RAND Generate random variables representing a target whose sampled signal
%      to average noise power ratio is generated according to a Swerling IV
%      model detected by a square-law detector.
%
%INPUTS: NDims If NDims is a scalar, then rand returns an NDimsXNDims
%          matrix of random variables. If NDims=[M,N1] is a two-element row
%          vector, then rand returns an MXN1 matrix of random variables.
%   avgSNR The average power signal to noise ratio of the target.
%        N The number of pulses that are to be incoherently added for
%          detection (in a square-law detector). In a Swerling IV model, a
%          different realization of the target power is used across each
%          pulse and the noise corrupting the pulses varies. If this
%          parameter is omitted or an empty matrix is passed, N=1 is used.
%
%OUTPUTS: vals A matrix whose dimensions are determined by N of the
%              generated random variables.
%
%Following the model of [1], a sample from the central gamma distribution
%is performed to obtain the complex signal to noise ratio of every single
%one of the N pulses. Then, the square law detector output conditioned on
%the signal to noise ratio is generated directly using NonFlucSqLawD.rand
%for each pulse and the values are added.
%
%REFERENCES:
%[1] P. Swerling, "Probability of detection for fluctuating targets," The
%    RAND Corporation, Santa Monica, CA, Tech. Rep. RM-1217, 1954.
%
%March 2017 David F. Crouse, Naval Research Laboratory, Washington D.C.

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

    if(isscalar(NDims))
        dims=[NDims, NDims];
    else
        dims=NDims;
    end

    vals=zeros(dims);

    numEls=numel(vals);
    for curEl=1:numEls
        for curPulse=1:N
            %Equation I.2 for  the input signal-to-noise power ratio. It is
            %different for each sample in the pulse train in the Swerling
            %IV model.

            curSNR=GammaD.rand(1,2,avgSNR/2);
            vals(curEl)=vals(curEl)+NonFlucSqLawD.rand(1,curSNR,1);
        end
    end
end
end
end

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


function ydata = tsne_p(P, labels, no_dims)
%TSNE_P Performs symmetric t-SNE on affinity matrix P
%
%   mappedX = tsne_p(P, labels, no_dims)
%
% The function performs symmetric t-SNE on pairwise similarity matrix P
% to create a low-dimensional map of no_dims dimensions (default = 2).
% The matrix P is assumed to be symmetric, sum up to 1, and have zeros
% on the diagonal.
% The labels of the data are not used by t-SNE itself, however, they
% are used to color intermediate plots. Please provide an empty labels
% matrix [] if you don't want to plot results during the optimization.
% The low-dimensional data representation is returned in mappedX.
%
%
% (C) Laurens van der Maaten, 2010
% University of California, San Diego

    if ~exist('labels', 'var')
        labels = [];
    end
    if ~exist('no_dims', 'var') || isempty(no_dims)
        no_dims = 2;
    end

    % First check whether we already have an initial solution
    if numel(no_dims) > 1
        initial_solution = true;
        ydata = no_dims;
        no_dims = size(ydata, 2);
    else
        initial_solution = false;
    end

    % Initialize some variables
    n = size(P, 1);                                     % number of instances
    momentum = 0.5;                                     % initial momentum
    final_momentum = 0.8;                               % value to which momentum is changed
    mom_switch_iter = 250;                              % iteration at which momentum is changed
    stop_lying_iter = 100;                              % iteration at which lying about P-values is stopped
    max_iter = 1000;                                    % maximum number of iterations
    epsilon = 500;                                      % initial learning rate
    min_gain = .01;                                     % minimum gain for delta-bar-delta

    % Make sure P-vals are set properly
    P(1:n + 1:end) = 0;                                 % set diagonal to zero
    P = 0.5 * (P + P');                                 % symmetrize P-values
    P = max(P ./ sum(P(:)), realmin);                   % make sure P-values sum to one
    const = sum(P(:) .* log(P(:)));                     % constant in KL divergence
    if ~initial_solution
        P = P * 4;                                      % lie about the P-vals to find better local minima
    end

    % Initialize the solution
    if ~initial_solution
        ydata = .0001 * randn(n, no_dims);
    end
    y_incs  = zeros(size(ydata));
    gains = ones(size(ydata));

    % Run the iterations
    for iter=1:max_iter

        % Compute joint probability that point i and j are neighbors
        sum_ydata = sum(ydata .^ 2, 2);
        num = 1 ./ (1 + bsxfun(@plus, sum_ydata, bsxfun(@plus, sum_ydata', -2 * (ydata * ydata')))); % Student-t distribution
        num(1:n+1:end) = 0;                                                 % set diagonal to zero
        Q = max(num ./ sum(num(:)), realmin);                               % normalize to get probabilities

        % Compute the gradients (faster implementation)
        L = (P - Q) .* num;
        y_grads = 4 * (diag(sum(L, 1)) - L) * ydata;

        % Update the solution
        gains = (gains + .2) .* (sign(y_grads) ~= sign(y_incs)) ...         % note that the y_grads are actually -y_grads
              + (gains * .8) .* (sign(y_grads) == sign(y_incs));
        gains(gains < min_gain) = min_gain;
        y_incs = momentum * y_incs - epsilon * (gains .* y_grads);
        ydata = ydata + y_incs;
        ydata = bsxfun(@minus, ydata, mean(ydata, 1));

        % Update the momentum if necessary
        if iter == mom_switch_iter
            momentum = final_momentum;
        end
        if iter == stop_lying_iter && ~initial_solution
            P = P ./ 4;
        end

        % Print out progress
        if ~rem(iter, 10)
            cost = const - sum(P(:) .* log(Q(:)));
            disp(['Iteration ' num2str(iter) ': error is ' num2str(cost)]);
        end

        % Display scatter plot (maximally first three dimensions)
        if ~rem(iter, 10) && ~isempty(labels)
            if no_dims == 1
                scatter(ydata, ydata, 9, labels, 'filled');
            elseif no_dims == 2
                scatter(ydata(:,1), ydata(:,2), 9, labels, 'filled');
            else
                scatter3(ydata(:,1), ydata(:,2), ydata(:,3), 40, labels, 'filled');
            end
            axis tight
            axis off
            drawnow
        end
    end


function [c, s] = foopsi(y, g, lam, solver)
%% Infer the most likely discretized spike train underlying an AR(1) fluorescence trace
% Solves the sparse non-negative deconvolution problem
%  min 1/2|c-y|^2 + lam |s|_1 subject to s_t = c_t-g c_{t-1} >= 0

%% inputs:
%   y:  T*1 vector, One dimensional array containing the fluorescence intensities
%withone entry per time-bin.
%   g:  scalar, Parameter of the AR(1) process that models the fluorescence ...
%impulse response.
%   lam:  scalar, sparsity penalty parameter lambda.
%   solver: string, optimization solver

%% outputs
%   c: T*1 vector, the inferred denoised fluorescence signal at each time-bin.
%   s: T*1 vector, discetized deconvolved neural activity (spikes)

%% Authors: Pengcheng Zhou, Carnegie Mellon University, 2016
% ported from the Python implementation from Johannes Friedrich

%% References
% Friedrich J et.al., NIPS 2016, Fast Active Set Method for Online Spike Inference from Calcium Imaging

%% initialization
y = reshape(y, [], 1);
T = length(y);
if ~exist('g', 'var') || isempty(g);   g = estimate_time_constant(y, 2); end

if ~exist('lam', 'var') || isempty(lam);   lam = 0; end
if ~exist('solver', 'var') || isempty(smin);   solver = 'SDPT3'; end

% construct the deconvolution matrix (s=G*c)
len_g = length(g);
g = reshape(g, 1, []);
indc = bsxfun(@minus, (1:T)', 0:len_g);
indr = repmat((1:T)', [1, len_g+1]);
v = ones(T,1)*[1,-g];
ind = (indc>0);
G = sparse(indr(ind), indc(ind), v(ind), T, T);

%% run optimization
% cvx_solver(solver);

cvx_begin quiet
variable c(T)
minimize(0.5*(c-y)'*(c-y) + lam*(1-sum(g))*norm(c,1))
subject to
G*c >=0;
cvx_end

s = reshape(G*c, 1, []);
s(1) = 0;
c = reshape(c,1, []);


function sigma = dtiComputeImageNoise(dwRaw, bvals, brainMask, noiseCalcMethod)
% Compute image noise from a 4-d DWI image
%
% sigma = dtiComputeImageNoise(dwRaw, bvals, brainMask, [noiseCalcMethod])
%
% Takes in dwi data and returns sigma, the image noise
%
% dwRaw    - Nifti structure of the dwi data
% bvals    - A 1xN vector of bvalues for each volume in dwRaw
% brainMask- A 3-D matrix of binary values  denoting which voxels are
%            insided the brain. This is only necesary for noiseCalcMethod =
%            'b0'
% noiseCalcMethod- Whether to calculate the noise based on the corner of
%                  the image (default) or based on the standard deviation
%                  of the b=0 images ('b0').

if ~exist('noiseCalcMethod','var') || isempty(noiseCalcMethod)
    noiseCalcMethod = 'corner';
end

if strcmp('corner', noiseCalcMethod)

    % According to Henkelman (1985), the expected signal variance (sigma) can
    % be computed as 1.5267 * SD of the background (thermal) noise.
    sz = size(dwRaw.data);
    x  = 10;
    y  = 10;
    z  = round(sz(3)/2);

    [x,y,z,s] = ndgrid(x-5:x+5, y-5:y:5, z-5:z+5, 1:sz(4));
    noiseInds = sub2ind(sz, x(:), y(:), z(:), s(:));
    sigma     = 1.5267 * std(double(dwRaw.data(noiseInds)));

elseif strcmp('b0', noiseCalcMethod)

    % Number of volumes in the dw dataset
    numVols   = size(dwRaw.data,4);
    % Get brainmask indices
    brainInds = find(brainMask);
    % preallocate a 2d array (with a 2nd dimension that is a singleton). The
    % first dimension is the number of volumes and the 3rd is each voxel
    % (within the brain mask).
    data      = zeros(numVols,1,length(brainInds));
    % Loop over the volumes and assign the voxels within the brain mask to data
    for ii=1:numVols
        tmp = double(dwRaw.data(:,:,:,ii));
        data(ii,1,:) = tmp(brainInds);
    end

    % Find which volumes ar b=0
    b0inds = find(bvals ==  0);
    n = length(b0inds);
    % Pull out the b=0 volumes
    dataB0 = squeeze(data(b0inds,1,:));
    % Calculate the median of the standard deviation. We do not think that
    % this needs to be rescaled. Henkelman et al. (1985) suggest that this
    % aproaches the true noise as the signal increases.
    sigma = median(std(dataB0,0,1));

    % std of a sample underestimates sigma (see http://nbviewer.ipython.org/4287207/)
    % This can be very big for small n (e.g., 20% for n=2)
    % We can compute the underestimation bias:
    bias = sigma * (1 - sqrt(2 / (n-1)) * (gamma(n / 2) / gamma((n-1) / 2)));

    % and correct for it:
    sigma = sigma + bias;
end


function [MU,k]=vonMisesStat(T)

% function [MU,k]=vonMisesStat(T)
% ------------------------------------------------------------------------
%
%
% ------------------------------------------------------------------------

%%
MU=angle(mean(exp(1i.*T)));
Rsq=mean(cos(T)).^2+mean(sin(T)).^2;
R=sqrt(Rsq);

p=2;
ki=R.*(p-Rsq)./(1-Rsq);
diffTol=ki/1000;
qIter=1;
while 1
    kn=ki;
    A=besseli(p/2,ki)./ besseli((p/2)-1,ki);
    ki=ki-((A-R)./(1-A^2-((p-1)/ki)*A));
    if abs(kn-ki)<=diffTol
        break
    end
    qIter=qIter+1;
end
k=ki;

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% 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/>.


function mappedX = cfa(X, no_dims, no_analyzers, no_iterations)
%CFA Performs manifold charting on dataset X
%
%   mappedX = cfa(X, no_dims, no_analyzers, no_iterations)
%
% Performs manifold charting on dataset X to reduce its dimensionality to
% no_dims dimensions. The variable no_analyzers determines the number of
% local factor analyzers that is used in the mixture of factor analyzers
% (default = 40). The variable no_iterations sets the number of
% iterations that is employed in the EM algorithm (default = 200).
%

% This file is part of the Matlab Toolbox for Dimensionality Reduction.
% The toolbox can be obtained from http://homepage.tudelft.nl/19j49
% You are free to use, change, or redistribute this code in any way you
% want for non-commercial purposes. However, it is appreciated if you
% maintain the name of the original author.
%
% (C) Laurens van der Maaten, Delft University of Technology

    if ~exist('no_dims', 'var')
        no_dims = 2;
    end
    if ~exist('no_analyzers', 'var')
        no_analyzers = 40;
    end
    if ~exist('no_iterations', 'var')
        no_iterations = 200;
    end

    % Make sure data is zero-mean, unit-variance
    X = X - repmat(mean(X, 1), [size(X, 1) 1]);
    X = X ./ repmat(var(X, 1), [size(X, 1) 1]);

    % Initialize some parameters
    min_var = 1e-5;                     % minimum STD of Gaussians
    X = X';
    [D n] = size(X);
    c = no_analyzers;
    d = no_dims;

    % Randomly initialize the parameters of the CFA model
    SigmaN = repmat(eye(d), [1 1 n]);
    Z = rand(d, n) * .1;
    Pi = repmat(1 / c, [1 c]);
    Kappa = rand(d, c) * .1;
    Mu = randn(D, c) * .1;
    SigmaC = repmat(eye(d), [1 1 c]);
    Lambda = rand(D, d, c) * .1;
    Psi = zeros(D, D, c);
    for j=1:c
        tmp = zeros(D, D);
        tmp(1:size(tmp, 2) + 1:end) = rand(D, 1) * .05;
        Psi(:,:,j) = tmp + tmp';
    end

    % Perform the EM algorithm for the optimization
    iter = 0;
    while iter < no_iterations

        % E-step
        % ====================================================

        % Do some precomputations for speed
        invPsi = zeros(size(Psi));
        detSigmaC = zeros(1, c);
        detPsi = zeros(1, c);
        logPi = zeros(1, c);
        for j=1:c
            invPsi(:,:,j) = inv(Psi(:,:,j) + eye(D));
            detSigmaC(j) = det(SigmaC(:,:,j));
            detPsi(j) = det(Psi(:,:,j));
            logPi(j) = log(Pi(j));
        end

        % Compute matrices Epsilon, Vc, and m
        Eps = zeros(n, c);
        Vc = zeros(d, d, c);
        m = zeros(d, c);
        const = ((D + d) / 2) * log(2 * pi);
        for j=1:c

            % Precomputations
            Xnc = X - repmat(Mu(:,j), [1 n]);
            Znc = Z - repmat(Kappa(:,j), [1 n]);
            tmpProd = Lambda(:,:,j)' * invPsi(:,:,j) * Lambda(:,:,j);

            % Compute Epsilon
            for i=1:n
                normX = (Xnc(:,i) - Lambda(:,:,j) * Znc(:,i));
                Eps(i, j) = -logPi(j) + const ...
                            + (.5 * log(detSigmaC(j))) + (.5 * detPsi(j)) ...
                            + (.5 * trace(SigmaC(:,:,j) * (SigmaN(:,:,i) + Znc(:,i) * Znc(:,i)'))) ...
                            + (.5 * trace(SigmaN(:,:,i) * tmpProd)) ...
                            + (.5 * normX' * invPsi(:,:,j) * normX);
            end

            % Compute Vc and m
            Vc(:,:,j) = inv(SigmaC(:,:,j) + eps * eye(d)) + tmpProd;
            m(:,j) = Kappa(:,j) + (Vc(:,:,j) \ Lambda(:,:,j)') * invPsi(:,:,j) * mean(Xnc, 2);
        end

        % Update estimate of Q
        Q = (repmat(sum(exp(-Eps), 2), [1 c]) .^ -1) .* exp(-Eps);

        % Update estimate of SigmaN
        for i=1:n
            tmp = zeros(d, d);
            for j=1:c
                tmp = tmp + Q(i, j) * Vc(:,:,j);
            end

            % Compute covariance matrix
            SigmaN(:,:,i) = inv(tmp + eps * eye(d));           % code above gave us inv(SigmaN)
        end

        % Update estimate of Z (= mappedX)
        for i=1:n
            tmp = zeros(d, 1);
            for j=1:c
                tmp = tmp + (Q(i, j) * Vc(:,:,j) * m(:,j));
            end
            Z(:,i) = SigmaN(:,:,i) * tmp;
        end

        % M-step
        % ====================================================

        % Update estimate of Pi
        Pi = sum(Q, 1) ./ n;

        % Update estimate of Mu and Kappa
        for j=1:c
            tmpQ = Q(:,c) ./ sum(Q(:,c));
            Mu(:,c) = sum(repmat(tmpQ', [D 1]) .* X, 2);
            Kappa(:,c) = sum(repmat(tmpQ', [d 1]) .* Z, 2);
        end

        % Update estimate of SigmaC
        for j=1:c
            tmp = 0;
            tmpQ = Q(:,c) ./ sum(Q(:,c));
            for i=1:n
                Znc = Z(:,i) - Kappa(:,j);
                tmp = tmp + (tmpQ(i) * (SigmaN(:,:,i) + Znc * Znc'));
            end

            % Enforce some variance
            tmp(1:size(tmp, 1) + 1:end) = max(min_var, tmp(1:size(tmp, 1) + 1:end));
            SigmaC(:,:,j) = tmp;
        end

        % Update estimate of Lambda
        for j=1:c
            Sc = zeros(D, d);
            tmpQ = Q(:,j) ./ sum(Q(:,j));
            Xnc = X - repmat(Mu(:,j), [1 n]);
            Znc = Z - repmat(Kappa(:,j), [1 n]);
            for i=1:n
                Sc = Sc + tmpQ(i) * (Xnc(:,i) * Znc(:,i)');
            end
            Lambda(:,:,j) = Sc / (SigmaC(:,:,j) + eps * eye(d));
        end

        % Update estimate of Psi
        for j=1:c
            tmpPsi = zeros(D, D);
            tmpQ = Q(:,j) ./ sum(Q(:,j));
            Xnc = X - repmat(Mu(:,j), [1 n]);
            Znc = Z - repmat(Kappa(:,j), [1 n]);
            tmpProd = Lambda(:,:,j) * SigmaN(:,:,i) * Lambda(:,:,j)';
            for i=1:n
                tmpPsi(1:size(tmpPsi, 2) + 1:end) = tmpPsi(1:size(tmpPsi, 2) + 1:end) + ...
                    tmpQ(i) * (((Xnc(:,i) - Lambda(:,:,j) * Znc(:,i)) .^ 2)' + tmpProd(1:size(tmpProd, 2) + 1:end));
            end
            Psi(:,:,c) = tmpPsi;
        end

        % Update number of iterations
        iter = iter + 1;
        if rem(iter, 5) == 0
            fprintf('.');
        end
    end

    % Transpose to get lowdimensional data representation
    mappedX = Z';


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 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 [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 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 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 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