function significant = spectsignificance(tests,alpha)
%
% From a estiamtion of p-values through the specttest function,
% It returns 0 or 1 for each power of coherence value, if the p-value is
% below the level of significance 'alpha'.
%
% INPUTS:
%
% tests                 The output of specttest, i.e. a cell
%                       where each element corresponds to one subject
% alpha                 Significance level
%
% OUTPUT:
%
% significant           Struct with 4 fields: lower, higher, lower_corr, higher_corr.
%                       ('_corr' reflects to multiple comparisons correction)
%                       Each field has a field 'states', just like each
%                       element of tests, with fields state(k).psd and
%                       state(k).coh containing 1 if the value is
%                       significant and 0 otherwise
%
% Author: Diego Vidaurre, OHBA, University of Oxford (2017)

if nargin < 2, alpha = 0.01; end

significant = struct();
significant.higher = struct();
significant.higher.state = struct();
significant.higher_corr = struct();
significant.higher_corr.state = struct();
significant.lower = struct();
significant.lower.state = struct();
significant.lower_corr = struct();
significant.lower_corr.state = struct();

K = length(tests.higher.state);
for k = 1:K
    significant.higher.state(k).psd = tests.higher.state(k).psd < alpha;
    significant.higher_corr.state(k).psd = tests.higher_corr.state(k).psd < alpha;
    significant.lower.state(k).psd = tests.lower.state(k).psd < alpha;
    significant.lower_corr.state(k).psd = tests.lower_corr.state(k).psd < alpha;
    significant.higher.state(k).coh = tests.higher.state(k).coh < alpha;
    significant.higher_corr.state(k).coh = tests.higher_corr.state(k).coh < alpha;
    significant.lower.state(k).coh = tests.lower.state(k).coh < alpha;
    significant.lower_corr.state(k).coh = tests.lower_corr.state(k).coh < alpha;
end

end


function [a_vec, a_vec_flt] = KiserTMOv(hdrv, filenameOutput, tmo_alpha, tmo_dn_clamping, tmo_white, tmo_gamma, tmo_quality, tmo_video_profile)
%
%
%      KiserTMOv(hdrv, filenameOutput, tmo_alpha, tmo_dn_clamping, tmo_white, tmo_gamma, tmo_quality, tmo_video_profile)
%
%
%       Input:
%           -hdrv: a HDR video structure; use hdrvread to create a hdrv
%           structure
%           -filenameOutput: output filename (if it has an image extension,
%           single files will be generated)
%           -tmo_alpha: \alpha_A, \alpha_B, \alpha_C coefficients
%           costants in the paper (Equation 3a, 3b, and 3c)
%           -tmo_dn_clamping: a boolean value (0 or 1) for setting black
%           and white levels clamping
%           -tmo_white: white point;
%           -tmo_gamma: gamma for encoding the frame
%           -tmo_quality: the output quality in [1,100]. 100 is the best quality
%           1 is the lowest quality.%
%           -tmo_video_profile: the compression profile (encoder) for compressing the stream.
%           Please have a look to the profile of VideoWriter from the MATLAB
%           help. Depending on the version of MATLAB some profiles may be not
%           be present.
%
%     Copyright (C) 2013-17 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:
%     "Real-time Automated Tone Mapping System for HDR Video"
% 	  by Chris Kiser, Erik Reinhard, Mike Tocci and Nora Tocci
%     in IEEE International Conference on Image Processing, 2012
%
%

if(~exist('tmo_alpha', 'var'))
    tmo_alpha = 0.98;
end

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

if(~exist('tmo_white', 'var'))
    tmo_white = 1e6;
end

if(tmo_white <= 0.0)
    tmo_white = 1e6;
end

if(~exist('tmo_gamma', 'var'))
    tmo_gamma = -2.2;
end

if(tmo_gamma < 0)
    bsRGB = 1;
else
    bsRGB = 0;
end

if(~exist('tmo_quality', 'var'))
    tmo_quality = 95;
end

if(~exist('tmo_video_profile', 'var'))
    tmo_video_profile = 'MPEG-4';
end

name = RemoveExt(filenameOutput);
ext  = fileExtension(filenameOutput);

bVideo = 0;
writerObj = 0;

if(strcmp(ext, 'avi') == 1 | strcmp(ext, 'mp4') == 1)
    bVideo = 1;
    writerObj = VideoWriter(filenameOutput, tmo_video_profile);
    writerObj.FrameRate = hdrv.FrameRate;
    writerObj.Quality = tmo_quality;
    open(writerObj);
end

hdrv = hdrvopen(hdrv);

disp('Tone Mapping...');

beta_clamping   = 0.999;
beta_clamping_c = (1.0 - beta_clamping);

a_vec = [];
a_vec_flt = [];

maxLprev = 0;

mkdir(name);

for i=1:hdrv.totalFrames
    disp(['Processing frame ', num2str(i)]);
    [frame, hdrv] = hdrvGetFrame(hdrv, i);

    %only physical values
    frame = RemoveSpecials(frame);
    frame(frame < 0) = 0;

    if(tmo_dn_clamping)
        %clamp black and white levels
        L = RemoveSpecials(lum(frame));
        %compute CDF's histogram
        [histo, bound, ~] = HistogramHDR(L, 256, 'log10', [], 1);
        histo_cdf = cumsum(histo);
        histo_cdf = histo_cdf/max(histo_cdf(:));
        [~, ind] = min(abs(histo_cdf - beta_clamping));
        maxL = 10^(ind * (bound(2) - bound(1)) / 256 + bound(1));

        [~, ind] = min(abs(histo_cdf-beta_clamping_c));
        minL = 10^(ind * (bound(2) - bound(1)) / 256 + bound(1));

        frame(frame > maxL) = maxL;
        frame(frame < minL) = minL;
        frame = frame - minL;
    end

    %compute statistics for the current frame
    L = lum(frame);
    Lav = logMean(L);
    maxL = max(L(:));
    A = maxL - Lav;
    B = Lav - min(L(:));

    if(i == 1)
        maxLprev = maxL;
        Aprev = A;
        Bprev = B;
        aprev = 0.18 * 2^(2 * (B - A) / (A + B));
    end

    %leaky integration
    tmo_alpha_c = 1.0 - tmo_alpha;
    An = tmo_alpha_c * Aprev + tmo_alpha * A;
    Aprev = An;

    Bn = tmo_alpha_c * Bprev + tmo_alpha * B;
    Bprev = Bn;

    a = SceneKey(An, Bn);
    an = tmo_alpha_c * aprev + tmo_alpha * a;
    aprev = an;

    %tone mapping
    [frameOut, ~, ~] = ReinhardTMO(frame, an, tmo_white, 'global');

    %example
    a_vec = [a_vec, maxL];
    maxLn =  0.5 * maxLprev + 0.5 *maxL;
    maxLprev = maxLn;
    a_vec_flt = [a_vec_flt, maxLn ];

    %gamma/sRGB encoding
    if(bsRGB)
        frameOut = ClampImg(ConvertRGBtosRGB(frameOut, 0), 0, 1);
    else
        frameOut = ClampImg(GammaTMO(frameOut, tmo_gamma, 0, 0), 0, 1);
    end

    if(bVideo)
        writeVideo(writerObj, frameOut);
    else
        imwrite(frameOut, [name, '/frame_', sprintf('%.10d',i), '.', ext]);
    end

    %update statistics for the next frame
    Aprev = A;
    Bprev = B;
    aprev = a;
end
disp('OK');

if(bVideo)
    close(writerObj);
end

hdrvclose(hdrv);

end

function a = SceneKey(An, Bn)
    a = 0.18 * 2^(2 * (Bn - An) / (An + Bn));
end


function [DEM] = spm_ADEM_update(DEM,COV)
% Updates ADEM structure using conditional expectations
% FORMAT [DEM] = spm_ADEM_update(DEM,COV)
%
% DEM - DEM structure
% COV - Covariance of parameter (P) fluctuations (E): P(i + 1) = P(i) + E
%     - where cov(E) = COV*pC
%
% This routine updates posterior expectations about states and parameters
% by replacing prior expectations with posterior expectations (and
% similarly updating hidden states and causes to the final iteration). If
% called with an extra argument, the posterior variances of the
% parameters are also updated.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_ADEM_update.m 6506 2015-07-24 10:26:51Z karl $

% preliminaries
%--------------------------------------------------------------------------
if nargin < 2, COV = 0; end

% update states and parameters (model)
%--------------------------------------------------------------------------
n     = length(DEM.M);
C     = DEM.qP.C;
for i = 1:(n - 1)

    % states
    %----------------------------------------------------------------------
    qE          = DEM.qU.x{i};
    if ~isempty(qE)
        DEM.M(i).x = spm_unvec(qE(:,end),DEM.M(i).x);
    end

    % parameters
    %----------------------------------------------------------------------
    qE          = spm_vec(DEM.qP.P{i});
    DEM.M(i).pE = spm_unvec(qE,DEM.M(i).pE);

    if nargin > 1

        % parameter covariance
        %------------------------------------------------------------------
        pC          = DEM.M(i).pC;
        np          = length(pC);
        qC          = C(1:np,1:np);
        C           = C(np + 1:end,np + 1:end);
        DEM.M(i).pC = qC + COV*pC;

    end

end

for i = 1:n
    if ~isempty(DEM.M(i).v)
        DEM.M(i).v  = spm_unvec(DEM.qU.v{i}(:,end),DEM.M(i).v);
    end
end

% update states and action (process)
%--------------------------------------------------------------------------
n     = length(DEM.G);
for i = 1:(n - 1)
    DEM.G(i).x = spm_unvec(DEM.pU.x{i}(:,end),DEM.G(i).x);
end
for i = 1:n
    if ~isempty(DEM.G(i).v)
        DEM.G(i).v  = spm_unvec(DEM.pU.v{i}(:,end),DEM.G(i).v);
    end
end
if isfield(DEM.G,'a')
    DEM.G(n).a = spm_unvec(DEM.qU.a{n}(:,end),DEM.G(n).a);
end


function [ nuniq, b1, b2 ] = i4vec2_sorted_unique ( n, a1, a2 )

%*****************************************************************************80
%
%% I4VEC2_SORTED_UNIQUE keeps unique elements of a sorted I4VEC2.
%
%  Discussion:
%
%    Item I is stored as the pair A1(I), A2(I).
%
%    The items must have been sorted, or at least it must be the
%    case that equal items are stored in adjacent vector locations.
%
%    If the items were not sorted, then this routine will only
%    replace a string of equal values by a single representative.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of items.
%
%    Input, integer A1(N), A2(N), the array of N items.
%
%    Output, integer NUNIQ, the number of unique items.
%
%    Output, integer B1(N), B2(N), an array of NUNIQ unique items.
%
  nuniq = 0;

  if ( n <= 0 )
    return
  end

  itest = 1;
  nuniq = 1;
  b1(nuniq) = a1(itest);
  b2(nuniq) = a2(itest);

  for itest = 2 : n

    if ( a1(itest) ~= b1(nuniq) | a2(itest) ~= b2(nuniq) )

      nuniq = nuniq + 1;

      b1(nuniq) = a1(itest);
      b2(nuniq) = a2(itest);

    end

  end

  return
end


function se = cross3d
%CROSS3D Return a 3D structuring element with cross shape
%
%
%
%   ---------
%
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 30/09/2004.
%

%   HISTORY

se = zeros([3 3 3]);
se(1,2,2) = 1;
se(3,2,2) = 1;
se(2,:,:) = [0 1 0;1 1 1;0 1 0];


%ISVALDFILE Test whether the argument is a valid datafile or dataset
%
% 	N = ISVALDFILE(A);
% 	N = ISVALDFILE(A,M);
% 	N = ISVALDFILE(A,M,C);
%
% INPUT
%   A     Input argument, to be tested on datafile or dataset
%   M     Minimum number of objects per class in A
%   C     Minimum number of classes in A
%
% OUTPUT
%   N  1/0 if A is / isn't a valid datafile or dataset
%
% DESCRIPTION
% The function ISVALDFILE tests if A is a datafile or dataset that has
% at least C classes. It is an extension of ISVALDSET and can be used it
% when datasets as well as datafiles are allowed.
% For datafiles(sets) with soft or targets labels it is tested whether A
% has at least M objects.
%
% SEE ALSO (PRTools Guide)
% ISDATASET, ISMAPPING, ISDATAIM, ISFEATIM, ISCOMDSET, ISVALDSET

function n = isvaldfile(a,m,c)

	if nargin < 3 | isempty(c), c = 0; end
	if nargin < 2 | isempty(m), m = 0; end

	if nargout == 0
		if ~isdatafile(a)
			isdataset(a);
		end
	else
		n = 1;
		if ~isdatafile(a) & ~isdataset(a)
			n = 0;
			return
		end
	end

	if c == 1 & getsize(a,3) == 0
		;  % accept unlabeled dataset as having one class
	elseif c > 0 & getsize(a,3) == 0

		if nargout == 0
  		error([newline 'Labeled prdatafile(set) expected'])
		else
			n = 0;
		end

	elseif getsize(a,3) < c

		if nargout == 0
			error([newline 'Datafile(set) should have at least ' num2str(c) ' classes'])
		else
			n = 0;
		end

	end

	if islabtype(a,'crisp') & any(classsizes(a) < m)

		if nargout == 0
			if m == 1

				error([newline 'Classes should have at least one object.' newline ...
						'Remove empty classes by A = remclass(A).'])
			else
				cn = num2str(m);
				error([newline 'Classes should have at least ' cn ' objects.' ...
						newline 'Remove small classes by A = remclass(A,' cn ')'])
			end
		else
			n = 0;
		end

	end

	if islabtype(a,'soft','targets') & size(a,1) < m
		error([newline 'Datafile(set) should have at least ' num2str(m) ' objects'])
	end

return


% get image block - 4
function [img1, img2, img3, img4] = getImgBlock(img)

[h, w] = size(img);
h_cen = floor(h/2);
w_cen = floor(w/2);

img1 = img(1:h_cen+2, 1:w_cen+2);
img2 = img(1:h_cen+2, w_cen-1:w);
img3 = img(h_cen-1:h, 1:w_cen+2);
img4 = img(h_cen-1:h, w_cen-1:w);

% figure;imshow(img1);
% figure;imshow(img2);
% figure;imshow(img3);
% figure;imshow(img4);
%
% F1 = cat(2,img1, img2);
% figure;imshow(F1);
% F2 = cat(2,img3, img4);
% figure;imshow(F2);
% F = cat(1,F1, F2);
% figure;imshow(F);

end


function [fx,tx,pv,fv]=fxpefac(s,fs,tinc,m,pp)
%FXPEFAC PEFAC pitch tracker [FX,TT,PV,FV]=(S,FS,TINC,M,PP)
%
% Input:   s(ns)      Speech signal
%          fs         Sample frequency (Hz)
%          tinc       Time increment between frames (s) [0.01]
%                     or [start increment end]
%          m          mode
%                     'g' plot graph showing waveform and pitch
%                     'G' plot spectrogram with superimposed pitch
%                     'x' use external files for algorithm parameter
%                         initialization: fxpefac_g and fxpefac_w
%          pp         structure containing algorithm parameters
%
% Outputs: fx(nframe)     Estimated pitch (Hz)
%          tx(nframe)     Time at the centre of each frame (seconds).
%          pv(nframe)     Probability of the frame of being voiced
%          fv             structure containing feature vectors
%                           fv.vuvfea(nframe,2) = voiced/unvoiced GMM features

% References
%  [1]  S.Gonzalez and M. Brookes,
%       A pitch estimation filter robust to high levels of noise (PEFAC), Proc EUSIPCO,Aug 2011.

% Bugs/Suggestions
% (1) do long files in chunks
% (2) option of n-best DP

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

persistent w_u m_u v_u w_v m_v v_v dpwtdef
% initialize persistent variables
if ~numel(w_u)

    % voiced/unvoiced decision based on 2-element feature vector
    % (a) mean power of the frame's log-freq spectrum (normalized so its short-term average is LTASS)
    % (b) sum of the power in the first three peaks
    %===== VUV
    if nargin>3 && any(m=='x')
        fxpefac_g;    % read in GMM parameters
        fxpefac_w;     % read in Weights parameters
    else
        w_u=[0.2123723 0.207788 0.2701817 0.1293616 0.04741722 0.1328791 ]';

        m_u=[0.2220388 0.4067706 ;
            0.04567656 0.4016914 ;
            0.8415278 0.3192158 ;
            0.2194808 0.1910079 ;
            1.6347 0.5819833 ;
            1.181519 0.6996485 ];

        v_u=reshape([0.01413822 0.003357913 0.003357913 0.01786169 ;
            0.0009377269 0.0006220489 0.0006220489 0.03422057 ;
            0.1233703 0.004299293 0.004299293 0.007660504 ;
            0.01779449 0.002078821 0.002078821 0.001605052 ;
            1.110173 0.00718649 0.00718649 0.005734435 ;
            0.5477135 -0.00182316 -0.00182316 0.05659796 ]',[2 2 6]);

        w_v=[0.07758689 0.2109879 0.1856225 0.06853158 0.2701563 0.1871148 ]';

        m_v=[1.208656 0.3365564 ;
            1.216643 0.5971916 ;
            4.08585 1.240948 ;
            8.322102 1.349939 ;
            1.734108 1.168643 ;
            0.5107205 0.940308 ];

        v_v=reshape([0.06181574 0.002950501 0.002950501 0.004528442 ;
            0.2946077 0.01433284 0.01433284 0.02684239 ;
            2.508473 -0.03310555 -0.03310555 0.1098579 ;
            14.17252 -0.09009174 -0.09009174 0.07989255 ;
            0.5834894 -0.07854027 -0.07854027 0.1108958 ;
            0.05978017 0.005528601 0.005528601 0.1309329 ]',[2 2 6]);
    end
    %===== PDP
    %     dfm = -0.4238; % df mean
    %     dfv = 3.8968; % df variance (although treated as std dev here)
    %     delta = 0.15;
    %     dflpso=[dfm 0.5/(log(10)*dfv^2) -log(2*delta/(dfv*sqrt(2*pi)))/log(10)]; % scale factor & offset for df pdf
    %     dpwtdef=[1.0000, 0.8250, 1.3064, 1.9863]; % default DP weights
    dpwtdef=[1.0000, 0.8250, 0.01868, 0.006773, 98.9, -0.4238]; % default DP weights
    %===== END

end

% Algorithm parameter defaults

p.fstep=5;              % frequency resolution of initial spectrogram (Hz)
p.fmax=4000;            % maximum frequency of initial spectrogram (Hz)
p.fres = 20;            % bandwidth of initial spectrogram (Hz)
p.fbanklo = 40;         % low frequency limit of log filterbank (Hz)
p.mpsmooth = 201;       % width of smoothing filter for mean power
% p.maxtranf = 1000;      % maximum value of tranf cost term
p.shortut = 7;          % max utterance length to average power of entire utterance
p.pefact = 1.5;         % shape factor in PEFAC filter
p.numopt = 3;           % number of possible frequencies per frame
p.flim = [60 400];      % range of feasible fundamental frequencies (Hz)
p.w = dpwtdef;          % DP weights
% p.rampk = 1.1;          % constant for relative-amplitude cost term
% p.rampcz = 100;         % relative amplitude cost for missing peak
p.tmf = 2;              % median frequency smoothing interval (s)
p.tinc = 0.01;          % default frame increment (s)

% update parameters from pp argument

if nargin>=5 && isstruct(pp)
    fnq=fieldnames(pp);
    for i=1:length(fnq)
        if isfield(p,fnq{i})
            p.(fnq{i})=pp.(fnq{i});
        end
    end
end

% Sort out input arguments
if nargin>=3  && numel(tinc)>0
    p.tinc = tinc;   % 0.01 s between consecutive time frames
end
if nargin<4
    m='';
end

% Spectrogram of the mixture
fmin = 0; fstep = p.fstep; fmax = p.fmax;
fres = p.fres;  % Frequency resolution (Hz)
[tx,f,MIX]=spgrambw(s,fs,fres,[fmin fstep fmax],[],p.tinc);
nframes=length(tx);
txinc=tx(2)-tx(1);  % actual frame increment
%  ==== we could combine spgrambw and filtbankm into a single call to spgrambw or use fft directly ====
% Log-frequency scale
[trans,cf]=filtbankm(length(f),2*length(f)-1,2*f(end),p.fbanklo,f(end),'usl');
O = MIX*trans'; % Original spectrum in Log-frequency scale

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Amplitude Compression

% Calculate alpha based on LTASS ratios
ltass = stdspectrum(6,'p',cf);
auxf = [cf(1),(cf(1:end-1)+cf(2:end))./2,cf(end)];
ltass = ltass.*diff(auxf);                  % weight by bin width

% estimated ltass
O = O.*repmat(diff(auxf),nframes,1);     % weight spectrum by bin width

if tx(end)<p.shortut                        % if it is a short utterance
    eltass = mean(O,1);                     % mean power per each frequency band
    eltass = smooth(eltass,p.mpsmooth);     % smooth in log frequency
    eltass= eltass(:).';                    % force a row vector

    % Same mean power per frame as ltass
    cte = mean(ltass)/mean(eltass);
    eltass = eltass.*cte;                   % normalize to have the same mean as LTASS
    O = O.*cte;

    % Linear AC
    alpha = (ltass)./(eltass);
    alpha = alpha(:).';
    alpha = repmat(alpha,nframes,1);
    O = O.*alpha;                           % force O to have an average LTASS spectrum
    % ==== should perhaps exclude the silent portions ***
else                                        % long utterance
    tsmo = 2; % time smoothing over 1 sec
    stt = round(tsmo/txinc);
    filttime = [ones(stt,1); zeros(stt-1,1)];
    filtfreq = ones(1,p.mpsmooth);
    eltass = imfilter(O,filttime);
    eltass = imfilter(eltass,filtfreq);     % filter in time and log frequency

    % Same mean power per frame than ltass
    cte = repmat(mean(ltass),nframes,1)./mean(eltass,2);
    eltass = eltass.*repmat(cte,1,length(cf));
    O = O.*repmat(cte,1,length(cf));

    % Linear AC
    alpha = repmat(ltass,nframes,1)./(eltass);
    O = O.*alpha;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create the filter to detect the harmonics
ini = find(cf>2*cf(1));
sca = cf/cf(ini(1)); % normalize bin frequencies to start at approximately 0.5
sca = sca(sca<10.5 & sca>0.5);  % restrict to 0.5 - 10.5 times fundamental
filh = -log10(p.pefact-cos(2*pi*sca));
filh = filh-mean(filh);  % force filter to be zero mean
posit = find(sca>=1);  % ==== this should just equal ini(1) ====
if ~mod(length(posit),2)
    filh = [filh 0];  % force to be an odd length after central tap
end
negat = find(sca<1);
numz = length(posit)-1-length(negat);
filh = filh./max(filh);
filh = [zeros(1,numz) filh];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Filter the log-frequency scaled spectrogram
B = imfilter(O,filh);  % ==== no good reason to use imfilter here ====

% Feasible frequency range
numopt = p.numopt; % Number of possible fundamental frequencies per frame
flim = p.flim;
pfreq = find(cf>flim(1) & cf<flim(2));
ff = zeros(nframes,numopt);
amp = zeros(nframes,numopt);
for i=1:nframes
    [pos,peak]=findpeaks(B(i,pfreq),[],5/(cf(pfreq(2))-cf(pfreq(1)))); % ==== calculate some out of loop ====
    if numel(pos)
        [peak,ind]=sort(peak,'descend');
        pos = pos(ind);                     % indices of peaks in the B array
        posff = cf(pfreq(pos));             % frequencies of peaks
        fin = min(numopt,length(posff));
        ff(i,1:fin)=posff(1:fin);           % save both frequency and amplitudes
        amp(i,1:fin)=peak(1:fin);
        %     else
        %         ff(i,:)=0;          % ==== unnecessary since they start as zeros ====
        %         amp(i,:)=0;
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Probabilitly of the frame of being voiced

% voiced/unvoiced decision based on 2-element feature vector
% (a) mean power of the frame's log-freq spectrum (normalized so its short-term average is LTASS)
% (b) sum of the power in the first three peaks

pow = mean(O,2)*1e-6;
vuvfea = [pow sum(amp,2)./(pow*1e9)];

pru=gaussmixp(vuvfea,m_u,v_u,w_u);  % Probability of being unvoiced
prv=gaussmixp(vuvfea,m_v,v_v,w_v);  % Probability of being voiced

% pru = exp(pru);
% prv=exp(prv);    % Linear probability
% pv = prv./(prv+pru); % ==== better to write pv=(1+exp(pru-prv)).^(-1) ====
pv=(1+exp(pru-prv)).^(-1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Dynamic programming

% w(1): relative amp, voiced local cost
% w(2): median pitch deviation cost
% w(3): df cost weight
% w(4): max df cost
% w(5): relative amp cost for missing peaks (very high)
% w(6): df mean

w = p.w;

% Relative amplitude
camp = -amp./repmat(max(amp,[],2),1,numopt);  % relative amplitude used as cost
camp(amp==0)=w(5); % If no frequency found

% Time interval for the median frequency
tmf = p.tmf; % in sec
inmf = round(tmf/txinc);

%--------------------------------------------------------------------------
% FORWARDS
% Initialize values
cost = zeros(nframes,numopt);
prev = zeros(nframes,numopt);
medfx = zeros(nframes,1);
dffact=2/txinc;

% First time frame
% cost(1,:) = w(1)*ramp(1,:);
cost(1,:) = w(1)*camp(1,:);  % only one cost term for first frame
fpos = ff(1:min(inmf,end),1);
mf=median(fpos(pv(1:min(inmf,end))>0.6));   % calculate median frequency of first 2 seconds
if isnan(mf)
    mf=median(fpos(pv(1:min(inmf,end))>0.5));
    if isnan(mf)
        mf=median(fpos(pv(1:min(inmf,end))>0.4));
        if isnan(mf)
            mf=median(fpos(pv(1:min(inmf,end))>0.3)); % ==== clumsy way of ensuring that we take the best frames ====
            if isnan(mf)
                mf=0;
            end
        end
    end
end
medfx(1)=mf;

for i=2:nframes              % main dynamic programming loop
    if i>inmf
        fpos = ff(i-inmf:i,1);  % fpos is the highest peak in each frame
        mf=median(fpos(pv(1:inmf)>0.6));  % find median frequency over past 2 seconds
        if isnan(mf)
            mf=median(fpos(pv(1:inmf)>0.5));
            if isnan(mf)
                mf=median(fpos(pv(1:inmf)>0.4));
                if isnan(mf)
                    mf=median(fpos(pv(1:inmf)>0.3));% ==== clumsy way of ensuring that we take the best frames ====
                    if isnan(mf)
                        mf=0;
                    end
                end
            end
        end
    end
    medfx(i)=mf;
    % Frequency difference between candidates and cost
    df = dffact*(repmat(ff(i,:).',1,numopt) - repmat(ff(i-1,:),numopt,1))./(repmat(ff(i,:).',1,numopt) + repmat(ff(i-1,:),numopt,1));
    costdf=w(3)*min((df-w(6)).^2,w(4));

    % Cost related to the median pitch
    if mf==0                                   % this test was inverted in the original version
        costf = zeros(1,numopt);
    else
        costf = abs(ff(i,:) - mf)./mf;
    end
    [cost(i,:),prev(i,:)]=min(costdf + repmat(cost(i-1,:),numopt,1),[],2); % ==== should we allow the possibility of skipping frames ? ====
    cost(i,:)=cost(i,:)+w(2)*costf + w(1)*camp(i,:);  % add on costs that are independent of previous path

end

% Traceback

fx=zeros(nframes,1);
best = zeros(nframes,1);

nose=find(cost(end,:)==min(cost(end,:))); % ==== bad method (dangerous) ===
best(end)=nose(1);
% ff = [ff zeros(nframes,1)];  % not clear why this was here
fx(end)=ff(end,best(end));
for i=nframes:-1:2
    best(i-1)=prev(i,best(i));
    fx(i-1)=ff(i-1,best(i-1));
end

if nargout>=4
    fv.vuvfea=vuvfea;  % voiced-unvoiced features
    fv.best=best;  % selected path
    fv.ff=ff;  % pitch candidates
    fv.amp=amp;  % pitch candidate amplitudes
    fv.medfx=medfx;  % median pitch
    fv.w=w;  % DP weights
    fv.dffact=dffact;  % df scale factor
end

if ~nargout || any(m=='g') || any(m=='G')
    nax=0;  % number of axes sets to link
    msk=pv>0.5; % find voiced frames as a mask
    fxg=fx;
    fxg(~msk)=NaN; % allow only good frames
    fxb=fx;
    fxb(msk)=NaN; % allow only bad frames
    if any(m=='G') || ~nargout && ~any(m=='g')
        clf;
        spgrambw(s,fs,'ilcwpf'); % draw spectrogram with log axes
        hold on
        plot(tx,log10(fxg),'-b',tx,log10(fxb),'-r'); % fx track
        yy=get(gca,'ylim');
        plot(tx,yy(1)+yy*[-1;1]*(0.02+0.05*pv),'-k'); % P(V) track
        hold off
        nax=nax+1;
        axh(nax)=gca;
        if any(m=='g')
            figure;   % need a new figure if plotting two graphs
        end
    end
    if any(m=='g')
        ns=length(s);
        [tsr,ix]=sort([(1:ns)/fs 0.5*(tx(1:end-1)+tx(2:end))']); % intermingle speech and frame boundaries
        jx(ix)=1:length(ix); % create inverse index
        sp2fr=jx(1:ns)-(0:ns-1);  % speech sample to frame number
        spmsk=msk(sp2fr);   % speech sample voiced mask
        sg=s;
        sg(~spmsk)=NaN;   % good speech samples only
        sb=s;
        sb(spmsk)=NaN;    % bad speech samples only
        clf;
        subplot(5,1,1);
        plot(tx,pv,'-b',(1:ns)/fs,0.5*mod(cumsum(fx(sp2fr)/fs),1)-0.6,'-b');
        nax=nax+1;
        axh(nax)=gca;
        ylabel('\phi(t), P(V)');
        set(gca,'ylim',[-0.65 1.05]);
        subplot(5,1,2:3);
        plot((1:ns)/fs,sg,'-b',(1:ns)/fs,sb,'-r');
        nax=nax+1;
        axh(nax)=gca;
        subplot(5,1,4:5);
        plot(tx,fxg,'-b',tx,fxb,'-r');
        ylabel('Pitch (Hz)');
        %         semilogy(tx,fxg,'-b',tx,fxb,'-r');
        %         ylabel(['Pitch (' yticksi 'Hz)']);
        set(gca,'ylim',[min(fxg)-30 max(fxg)+30]);
        nax=nax+1;
        axh(nax)=gca;
    end
    if nax>1
        linkaxes(axh,'x');
    end
end

function y=smooth(x,n)
nx=length(x);
c=cumsum(x);
y=[c(1:2:n)./(1:2:n) (c(n+1:end)-c(1:end-n))/n (c(end)-c(end-n+2:2:end-1))./(n-2:-2:1)];


%--- help for abstvar/irf ---
%
%  Compute impulse response function from the given parameter values
%
%  ::
%
%     myirfs = irf(self, shock_names, irf_periods, params, Rfunc);
%
%  Args:
%
%     self (var object): var object
%
%     shock_names (cellstr): shocks to compute IRFs (has to be consistent with the names given in :func:`identification <var.identification>`)
%
%     irf_periods (int): number of periods to compute IRFs (default: 40)
%
%     params (vector): parameter values of the model. If empty MLE/posterior-mode values are used.
%
%     Rfunc (function handle): identification function. This is an output of :func:`identification <var.identification>`. (default: choleski identification)
%
%     girf_setup (struct|{empty}): structure containing information relevant
%        for the computation of generalized impulse response functions. If
%        empty, simple regime-specific impulse responses are computed, else
%        girfs are computed. In that case the relevant information to
%        provide in girf_setup is:
%        - nsims : (default=300) number of simulations for the integration.
%        Note that even setting girf_setup=struct() will trigger the
%        computation of girfs. But in that case only the default options
%        will apply.
%
%  Returns:
%
%     : struct containing IRFs
%
%  Note:
%
%     Only successful IRFs are returned. If the structure does not return some IRFs make sure that IRFs properly identified.
%
%
%    Other functions named irf
%
%       dsge/irf    generic/irf
%


%==================================================================
%                        General Data File
% Title: TETRAHEDRA
% Units: SI
% Dimensions: 2D
% Type of problem: Plane_Stress
% Type of Phisics: ELASTIC
% Micro/Macro: MACRO
%
%==================================================================

%% Data

Data_prb = {
'TRIANGLE';
'SI';
'2D';
'Plane_Stress';
'THERMAL';
'MACRO';
};

%% Coordinates
% Node                X                Y                Z

coord = [
   1        00000        00000
     2  1.00000e-02  1.00000e-02
     3        00000  2.00000e-02
     4  2.00000e-02        00000
     5  2.00000e-02  2.00000e-02
     6  1.00000e-02  3.00000e-02
     7  3.00000e-02  1.00000e-02
     8        00000  4.00000e-02
     9  4.00000e-02        00000
    10  3.00000e-02  3.00000e-02
    11  4.00000e-02  2.00000e-02
    12  2.00000e-02  4.00000e-02
    13  4.00000e-02  4.00000e-02
];

%% Conectivities
% Element        Node(1)                Node(2)                Node(3)                Node(4)                Material

connec = [
     1      5      2      4
     2      3      2      5
     3      1      2      3
     4      4      2      1
     5     12      6      5
     6      8      6     12
     7      3      6      8
     8      5      6      3
     9     11      7      9
    10      5      7     11
    11      4      7      5
    12      9      7      4
    13     13     10     11
    14     12     10     13
    15      5     10     12
    16     11     10      5
];

%% Variable Prescribed
% Node            Dimension                Value

dirichlet_data = [
                            1 1 0
                            3 1 0
                            8 1 0
];

%% Force Prescribed
% Node                Dimension                Value

pointload_complete = [
11 1 -1
];

%% Volumetric Force
% Element        Dim                Force_Dim

Vol_force = [
];

%% Group Elements
% Element        Group_num

Group = [
];

%% Initial Holes
% Elements that are considered holes initially
% Element

Initial_holes = [
];

%% Boundary Elements
% Elements that can not be removed
% Element

Boundary_elements = [
];

%% Micro gauss post
%
% Element

Micro_gauss_post = [
];

%% Micro Slave-Master
% Nodes that are Slaves
% Nodes             Value (1-Slave,0-Master)

Micro_slave = [
];

%% Nodes solid
% Nodes that must remain
% Nodes

nodesolid = unique(pointload_complete(:,1));

%% External border Elements
% Detect the elements that define the edge of the domain
% Element               Node(1)           Node(2)

External_border_elements = [
];

%% External border Nodes
% Detect the nodes that define the edge of the domain
% Node

External_border_nodes = [
];

%% Materials
% Materials that have been used
% Material_Num              Mat_density        Young_Modulus        Poisson

Materials = [
];


function value = r8_mop ( i )

%*****************************************************************************80
%
%% R8_MOP returns the I-th power of -1 as an R8 value.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer I, the power of -1.
%
%    Output, real R8_MOP, the I-th power of -1.
%
  if ( mod ( i, 2 ) == 0 )
    value = + 1.0;
  else
    value = - 1.0;
  end

  return
end


function M = callback_blurring( M, dir, options )

% callback_blurring - callback for the deconvolution with wavelets
%
%   M = callback_blurring( M, dir, options );
%
%   Copyright (c) 2007 Gabriel Peyre

if isfield(options, 'eta')
    eta = options.eta;
else
    eta = 5;
end
if isfield(options, 'eta')
    Jmin = options.Jmin;
else
    Jmin = 4;
end

n = sqrt(size(M,1));
M = reshape(M,n,n);

if dir==1
    % wavelet synthesis and then blurring
    M = perform_wavelet_transform(M, Jmin, -1, options );
    M = perform_blurring( M, eta );
else
    % transpose
    M = perform_blurring( M, eta );
    M = perform_wavelet_transform(M, Jmin, 1, options );
end

M = M(:);


function result = ssc_mc_omp(X, D, K)
    solver = spx.cluster.ssc.SSC_TOMP(X, D, K);
    result = solver.solve();
end


impts=zeros(yw*exf,xw*exf);
n_rendered=0;
weight=str2double(get(handles.weight,'String'));
size_fac=str2double(get(handles.size_fac_edit,'String'));

if get(handles.adv_cb,'Value') %if using advanced thresholding don't need r0 tolerances
    if get(handles.lp_N_cb,'Value') %if specifying tolerances for loc. prec.
        for i=nstart:nend
            if xc(i)>=1 && yc(i)>=1 && xc(i)<xw*exf && yc(i)<yw*exf && lp(i)*1000 >= lp_tol_min && lp(i)*1000 <= lp_tol_max && a0_err_all(i)/a0_all(i) <= fr_un && xf_err_all(i) <= max_unc && yf_err_all(i) <= max_unc
              wide=ceil(size_fac*lppix(i)*1.5+1);
              if xc(i)-wide>=1 && xc(i)+wide<xw*exf && yc(i)-wide>=1 && yc(i)+wide<yw*exf
                n_rendered=n_rendered+1;
                for j=xc(i)-wide:xc(i)+wide
                  for k=yc(i)-wide:yc(i)+wide
                    dx=double(j)-xf(i);
                    dy=double(k)-yf(i);
                    int=pi*lp2pix(i)*size_fac;
                    a=exp(-2*(dx*dx+dy*dy)/(size_fac*size_fac*lp2pix(i)))*N(i)*weight/int;
                    impts(k,j)=impts(k,j)+a;
                  end
                end
              end
            end
            waitbarxmod(i/nend,w); %update
        end
    else %if specifying tolerances for # of photons/molecule (N)
        for i=nstart:nend
            if xc(i)>=1 && yc(i)>=1 && xc(i)<xw*exf && yc(i)<yw*exf && N(i) >= N_tol_min && N(i) <= N_tol_max && a0_err_all(i)/a0_all(i) <= fr_un && xf_err_all(i) <= max_unc && yf_err_all(i) <= max_unc
              wide=ceil(size_fac*lppix(i)*1.5+1);
              if xc(i)-wide>=1 && xc(i)+wide<xw*exf && yc(i)-wide>=1 && yc(i)+wide<yw*exf
                n_rendered=n_rendered+1;
                for j=xc(i)-wide:xc(i)+wide
                  for k=yc(i)-wide:yc(i)+wide
                    dx=double(j)-xf(i);
                    dy=double(k)-yf(i);
                    int=pi*lp2pix(i)*size_fac;
                    a=exp(-2*(dx*dx+dy*dy)/(size_fac*size_fac*lp2pix(i)))*N(i)*weight/int;
                    impts(k,j)=impts(k,j)+a;
                  end
                end
              end
            end
            waitbarxmod(i/nend,w); %update
        end
    end
else %if not using advanced thresholding include r0 in tolerances
    if get(handles.lp_N_cb,'Value') %if specifying tolerances for loc. prec.
        for i=nstart:nend
            if xc(i)>=1 && yc(i)>=1 && xc(i)<xw*exf && yc(i)<yw*exf && lp(i)*1000 >= lp_tol_min && lp(i)*1000 <= lp_tol_max && r0_all(i) >= r0_tol_min && r0_all(i) <= r0_tol_max && r0_err_all(i)/r0_all(i) <= fr_un && a0_err_all(i)/a0_all(i) <= fr_un && xf_err_all(i) <= max_unc && yf_err_all(i) <= max_unc
              wide=ceil(size_fac*lppix(i)*1.5+1);
              if xc(i)-wide>=1 && xc(i)+wide<xw*exf && yc(i)-wide>=1 && yc(i)+wide<yw*exf
                n_rendered=n_rendered+1;
                for j=xc(i)-wide:xc(i)+wide
                  for k=yc(i)-wide:yc(i)+wide
                    dx=double(j)-xf(i);
                    dy=double(k)-yf(i);
                    int=pi*lp2pix(i)*size_fac;
                    a=exp(-2*(dx*dx+dy*dy)/(size_fac*size_fac*lp2pix(i)))*N(i)*weight/int;
                    impts(k,j)=impts(k,j)+a;
                  end
                end
              end
            end
            waitbarxmod(i/nend,w); %update
        end
    else %if specifying tolerances for # of photons/molecule (N)
        for i=nstart:nend
            if xc(i)>=1 && yc(i)>=1 && xc(i)<xw*exf && yc(i)<yw*exf && N(i) >= N_tol_min && N(i) <= N_tol_max && r0_all(i) >= r0_tol_min && r0_all(i) <= r0_tol_max && r0_err_all(i)/r0_all(i) <= fr_un && a0_err_all(i)/a0_all(i) <= fr_un && xf_err_all(i) <= max_unc && yf_err_all(i) <= max_unc
              wide=ceil(size_fac*lppix(i)*1.5+1);
              if xc(i)-wide>=1 && xc(i)+wide<xw*exf && yc(i)-wide>=1 && yc(i)+wide<yw*exf
                n_rendered=n_rendered+1;
                for j=xc(i)-wide:xc(i)+wide
                  for k=yc(i)-wide:yc(i)+wide
                    dx=double(j)-xf(i);
                    dy=double(k)-yf(i);
                    int=pi*lp2pix(i)*size_fac;
                    a=exp(-2*(dx*dx+dy*dy)/(size_fac*size_fac*lp2pix(i)))*N(i)*weight/int;
                    impts(k,j)=impts(k,j)+a;
                  end
                end
              end
            end
            waitbarxmod(i/nend,w); %update
        end
    end
end

thresh=impts*0+1;
impts=thresh.*(impts>thresh)+impts.*(impts<=thresh);
clear thresh;


function stateLogRow = getStateLogRowAtTime(stateLog, time)
    if(time <= min(stateLog(:,1)))
        stateLogRow = stateLog(1,:);
    elseif(time >= max(stateLog(:,1)))
        stateLogRow = stateLog(end,:);
    else
        frameTimeLwr = max(stateLog(stateLog(:,1)<=time,1));
        stateLogRowLwr = stateLog(stateLog(:,1)==frameTimeLwr,:);
        stateLogRowLwr = stateLogRowLwr(1,:);

        frameTimeUpr = min(stateLog(stateLog(:,1)>time,1));
        stateLogRowUpr = stateLog(stateLog(:,1)==frameTimeUpr,:);
        stateLogRowUpr = stateLogRowUpr(1,:);

        interpX = [stateLogRowLwr(1), stateLogRowUpr(1)];
        interpYx = [stateLogRowLwr(2), stateLogRowUpr(2)];
        interpYy = [stateLogRowLwr(3), stateLogRowUpr(3)];
        interpYz = [stateLogRowLwr(4), stateLogRowUpr(4)];
        interpYVx = [stateLogRowLwr(5), stateLogRowUpr(5)];
        interpYVy = [stateLogRowLwr(6), stateLogRowUpr(6)];
        interpYVz = [stateLogRowLwr(7), stateLogRowUpr(7)];

        posX = interp1(interpX,interpYx,time);
        posY = interp1(interpX,interpYy,time);
        posZ = interp1(interpX,interpYz,time);
        velX = interp1(interpX,interpYVx,time);
        velY = interp1(interpX,interpYVy,time);
        velZ = interp1(interpX,interpYVz,time);

        stateLogRow = stateLogRowLwr;
        stateLogRow(2:7) = [posX, posY, posZ, velX, velY, velZ];
    end
end


classdef chebtech2 < chebtech
%CHEBTECH2   Approximate smooth functions on [-1,1] with Chebyshev interpolants.
%
%   Class for approximating smooth functions on the interval [-1,1] using
%   function values at 2nd-kind Chebyshev points and coefficients of the
%   corresponding 1st-kind Chebyshev series expansion.
%
% Constructor inputs:
%   CHEBTECH2(OP) constructs a CHEBTECH2 object from the function handle OP. OP
%   should be vectorised (i.e., accept a vector input) and ouput a vector of
%   the same length. CHEBTECH2 objects allow for array-valued construction
%   (i.e., of an array-valued function), in which case OP should accept a column
%   vector of length N and return a matrix of size NxM.
%
%   CHEBTECH2(OP, DATA) constructs a CHEBTECH2 using the additional data
%   supplied in the DATA structure.  Fields currently recognized are:
%     DATA.VSCALE    (Default:  0)
%     DATA.HSCALE    (Default:  1)
%         The constructor builds a CHEBTECH2 with 'happiness' (see
%         HAPPINESSCHECK.m) relative to the maximum of the given vertical scale
%         DATA.VSCALE and the (column-wise) infinity norm of the sampled
%         function values of OP, and the fixed horizontal scale DATA.HSCALE. If
%         not given (or given as empty), the VSCALE defaults to 0 initially,
%         and HSCALE defaults to 1.
%   If any fields in DATA are empty or not supplied, or if DATA itself is empty
%   or not supplied, appropriate default values are set.
%
%   CHEBTECH2(OP, DATA, PREF) overrides the default behavior with that given by
%   the preference structure PREF. See CHEBTECH.TECHPREF for details.
%
%   CHEBTECH2(VALUES, ...) returns a CHEBTECH2 object which interpolates the
%   values in the columns of VALUES at 2nd-kind Chebyshev points and
%   CHEBTECH2({VALUES, COEFFS}, ... ) uses the Chebyshev coefficients passed in
%   COEFFS rather than computing them from VALUES. If VALUES, is empty then the
%   CHEBTECH2 is constructed directly from the COEFFS. If COEFFS are passed,
%   the resulting CHEBTECH2 is always deemed 'happy'.
%
% Examples: % Basic construction: f = chebtech2(@(x) sin(x))
%
%   % Construction with preferences:
%   p.sampleTest = 0; % See CHEBTECH.TECHPREF for details
%   f = chebtech2(@(x) sin(x), [], [], p)
%
%   % Array-valued construction:
%   f = chebtech2(@(x) [sin(x), cos(x), exp(x)])
%
% See also CHEBTECH, CHEBTECH.TECHPREF, CHEBPTS, HAPPINESSCHECK, REFINE.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CHEBTECH2 Class Description:
%
% The CHEBTECH2 class represents smooth functions on the interval [-1,1] using
% function values at 2nd-kind Chebyshev points and coefficients of the
% corresponding 1st-kind Chebyshev series expansion.
%
% The constructor is supplied with a handle that evaluates a given function on
% an increasingly fine Chebyshev 2nd-kind grid (see REFINE.m) until the
% representation is deemed 'happy' (see HAPPINESSCHECK.m). The resulting object
% can be used to evaluate and operate on the input function.
%
% More information can be found in the CHEBTECH class definition.
%
% Class diagram: [<<CHEBTECH>>] <-- [CHEBTECH2]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS CONSTRUCTOR:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function obj = chebtech2(op, data, pref)
            % Parse inputs.
            if ( (nargin == 0) || isempty(op) )
                % Return an empty CHEBTECH2 on null input:
                return
            end

            if ( (nargin < 2) || isempty(data) )
                    data = struct();
            end

            if ( (nargin < 3) || isempty(pref) )
                pref = chebtech.techPref();
            else
                pref = chebtech.techPref(pref);
            end

            data = chebtech.parseDataInputs(data, pref);

            % Force nonadaptive construction if PREF.FIXEDLENGTH is numeric and
            % we're not using contour integrals.
            if ( ~(isnumeric(op) || iscell(op)) && ...
                    ~isnan(pref.fixedLength) && ~pref.useTurbo )
                % Evaluate op on the Chebyshev grid of given size:
                op = feval(op, chebtech2.chebpts(pref.fixedLength));
            end

            % Actual construction takes place here:
            [obj, values] = populate(obj, op, data, pref);

            if ( isnumeric(op) || iscell(op) )
                % Set length of obj to PREF.FIXEDLENGTH (if it is non-trivial).
                if ( ~isnan(pref.fixedLength ) )
                    obj = prolong(obj, pref.fixedLength);
                end

                % No need to error check when constructing from discrete data.
                return
            elseif ( obj.ishappy )
                % Use contour integrals if requested.
                if ( pref.useTurbo )
                    obj = constructorTurbo(obj, op, pref);
                end

                % No need to error check if we are happy:
                return
            end

            % Check for NaNs (if not happy):
            if ( pref.extrapolate )
                % Check for NaNs in interior only (because extrapolate was on):
                if ( any(any(isnan(obj.coeffs(2:end-1,:)))) )
                    error('CHEBFUN:CHEBTECH2:chebtech2:nanEval', ...
                        'Function returned NaN when evaluated.')
                end
                % We make sure not to return NaNs at +1 and -1.
                valuesTemp = extrapolate(obj, values);
                valuesTemp([1 end], :) = valuesTemp([1,end],:);
                obj.coeffs = obj.vals2coeffs(valuesTemp);
            elseif ( any(isnan(obj.coeffs(:))) )
                % Here we throw an error if NaNs were encountered anywhere.
                error('CHEBFUN:CHEBTECH2:chebtech2:nanEval2', ...
                    'Function returned NaN when evaluated.')
            end
        end
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = true )

        % Aliasing:
        coeffs = alias(coeffs, m)

        % Angles of Chebyshev points. (i.e., acos(chebpts(n))
        t = angles(n)

        % Evaluate a Chebyshev interpolant using the barycentric formula:
        out = bary(x, values)

        % Compute Chebyshev barycentric weights:
        w = barywts(n)

        % Compute Chebyshev points (x) and optionally quadrature (w)
        % and barycentric (v) weights:
        [x, w, v, t] = chebpts(n);

        % Tensor product grid of Chebyshev points in 1D, 2D or 3D:
        out = tensorGrid(N, dom)

        % Convert coefficients to values:
        values = coeffs2vals(coeffs);

        % Make a CHEBTECH2 (constructor shortcut):
        f = make(varargin);

        % Compute Chebyshev quadrature weights:
        w = quadwts(n)

        % Refinement function for CHEBTECH2 construction (evaluates OP on grid):
        [values, points, giveUp] = refine(op, values, pref)

        % Return the value-based discretization class which uses CHEBTECH2:
        function disc = returnValsDisc()
            disc = @chebcolloc2;
        end

        % Convert values to coefficients:
        coeffs = vals2coeffs(values)

    end

end


function [img] = hyperConvert3d(img, h, w, numBands)
% HYPERCONVERT2D Converts an 2D matrix to a 3D data cube
% Converts a 2D matrix (p x N) to a 3D data cube (m x n x p)
% where N = m * n
%
% Usage
%   [M] = hyperConvert3d(M)
% Inputs
%   M - 2D data matrix (p x N)
% Outputs
%   M - 3D data cube (m x n x p)

if (ndims(img) ~= 2)
    error('Input image must be p x N.');
end

[numBands, N] = size(img);

if (1 == N)
    img = reshape(img, h, w);
else
    img = reshape(img.', h, w, numBands);
end

return;


function d =  testing(a,d)

 n= get_dim(d);
 r = zeros(n,1);
 for i=1:a.kmax
 	r =  r + a.alpha(i).*get_x(test(a.child{i},d));
 end

 r=sign(r);
%  if(c > 1)
%  	L=-ones(c)+2*eye(c);
% 	for i=1:n
% 		[mi ind]=min(sum(abs(repmat(r(i,:),c,1)-L),2));
% 		r(i,:)=L(ind,:);
% 	end
%  end

 d=set_x(d,r);
 d=set_name(d,[get_name(d) ' -> ' get_name(a)]);


function [] = baselineSIRFS(class,jobID)
%GETDEPTHIMAGE Summary of this function goes here
%   Detailed explanation goes here

globals
statesDir = jobDirs(class,jobID,'state');
sirfsstatedir = fullfile(cachedir,class,sprintf('baselineSIRFS%s',jobID));
mkdirOptional(sirfsstatedir);
fnames = getFileNamesFromDirectory(dmapDir,'types',{'.mat'});

fprintf('\n%%%%%%%%%%%% SIRFS %%%%%%%%%%%%\n');
%% Loading precomputed shape
for i=1:length(fnames)
%for i=1:length(fnames)
    sirfsdmapFile = fullfile(sirfsstatedir,fnames{i});
    if(exist(sirfsdmapFile,'file'))
        continue;
    end
    stateFile = fullfile(statesDir,fnames{i});
    state = load(stateFile);state=state.state;
    sirfsstate = getsirfsstate(state);
    savefunc(sirfsdmapFile,sirfsstate);
    %vis_PSIRFS(sirfsstate); pause
end
end

function savefunc(file,state)
    save(file,'state');
end

function sirfsstate = getsirfsstate(state)
    sigma = 3; % Controls the "bandwidth" of the input depth (the standard deviation of a Gaussian at which point the signal becomes reliable)
    mult = 5; % Controls the importance of the input depth (the multiplier on the loss)
    niters = 200;
    input_image = im2double(state.im);
    input_image(input_image<1/255) = 1/255;
    sirfsstate = SIRFS(input_image, (state.mask), [], ...
        ['params.DO_DISPLAY = 0; params.N_ITERS_OPTIMIZE = ' num2str(niters) ';']);
    sirfsstate.mask = state.mask;
    sirfsstate.im = input_image;
    sirfsstate.dmap = sirfsstate.height;
end


function f=burger(u,deriv)
if nargin<2,
	deriv=0;
end;
if deriv==0,
	f=0.5*u.^2;
else
	f=u;
end;


function run_test_single_model
% Copyright (c) 2014-present University of Illinois at Urbana-Champaign
% All rights reserved.
%
% Developed by:     Po-Sen Huang, Paris Smaragdis
%                   Department of Electrical and Computer Engineering
%                   Department of Computer Science
%
% Given a model, evaluate the performance.
    baseDir = '../../../';
    addpath([baseDir, filesep, 'codes']);
    addpath([baseDir, filesep, 'codes', filesep, 'denoising']);

    addpath([baseDir, filesep, 'tools', filesep,'bss_eval']);
    addpath([baseDir, filesep, 'tools', filesep,'bss_eval_3']);
    addpath([baseDir, filesep, 'tools', filesep,'labrosa']);

    ModelPath=[baseDir, filesep, 'codes',filesep,'denoising', filesep, 'demo'];

    global SDR;
    global SDR_bss3;

    SDR.deviter=0;   SDR.devmax=0;   SDR.testmax=0;
    SDR.devsar=0; SDR.devsir=0; SDR.testsar=0; SDR.testsir=0;
    SDR_bss3.deviter=0;   SDR_bss3.devmax=0;   SDR_bss3.testmax=0;
    SDR_bss3.devsar=0; SDR_bss3.devsir=0; SDR_bss3.testsar=0; SDR_bss3.testsir=0;

    j=870;

    % Load model
    load([ModelPath, filesep, 'denoising_model_', num2str(j),'.mat']);
    eI.saveDir = [baseDir, filesep, 'codes', filesep, 'denoising', ...
        filesep, 'demo', filesep, 'results', filesep];
    %%
    index = 2;
    [speech, fs] = audioread(['wav', filesep, 'original_speech', num2str(index), '.wav']);
    [noise, fs] = audioread(['wav', filesep, 'original_noise',num2str(index),'.wav']);

    x = speech + noise;
    eI.fs = fs;
    %%
    output = test_denoising_general_kl_bss3(x', theta, eI, 'testall', 0);
    %%
  	sz = 1024.*[1 1/4];
    wn = sqrt( hann( sz(1), 'periodic')); % hann window
    wav_singal = stft2( output.source_signal, sz(1), sz(2), 0, wn);
    wav_noise = stft2( output.source_noise, sz(1), sz(2), 0, wn);
    wav_singal = wav_singal./max(abs(wav_singal));
    wav_noise = wav_noise./max(abs(wav_noise));

    audiowrite([eI.saveDir, filesep,'separated_speech',num2str(index),'.wav'], wav_singal, fs);
    audiowrite([eI.saveDir, filesep,'separated_noise',num2str(index),'.wav'], wav_noise, fs);

    % Get separation stats
    [sdr,sir,sar,stoi] = sep_perf(wav_singal, [speech'; noise'], fs);
end


function f = floor(f)
%FLOOR   Pointwise floor function of a CHEBTECH.
%   G = FLOOR(F) returns the CHEBTECH G such that G(X) = FLOOR(F(x)) for each x
%   in [-1, 1].
%
%   If F is complex, then the G = FLOOR(REAL(F)) + 1i*FLOOR(IMAG(F)).
%
%   Note that FLOOR() assumes the output G(X) is a constant. If it is not, then
%   garbage is returned with no warning.
%
% See also CEIL, ROUND, FIX.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% Evaluate at the two end points, and an arbitrary interior point:
arbitraryPoint = 0.1273881594;
fx = feval(f, [-1 ; arbitraryPoint ; 1]);
% Take the mean:
meanfx = mean(fx, 1);
% Compute the floor:
f.coeffs = floor(meanfx);

end


function [s,xform] = relaxAlignAll(s, refImg, outMm, bb, interp)
%
% [s,xform] = relaxAlignAll(s, refImg, [outMm=refImg.pixdim], [bb=true], [interp=7])
%
% Aligns all the series in s to the NIFTI file (or struct) refImg.
% If refImg is empty, all series are aligned to the first series.
%
% If bb==true, then the bounding box will be taken from the reference
% image. If bb==false, it will be taken from the first image in the series.
% If bb is a valid bounding box, then that will be used.
%
%
% HISTORY:
% 2008.01.01 RFD: wrote it.
% 2008.10.06 RFD: fixed bug where s(1) was getting zeroed-out when refImg
% was empty.
% 2009.12.07 RFD: no longer set NANs to 0. NANs are useful for knowing what
% regions are outside the FOV. Also, changed it to use the actual transform
% from the dicom header.

if(~exist('refImg','var'))
  refImg = [];
end
if(ischar(s))
  s = dicomLoadAllSeries(s);
end
if(~exist('outMm','var'))
  outMm = [];
end
if(~exist('bb','var')||isempty(bb))
  bb = true;
end
if(~exist('interp','var')||isempty(interp))
  interp = 1;
end
if(numel(interp)<6)
   interp = [interp(1) interp(1) interp(1) 0 0 0];
end

% Don't try to process localizers...
locInds = ~cellfun('isempty',regexp({s.seriesDescription},'LOCALIZER'));
if(any(locInds))
    fprintf('Discarding series [%d] since they appear to be localizers.\n', find(locInds));
    s = s(~locInds);
end

nSeries = numel(s);

disp('Applying cannonical xform to all series...');
for(ii=1:nSeries)
    canXform = mrAnatComputeCannonicalXformFromDicomXform(s(ii).imToScanXform,size(s(ii).imData));
    [s(ii).imData,s(ii).mmPerVox] = applyCannonicalXform(s(ii).imData, canXform, s(ii).mmPerVox, false);
    % Now that the data have been flipped to our cannonical (axial)
    % orientation, we need to flip the imToScanXform to also reflect this
    % new orientation:
    s(ii).imToScanXform = inv(canXform*inv(s(ii).imToScanXform));
end

disp(['Aligning images to the first series "' s(1).seriesDescription '"...']);
s(1).xformToFirst = inv(s(1).imToScanXform);
Vfirst.uint8 = uint8(round(mrAnatHistogramClip(double(s(1).imData),0.3,0.99).*255));
Vfirst.mat = s(1).imToScanXform;

for(ii=2:nSeries)
    Vin.uint8 = uint8(round(mrAnatHistogramClip(double(s(ii).imData),0.3,0.99).*255));
    Vin.mat = s(ii).imToScanXform;
    evalc('transRot = spm_coreg(Vfirst, Vin);');
    fprintf('Series %d (%s) alignment: trans = [%0.4f %0.4f %0.4f], rot = [%0.4f %0.4f %0.4f].\n',ii,s(ii).seriesDescription,transRot);
    % Vin.mat\spm_matrix(transRot(end,:))*Vfirst.mat
    s(ii).xformToFirst = inv(Vin.mat)*spm_matrix(transRot(end,:));
end

if(~isempty(refImg))
    if(ischar(refImg))
        refImg = niftiRead(refImg);
    end
    disp(['Aligning first image to the template image in ' refImg.fname '...']);
    img = double(refImg.data);
    Vref.uint8 = uint8(round(mrAnatHistogramClip(img,0.4,0.98).*255));
    Vref.mat = refImg.qto_xyz;
    if(isempty(outMm))
        outMm = refImg.pixdim([1:3]);
    end

    if(numel(bb)~=6)
        if(bb)
            bb = mrAnatXformCoords(Vref.mat, [1 1 1; size(img)]);
        else
            bb = mrAnatXformCoords(Vref.mat, [1 1 1; size(s(1).imData)]);
        end
    end

    % Align to ref
    evalc('transRot = spm_coreg(Vref, Vfirst);');
    fprintf('Ref alignment: trans = [%0.4f %0.4f %0.4f], rot = [%0.4f %0.4f %0.4f].\n',transRot);
    % Vin.mat\spm_matrix(transRot(end,:))*Vfirst.mat
    disp('Resampling all series...');
    % Now resample
    for(ii=1:nSeries)
        fprintf('   resampling series %d...\n',ii);
        xf = s(ii).xformToFirst*spm_matrix(transRot(end,:));
        [s(ii).imData,s(ii).imToScanXform] = mrAnatResliceSpm(double(s(ii).imData), xf, bb, outMm, interp, 0);
    	s(ii).mmPerVox = outMm;
    end
else
    % No ref image- just resample everything to be aligned to the first
    % series and at outMm voxel size.
    if(numel(bb)~=6)
        bb = mrAnatXformCoords(Vfirst.mat, [1 1 1; size(s(1).imData)]);
    end
    if(isempty(outMm))
        outMm = s(1).mmPerVox;
    end
    disp('Resampling all series...');
    for(ii=1:nSeries)
        [s(ii).imData,s(ii).imToScanXform] = mrAnatResliceSpm(double(s(ii).imData), s(ii).xformToFirst, bb, outMm, interp, 0);
    	s(ii).mmPerVox = outMm;
    end
end
xform = s(1).imToScanXform;

return;


function BCType = CorrectBCTable_v2(EToV,VX,VY,BCType,fd,BCcode)

% function BCType = CorrectBCTable(EToV,BCType,fd,BCcode);
% Purpose: Setup BCType for boundary conditions in 2D
%
%    EToV   : Element-To-Vertice table
%    VX, VY : (x,y)-coordinates of mesh vertices
%    BCType : Table with types of faces for BC's
%    fd     : handle to distance function
%    BCcode : Integer for specific boundary type
%
% By Allan P. Engsig-Karup

Globals2D;

VNUM = [1 2;2 3;3 1]; % face orientations

pxc = 0.5*(VX(EToV)+VX(EToV(:,[2 3 1])));
pyc = 0.5*(VY(EToV)+VY(EToV(:,[2 3 1])));
dc  = abs(fd([pxc(:) pyc(:)])); % distances to boundaries from face centers
tol = 1e-4; % tolerance
idx = find(dc<tol);
BCType(idx) = BCcode;
return


function sgmga_write_tests ( )

%****************************************************************************80
%
%% SGMGA_WRITE_TESTS calls SGMGA_WRITE_TEST with various arguments.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 June 2010
%
%  Author:
%
%    John Burkardt
%
%  Local Parameters:
%
%    Local, real TOL, a tolerance for point equality.
%    A value of sqrt ( eps ) is reasonable, and will allow the code to
%    consolidate points which are equal, or very nearly so.  A value of
%    -1.0, on the other hand, will force the code to use every point, regardless
%    of duplication.
%
  addpath ( '../sandia_rules' );

  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SGMGA_WRITE_TESTS\n' );
  fprintf ( 1, '  Call SGMGA_WRITE_TEST with various arguments.\n' );
%
%  Set the point equality tolerance.
%
  tol = sqrt ( eps );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  All tests will use a point equality tolerance of %e\n', tol );

  dim_num = 2;
  for dim = 1 : dim_num
    importance(dim,1) = 1.0;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l2_ccxcc_iso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    importance(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l2_ccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 3;
  for dim = 1 : dim_num
    importance(dim,1) = 1.0;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 1, 1 ]';
  growth = [ 6, 6, 6 ]';
  np = [ 0, 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d3_l2_ccxccxcc_iso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 3;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 1, 1 ]';
  growth = [ 6, 6, 6 ]';
  np = [ 0, 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d3_l2_ccxccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 3;
  rule = [ 1, 3 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l3_ccxgp_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 4 ]';
  growth = [ 6, 3 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l2_ccxgl_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 7 ]';
  growth = [ 6, 3 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l2_ccxlg_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 8 ]';
  growth = [ 6, 3 ]';
  np = [ 0, 1 ]';
  np_sum = sum ( np(1:dim_num) );
  p(1) = 1.5;
  file_name = 'sgmga_d2_l2_ccxglg_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 2, 9 ]';
  growth = [ 6, 3 ]';
  np = [ 0, 2 ]';
  np_sum = sum ( np(1:dim_num) );
  p(1,1) = 0.5;
  p(2,1) = 1.5;
  file_name = 'sgmga_d2_l2_f2xgj_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );

  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 6, 10 ]';
  growth = [ 3, 4 ]';
  np = [ 1, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p(1) = 1.0;
  file_name = 'sgmga_d2_l2_gghxhgk_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  LEVEL_MAX 1
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 1;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l1_ccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  LEVEL_MAX 2 already done
%
%  LEVEL_MAX 3
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 3;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l3_ccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  LEVEL_MAX 4
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 4;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l4_ccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  LEVEL_MAX 5
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 5;
  rule = [ 1, 1 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l5_ccxcc_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  Dimension 3
%
  dim_num = 3;
  for dim = 1 : dim_num
    important(dim,1) = dim;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 2;
  rule = [ 1, 4, 5 ]';
  growth = [ 6, 3, 3 ]';
  np = [ 0, 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d3_l2_ccxglxgh_aniso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  Rule 3, LEVEL_MAX 4
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = 1.0;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 4;
  rule = [ 3, 3 ]';
  growth = [ 6, 6 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l4_gpxgp_iso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  Rule 3, Growth 4, LEVEL_MAX 4
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = 1.0;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 4;
  rule = [ 3, 3 ]';
  growth = [ 4, 4 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l4_gpsexgpse_iso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  Rule 3, Growth 5, LEVEL_MAX 4
%
  dim_num = 2;
  for dim = 1 : dim_num
    important(dim,1) = 1.0;
  end
  level_weight = sgmga_importance_to_aniso ( dim_num, importance );
  level_max = 4;
  rule = [ 3, 3 ]';
  growth = [ 5, 5 ]';
  np = [ 0, 0 ]';
  np_sum = sum ( np(1:dim_num) );
  p = [];
  file_name = 'sgmga_d2_l4_gpmexgpme_iso';
  sgmga_write_test ( dim_num, level_weight, level_max, rule, growth, np, p, tol, ...
    file_name );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SGMGA_WRITE_TESTS:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  rmpath ( '../sandia_rules' );

  return
end


function [feat,idxs_bbox_pair,cb1,cb2] = get_spatial_features_neighbour_locref(locations,idxs_bbox_pair,next_joints, locref)

cb1 = locations(idxs_bbox_pair(:,1), :);
cb2 = locations(idxs_bbox_pair(:,2), :);

delta = cb2 - cb1;

deltaReal_forward = delta + squeeze(locref(idxs_bbox_pair(:,2), 2, :));
deltaReal_backward = -delta + squeeze(locref(idxs_bbox_pair(:,1), 1, :));

deltaPred_forward = squeeze(next_joints(idxs_bbox_pair(:,1), 1, :));
deltaPred_backward = squeeze(next_joints(idxs_bbox_pair(:,2), 2, :));

feat = cat(2, deltaReal_forward, deltaReal_backward, ...
              deltaPred_forward, deltaPred_backward);


function gX = expKernDiagGradX(kern, X)

% EXPKERNDIAGGRADX Gradient of EXP kernel's diagonal with respect to X.
% FORMAT
% DESC computes the gradient of the diagonal of the exponentiated kernel matrix with
% respect to the elements of the design matrix given in X.
% ARG kern : the kernel structure for which gradients are being computed.
% ARG X : the input data in the form of a design matrix.
% RETURN gX : the gradients of the diagonal with respect to each element
% of X. The returned matrix has the same dimensions as X.
%
% SEEALSO : expKernParamInit, kernDiagGradX, expkernGradX
%
% COPYRIGHT : Neil D. Lawrence, 2006

% KERN

gX = kernDiagGradX(kern.argument, X);


% CORRIMAGE - compute correlation image between an event and amplitude
%               and phase in the time-frequency domain.
%
% Usage:
%     corrimage(data, sortvar, times);
%     [times, freqs, alpha, sigout, limits ] = corrimage(data, sortvar, ...
%                                    times, 'key1', val1, 'key2', val2, ...)
%
% Inputs:
%   data    - [float array] data of size (times,trials)
%   sortvar - [float array] sorting variable of size (trials)
%   times   - [float array] time indices for every data point. Size of
%             (times). Note: same input as the times vector for erpimage.
%
% Optional input:
%   'mode'     - ['phase'|'amp'] compute correlation of event values with
%                phase ('phase') or amplitude ('amp') of signal at the
%                given time-frequency points. Default is 'amp'.
%   'freqs'    - [min nfreqs max] build a frequency vector of size nfreqs
%                with frequency spaced in a log scale. Then compute
%                correlation at these frequency value.
%                Default is 50 points in a log scale between 2.5Hz to 50Hz.
%   'times'    - [float vector] compute correlation at these time value (ms).
%                (uses closest times points in 'times' input and return
%                them in the times output).
%                Default is 100 steps between min time+5% of time range and
%                max time-5%. Enter only 2 values [N X] to generate N
%                time points and trim by X %. If N is negative, uses it as
%                a subsampling factor [-3 5] trims times by 5% and subsample
%                by 3 (by subsampling one obtains a regularly spaced times).
%   'trim'     - [low high] low and high percentile of sorted sortvar values
%                to retain. i.e. [5 95] remove the 5 lowest and highest
%                percentile of sortvar values (and associated data) before
%                computing statistics. Default is [0 100].
%   'align'    - [float] same as 'align' parameter of ERPIMAGE. This
%                parameter is used to constrain the 'times' parameter so
%                correlation with data trials containing 0-values (as a
%                result of data alignment) are avoided: computing these
%                correlations would produce spurious significant results.
%                Default is no alignment.
%   'method'   - ['erpimage'|timefreq'] use either the ERPIMAGE function
%                of the TIMEFREQ function to compute spectral decomposition.
%                Default is 'timefreq' for speed reasons (note that both
%                methods should return the same results).
%   'erpout'   - [min max] regress out ERP using the selected time-window [min
%                max] in ms (the ERP is subtracted from the whole time period
%                but only regressed out in the selected time window).
%   'triallimit' - [integer array] specify trial boundaries for subjects. For
%                instance [1 200 400] indicates 2 subjects, trials 1 to 199
%                for subject 1 and trials 200 to 399 for subject 2. This is
%                currently only used for regressing erp out.
%
% Processing options:
%   'erpimopt' - [cell array] erpimage additional options (number of cycle ...).
%   'tfopt'    - [cell array] timefreq additional options (number of cycle ...).
%
% Plotting options:
%   'plotvals' - [cell array of output values] enter output values here
%                { times freqs alpha sigout} to replot them.
%   'nofig'    - ['on'|'off'] do not create figure.
%   'cbar'     - ['on'|'off'] plot color bar. Default: 'on'.
%   'smooth'   - ['on'|'off'] smooth significance array. Default: 'on'.
%   'plot'     - ['no'|'alpha'|'sigout'|'sigoutm'|'sigoutm2'] plot -10*log(alpha)
%                values ('alpha'); output signal (slope or ITC) ('sigout'),
%                output signal masked by significance ('sigoutm') or the last
%                2 option combined ('sigoutm2'). 'no' prevent the function
%                from plotting. In addition, see pmask. Default is 'sigoutmasked'.
%   'pmask'    - [real] maximum p value to show in plot. Default is 0.00001
%                (0.001 taking into account multiple comparisons (100)). Enter
%                0.9XXX to get the higher tail or a negative value (e.e., -0.001
%                to get both tails).
%   'vert'     - [real array] time vector for vertivcal lines.
%   'limits'   - [min max] plotting limits.
%
% Outputs:
%   times    - [float vector] vector of times (ms)
%   freqs    - [float vector] vector of frequencies (Hz)
%   alpha    - [float array] array (freqs,times) of p-values.
%   sigout   - [float array] array (freqs,times) of signal out (coherence
%              for phase and slope for amplitude).
%
% Important note: the 'timefreq' method may truncate the time window to
%                 compute the spectral decomposition at the lowest freq.
%
% Author: Arnaud Delorme & Scott Makeig, SCCN UCSD,
%         and CNL Salk Institute, 18 April 2003
%
% See also: ERPIMAGE

%123456789012345678901234567890123456789012345678901234567890123456789012

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

function [time, freq, alpha, sigout, limits, tf, sortvar] = corrimage(data, sortvar, timevect, varargin)

if nargin < 3
    help corrimage;
    return;
end

if isempty(timevect), timevect = [1 2]; end

% check inputs
% ------------
g = finputcheck(varargin, { 'freqs'    'real'   [0 Inf]    [2.5 50 50];
                            'times'    'real'   []         [100 5]; % see function at the end
                            'mode'     'string' { 'phase','amp' }  'amp';
                            'vert'     'real'   []         [];
                            'align'    { 'real','cell' }   []         [];
                            'plotvals' 'cell'   []         {};
                            'pmask'    'real'   []         0.00001;
                            'triallimit' 'integer'   []       [];
                            'trim'     'real'   [0 100]    [0 100];
                            'limits'   'real'   []         [];
                            'method'   'string' { 'erpimage','timefreq' }        'timefreq';
                            'plot'     'string' { 'no','alpha','sigout','sigoutm','sigoutp','sigoutm2' }  'sigoutm';
                            'nofig'    'string' { 'on','off' } 'off';
                            'cbar'     'string' { 'on','off' } 'on';
                            'smooth'   'string' { 'on','off' } 'off';
                            'erpout'   'real'   []             [];
                            'tfopt'    'cell'   []             {};
                            'erpimopt' 'cell'   []             {} });
if ischar(g), error(g); end

fprintf('Generating %d frequencies in log scale (ignore message on linear scale)\n', g.freqs(2));
g.freqs = logscale(g.freqs(1), g.freqs(3), g.freqs(2));

frames = length(timevect);
if size(data,1) == 1
    data = reshape(data, frames, size(data,2)*size(data,3)/frames);
end

% trim sortvar values
% -------------------
[sortvar sortorder] = sort(sortvar);
data = data(:, sortorder);
len = length(sortvar);
lowindex  = round(len*g.trim(1)/100)+1;
highindex = round(len*g.trim(2)/100);
sortvar = sortvar(lowindex:highindex);
data    = data(:, lowindex:highindex);
if lowindex ~=1 || highindex ~= length(sortorder)
    fprintf('Actual percentiles %1.2f-%1.2f (indices 1-%d -> %d-%d): event vals min %3.2f; max %3.2f\n', ...
             100*(lowindex-1)/len, 100*highindex/len, len, lowindex, highindex, min(sortvar), max(sortvar));
end

% assign subject number for each trial
% ------------------------------------
if ~isempty(g.triallimit)
    alltrials = zeros(1,len);
    for index = 1:length(g.triallimit)-1
        alltrials([g.triallimit(index):g.triallimit(index+1)-1]) = index;
    end
    alltrials = alltrials(sortorder);
    alltrials = alltrials(lowindex:highindex);
end

%figure; hist(sortvar)

% constraining time values depending on data alignment
% ----------------------------------------------------
srate = 1000*(length(timevect)-1)/(timevect(end)-timevect(1));
if ~isempty(g.align)

    if iscell(g.align)
        fprintf('Realigned sortvar plotted at %g ms.\n',g.align{1});
        shifts = round((g.align{1}-g.align{2})*srate/1000); % shifts can be positive or negative
        g.align = g.align{1};
    else
        if isinf(g.align)
            g.align = median(sortvar);
        end
        fprintf('Realigned sortvar plotted at %g ms.\n',g.align);

        % compute shifts
        % --------------
        shifts = round((g.align-sortvar)*srate/1000); % shifts can be positive or negative
    end

    %figure; hist(shifts)
    minshift = min(shifts); % negative
    maxshift = max(shifts); % positive
    if minshift > 0, error('minshift has to be negative'); end
    if maxshift < 0, error('maxshift has to be positive'); end

    % realign data for all trials
    % ---------------------------
    aligndata=zeros(size(data))+NaN; % begin with matrix of zeros()
    for t=1:size(data,2), %%%%%%%%% foreach trial %%%%%%%%%
        shft = shifts(t);
        if shft>0, % shift right
            aligndata(shft+1:frames,t)=data(1:frames-shft,t);
        elseif shft < 0 % shift left
            aligndata(1:frames+shft,t)=data(1-shft:frames,t);
        else % shft == 0
            aligndata(:,t) = data(:,t);
        end
    end % end trial
    data = aligndata(maxshift+1:frames+minshift,:);
    if any(any(isnan(data))), error('NaNs remaining after data alignment'); end
    timevect = timevect(maxshift+1:frames+minshift);

    % take the time vector subset
    % ---------------------------
    if isempty(timevect), error('Shift too big, empty time vector');
    else fprintf('Time vector truncated for data alignment between %1.0f and %1.0f\n', ...
                 min(timevect), max(timevect));
    end;
end

% regress out the ERP from the data (4 times to have residual ERP close to 0)
% ---------------------------------------------------------------------------
if ~isempty(g.erpout)
    %data = erpregout(data);
    %data = erpregout(data);
    %data = erpregout(data);
    disp('Regressing out ERP');
    erpbeg = mean(data,2);
    if ~isempty(g.triallimit)
        for index = 1:length(g.triallimit)-1
            trials = find(alltrials == index);
            %[data(:,trials) erp factors]= erpregout(data(:,trials), [timevect(1) timevect(end)], [300 400]);
            erpstart = mean(data(:,trials),2);
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            erpend = mean(data(:,trials),2);
            fprintf([ '***********************************************\n' ...
                      'Ratio in ERP after regression (compare to before) is %3.2f\n' ...
                      '***********************************************\n' ], mean(erpend./erpstart));
        end
    end
    erpend = mean(data,2);
    fprintf([ '***********************************************\n' ...
              'Ratio in grand ERP after regression (compare to before) is %3.2f\n' ...
              '***********************************************\n' ], mean(erpend./erpbeg));

    if 0
    %trials = find(alltrials == 1);
    data2 = data;
    dasf

    [data(:,trials) erp factors]= erpregout(data(:,trials), [timevect(1) timevect(end)], [300 400]);

    figure; subplot(1,2,1); erpimage(data, sortvar, timevect, '', 300, 500, 'erp');

    figure;
    subplot(1,2,1); erpimage(data2, sortvar, timevect, '', 300, 500, 'erp');
    subplot(1,2,2); erpimage(data , sortvar, timevect, '', 300, 500, 'erp');

    figure;
    subplot(1,2,1); erpimage(data2(:,trials), sortvar(trials), timevect, '', 0, 0, 'erp');
    subplot(1,2,2); erpimage(data (:,trials), sortvar(trials), timevect, '', 0, 0, 'erp');

    figure;
    for index = 1:length(g.triallimit)-1
        subplot(3,5,index);
        trials = find(alltrials == index);
        erpimage(data(:,trials), sortvar(trials), timevect, '', 50, 100, 'erp');
    end

    disp('Regressing out ERP');
    if ~isempty(g.triallimit)
        for index = 1:length(g.triallimit)-1
            trials = find(alltrials == index);
            [data(:,trials) erp factors]= erpregout(data(:,trials), [timevect(1) timevect(end)], [300 400]);
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            data(:,trials) = erpregout(data(:,trials));
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
            %data(:,trials) = erpregout(data(:,trials), [timevect(1) timevect(end)], g.erpout);
        end
    else
        %data = erpregout(data, [timevect(1) timevect(end)], g.erpout);
    end
    end
end

% generate time points
% --------------------
g.times = gettimes(timevect, g.times);
data = reshape(data, 1, size(data,2)*size(data,1));

% time frequency decomposition
% ----------------------------
if strcmpi(g.method, 'timefreq') && isempty(g.plotvals)
    data = reshape(data, length(data)/length(sortvar), length(sortvar));
    [tf, g.freqs, g.times] = timefreq(data, srate, 'freqs', g.freqs, 'timesout', g.times, ...
                                      'tlimits', [min(timevect) max(timevect)], 'wavelet', 3);
    outvar   = sortvar;
end

% compute correlation
% -------------------
if strcmpi(g.mode, 'phase') && isempty(g.plotvals)
    for freq = 1:length(g.freqs)
        fprintf('Computing correlation with phase %3.2f Hz ----------------------\n', g.freqs(freq));
        for time = 1:length(g.times)
            if strcmpi(g.method, 'erpimage')
                [outdata,outvar,outtrials,limits,axhndls,erp, ...
                 amps,cohers,cohsig,ampsig,outamps,phsangls,phsamp,sortidx] =erpimage(data,sortvar,timevect, ...
                        '', 0,0,g.erpimopt{:}, 'phasesort', [g.times(time) 0 g.freqs(freq)], 'noshow', 'yes');
            else
                phsangls = angle( squeeze(tf(freq, time, :))' );
            end

            % computing ITCs
            [ ITC(freq, time) alpha(freq, time) ] = ...
                    bootcircle(outvar/mean(outvar), exp(j*phsangls), 'naccu', 250);

            % accumulate 200 values, fitted with a normal distribution
            % --------------------------------------------------------
            %cmplx = outvar .* exp(j*phsangls)/mean(outvar);
            %ITC(freq, time) = mean(cmplx);
            %alpha(freq,time) = bootstat(outvar/mean(outvar), exp(j*phsangls), 'res = mean(arg1 .* arg2)', ...
            %                         'naccu', 100, 'vals', abs(ITC(freq, time)), 'distfit', 'norm');
        end
    end
    sigout = ITC;
elseif isempty(g.plotvals)
    for freq = 1:length(g.freqs)
        fprintf('Computing correlation with amplitude %3.2f Hz ----------------------\n', g.freqs(freq));
        for time = 1:length(g.times)
            if strcmpi(g.method, 'erpimage')
                [outdata,outvar,outtrials,limits,axhndls,erp, ...
                 amps,cohers,cohsig,ampsig,outamps,phsangls,phsamp,sortidx] =erpimage(data,sortvar,timevect, ...
                             '', 0,0,g.erpimopt{:}, 'ampsort', [g.times(time) 0 g.freqs(freq)], 'noshow', 'yes');
            else
                phsamp = abs(squeeze(tf(freq, time, :)))';
            end

            % computing ITCs
            [ypred alpha(freq, time) Rsq slope(freq, time)] = myregress(outvar, 20*log10(phsamp));
        end
    end;
    sigout = slope;
else
    g.times = g.plotvals{1};
    g.freqs = g.plotvals{2};
    alpha   = g.plotvals{3};
    sigout  = g.plotvals{4};
end

% plot correlation
% ----------------
if ~strcmp('plot', 'no')
    if ~isreal(sigout),
        if strcmpi(g.plot, 'sigoutp')
            sigoutplot = angle(sigout);
        else
            sigoutplot = abs(sigout);
        end
    else sigoutplot = sigout;
    end
    sigouttmp = sigoutplot;
    if strcmpi(g.smooth, 'on')
        tmpfilt = gauss2d(3,3,.3,.3);
        tmpfilt = tmpfilt/sum(sum(tmpfilt));
        alpha = conv2(alpha, tmpfilt, 'same');
    end

    % mask signal out
    if g.pmask > 0.5
        indices = find( alpha(:) < g.pmask);
        sigouttmp = sigoutplot;
        sigouttmp(indices) = 0;
    elseif g.pmask < 0 % both sides, i.e. 0.01
        sigouttmp = sigoutplot;
        indices = intersect_bc(find( alpha(:) > -g.pmask), find( alpha(:) < 1+g.pmask));
        sigouttmp(indices) = 0;
    else
        sigouttmp = sigoutplot;
        indices = find( alpha(:) > g.pmask);
        sigouttmp(indices) = 0;
    end

    if strcmpi(g.nofig, 'off'), figure; end
    switch g.plot
     case 'alpha',   limits = plotfig(g.times, g.freqs, -log10(alpha), g);
     case 'sigout',  limits = plotfigsim(g.times, g.freqs, sigoutplot, g);
     case { 'sigoutm' 'sigoutp' }, limits = plotfigsim(g.times, g.freqs, sigouttmp, g);
     case 'sigoutm2', limits = subplot(1,2,1); plotfigsim(g.times, g.freqs, sigoutplot, g);
                      limits = subplot(1,2,2); plotfigsim(g.times, g.freqs, sigouttmp, g);
    end
end

time = g.times;
freq = g.freqs;

return;

% formula for the normal distribution
% -----------------------------------
function y = norm(mu, sigma, x);

y = 1/sqrt(2) * exp( -(x-mu).^2/(sigma*sigma*2) ) / (sqrt(pi)*sigma);

% get time points
% ---------------
function val = gettimes(timevect, timevar);
    if length(timevar) == 2

        if timevar(1) > 0
            % generate linearly space vector
            % ------------------------------
            npoints = timevar(1);
            trim    = timevar(2);
            if length(timevect)-2*round(trim/100*length(timevect)) < npoints
                npoints = length(timevect)-round(trim/100*length(timevect));
            end
            fprintf('Generating %d times points trimmed by %1.1f percent\n', npoints, trim);
            timer = max(timevect) - min(timevect);
            maxt = max(timevect)-timer*trim/100;
            mint = min(timevect)+timer*trim/100;
            val = linspace(mint,maxt, npoints);
        else
            % subsample data
            % --------------
            nsub    = -timevar(1);
            trim    = timevar(2);
            len     = length(timevect);
            trimtimevect = timevect(round(trim/100*len)+1:len-round(trim/100*len));
            fprintf('Subsampling by %d and trimming data by %1.1f percent (%d points)\n', nsub, trim, round(trim/100*len));
            val = trimtimevect(1:nsub:end);
        end
    else
        val = timevar;
    end;

    % find closet points in data
    oldval = val;
    for index = 1:length(val)
        [dum ind] = min(abs(timevect-val(index)));
        val(index) = timevect(ind);
    end
    if length(val) < length(unique(val))
        disp('Warning: duplicate times, reduce the number of output times');
    end
    if all(oldval == val)
        disp('Debug msg: Time value unchanged by finding closest in data');
    end;

% get log scale (for frequency)
% -------------
function val = logscale(a,b,n);
    %val = [5 7 9]; return;
    val = linspace(log(a), log(b), n);
    val = exp(val);

% plot figure
% -----------
function limits = plotfig(times, freqs, vals, g)
    icadefs;
    imagesc(times, [1:size(vals,1)], vals);

    colormap(DEFAULT_COLORMAP);
    ticks = linspace(1, size(vals,1), length(freqs));
    ticks = ticks(1:4:end);
    set(gca, 'ytick', ticks);
    set(gca, 'yticklabel', num2str(freqs(1:4:end)', 3))

    xlabel('Time (ms)'); ylabel('Freq (Hz)');
    if ~isempty(g.limits), caxis(g.limits); end
    limits = caxis;
    if ~isempty(g.vert)
        for vert = g.vert(:)'
            hold on; plot([vert vert], [0.001 500], 'k', 'linewidth', 2);
        end
    end
    if strcmpi(g.cbar,'on')
        cbar;
    end

% plot figure with symmetrical phase
% ---------------------------------
function limits = plotfigsim(times, freqs, vals, g)
    icadefs;
    imagesc(times, [1:size(vals,1)], vals);

    colormap(DEFAULT_COLORMAP);
    ticks = linspace(1, size(vals,1), length(freqs));
    ticks = ticks(1:4:end);
    set(gca, 'ytick', ticks);
    set(gca, 'yticklabel', num2str(freqs(1:4:end)', 3))

    if ~isempty(g.limits)
        caxis(g.limits);
        limits = g.limits;
    else
        clim = max(abs(caxis));
        limits = [-clim clim];
        caxis(limits);
    end
    xlabel('Time (ms)'); ylabel('Freq (Hz)');
    if ~isempty(g.vert)
        for vert = g.vert(:)'
            hold on; plot([vert vert], [0.01 500], 'k', 'linewidth', 2);
        end
    end
    if strcmpi(g.cbar,'on')
        cbar;
    end
    return;

% -----------------------------------------
% plot time-freq point (when clicking on it
% -----------------------------------------
function plotpoint(data, sortvar, timevect, freq, timepnts);

figure;
subplot(2,2,1);
erpimage(act_all(:,:),sortvar_all,timepnts, ...
   '', 300,10,'erp', 'erpstd', 'caxis',[-1.0 1.0], 'srate',256,'align',352, 'yerplabel', '', erpimopt{:}, ...
                                                   'phasesort', [500 0 5]); % aligned to median rt

% plot in polar coordinates phase versus RT
% -----------------------------------------
phaseang2 = [phsangls phsangls-2*pi]; phaseang2 = movav(phaseang2,[], 100);
outvar2   = [outvar   outvar];   outvar2   = movav(outvar2,[], 100);
phaseang2 = phaseang2(length(phsangls)/2-50:length(phsangls)+length(phsangls)/2-50);
outvar2   = outvar2  (length(phsangls)/2-50:length(phsangls)+length(phsangls)/2-50);
subplot(2,2,3);
polar(phsangls, outvar, '.');
hold on; polar(phaseang2, outvar2, 'r');

% computing ITC
% -------------
cmplx = outvar .* exp(j*phsangls);
ITCval = mean(cmplx);
angle(ITCval)/pi*180;
abs(ITCval)/mean(outvar);
text(-1300,-1400,sprintf('ITC value: amplitude %3.4f, angle %3.1f\n', abs(ITCval)/mean(outvar), angle(ITCval)/pi*180));

% accumulate 200 values
% ---------------------
alpha = 0.05;
if exist('accarray') ~= 1, accarray = NaN; end
[sigval accarray] = bootstat(outvar/mean(outvar), phsangls, 'res = mean(arg1 .* exp(arg2*complex(0,1)))', ...
                      'accarray', accarray, 'bootside', 'upper', 'alpha', alpha);
text(-1300,-1600,sprintf('Threshold for significance at %d percent(naccu=200): %3.4f\n', alpha*100, sigval));
title(sprintf('Clust %d corr. theta phase at 500 ms and RT', clust));

% amplitude sorting
% -----------------
figure;
[outdata,outvar,outtrials,limits,axhndls,erp, ...
          amps,cohers,cohsig,ampsig,outamps,phsangls,phsamp,sortidx]=erpimage(act_all(:,:),sortvar_all,timepnts, ...
   '', 0,0,'erp', 'erpstd', 'caxis', 0.5, 'cbar', ...
   'srate',256,'align',352, 'yerplabel', '', erpimopt{:}, 'ampsort', [500 0 5]); % aligned to median rt
close;
subplot(2,2,2);
erpimage(act_all(:,:),sortvar_all,timevect, ...
   '', 300,10,'erp', 'erpstd', 'caxis', 0.5, 'cbar', ...
   'srate',256,'align',352, 'yerplabel', '', erpimopt{:}, 'ampsort', [500 0 5]); % aligned to median rt

% compute correlation
% -------------------
[ypred alpha Rsq] = myregress(outvar, phsamp);
subplot(2,2,4);
plot(outvar, phsamp, '.');
hold on;
plot(outvar, ypred, 'r');
xlabel('Reaction time');
ylabel('Amplitude');
title(sprintf('Theta amp. at 500 ms vs RT (p=%1.8f, R^2=%3.4f)', alpha, Rsq));
set(gcf, 'position', [336 485 730 540], 'paperpositionmode', 'auto');

setfont(gcf, 'fontsize', 10);
eval(['print -djpeg clust' int2str(clust) 'corrthetart.jpg']);

% set up for command line call
% copy text from plotcorrthetaart
%timevect = times;
sortvar = sortvar_all;
data = act_all;
time = 1
freq = 1
g.times = 0;
g.freqs = 5;
g.erpimopt = {};


function generalscript(path, lambdas, sigmas, tasks)

addpath(path);

kernelFID=fopen('all.kernel');
A=fread(kernelFID, 'float');
K=reshape(A,[sqrt(length(A)),sqrt(length(A))]);

perclassattributes = dlmread('all-perclass.attributes');
S = dlmread('all-perimage.attributes');
load experimentIndices

A=unique(perclassattributes, 'rows');
if length(dir('attrClasses*'))>0
    load attrClasses
    A=attrClasses;
end
% keyboard
attributesInput=A(trainClassesIndices,:);
attributesOutput=A(testClassesIndices,:);
nAttrs=size(A,2);
% allClass = dlmread('all.classid')+1;

% keyboard

nTrainingClasses=length(trainClassesIndices);
nTrainingInstances=length(trainInstancesIndices);

hist=[];
S=S(trainInstancesIndices,:);
Stest=attributesOutput;
% Stest(Stest==0)=-1;
% for i=1:size(Stest,1)
%     Stest(i,:)=Stest(i,:)-mean(Stest(i,:));
%     Stest(i,:)=Stest(i,:)/norm(Stest(i,:));
% end

for t=1:length(tasks)
    nNewTasks=tasks(t);

    disp('Getting labels...');

%     Y=zeros(nTrainingInstances,nTrainingClasses+nNewTasks);%-1;%-ones(nTrainingInstances,nTrainingClasses);%/(nTrainingClasses-1);
%     for i=1:nTrainingInstances
%         Y(i,trainInstancesLabels(i))=1;
%     end

    disp('Precalculating statistics...');
    KTrain=K(trainInstancesIndices, trainInstancesIndices);
    KK=KTrain'*KTrain;

%     S=[attributesInput; rand(nNewTasks, nAttrs)];
%     S=[attributesInput; sign(rand(nNewTasks, nAttrs)-0.5)];
%     S(S==0)=-1;
%     for i=1:size(S,1)
%         S(i,:)=S(i,:)-mean(S(i,:));
%         S(i,:)=S(i,:)/norm(S(i,:));
%     end

    KYS=KTrain*S;
    SS=S'*S;

    % keyboard
    for s=1:length(sigmas)
        sigma=sigmas(s);
        KYS_invSS=KYS/(SS+sigma*eye(size(S,2)));

        disp('Learning...');
        % step=10^-8;
        % for t=1:500
        % %     keyboard
        %     W = W - step * (XX*W*SS -XYS + lambda*W);
        % end
        for lambdaIndex=1:length(lambdas)
            lambda=lambdas(lambdaIndex);

            Alpha=(KK+lambda*KTrain)\KYS_invSS;

            disp('Predicting...');
            KTest=K(testInstancesIndices,trainInstancesIndices);

            pred=Stest*Alpha'*KTest';
            [scores, classPred]=max(pred',[],2);

            disp('Evaluating...');
            gt=testInstancesLabels;
            r=mean(gt==classPred')
%             confusionmat(gt, classPred')
            hist=[hist; [lambda, sigma, nNewTasks, r]];
        %     break;
            save('hist4', 'hist');
        end
    end
end
end


function val = get_params(CPD, name)
% GET_PARAMS Get the parameters (fields) for a gaussian_CPD object
% val = get_params(CPD, name)
%
% The following fields can be accessed
%
% mean       - mu(:,i) is the mean given Q=i
% cov        - Sigma(:,:,i) is the covariance given Q=i
% weights    - W(:,:,i) is the regression matrix given Q=i
%
% e.g., mean = get_params(CPD, 'mean')

switch name
 case 'mean',      val = CPD.mean;
 case 'cov',       val = CPD.cov;
 case 'weights',   val = CPD.weights;
 otherwise,
  error(['invalid argument name ' name]);
end