% Z_mean{i}: [num_components_for_subj_i x num_clusters]
%            contains posterior prob. of cluster membership
% cmp_keep:  [1 x num_subjects] list of preserved components for each
%           subject
% B_bar_mean{i,j}:  B-spline basis coefficients from cluster i to cluster j
%                   (note this is the transpose of my normal format)
% phi_t:        [num_b_splines x time] time-varying b-spline basis function
% Theta_diag:   [num_b_splines x num_PCs] FPCA weights for
%               self-connectivity
% Theta_offdiag: [num_b_splines x num_PCs] FPCA weights for
%               cross-connectivity
% NOTE: To obtain the 80x1 time-varying group PDC from cluster i to cluster
%       j -- F(i,j):
%       F(j,j) = phi_t'Theta_diag'B_bar_mean{j,j}
%       F(i,j) = phi_t'Theta_offdiag'B_bar_mean{i,j}  where j ~= i
%
% S_bar_mean:   [num_clusters x 3] MNI centroids for each cluster
%
%

%%
clear all; clc;

load real_data
load smoothing_outputs
load mcmc_outputs

%% Get posterior means spatial locations & connectivity coefs & indicators
S_bar_mean=zeros(M,3);
for i=1:size(S_BAR_array,1)
    S_bar_mean=S_bar_mean+S_BAR_array{i}/size(S_BAR_array,1);
end
B_bar_mean=cell(M,M);
for k1=1:M
    for k2=1:M
        B_bar_mean{k1,k2}=zeros(1,Q);
        for iter=1:size(B_BAR_array,1)
            B_bar_mean{k1,k2}=B_bar_mean{k1,k2}+B_BAR_array{iter}{k1,k2}/size(B_BAR_array,1);
        end
    end
end
Z_mean=cell(N,1);
for i=1:N
    Z_mean_i=Z_array{1}{i};
    for iter=2:size(Z_array,1)
        Z_mean_i=Z_mean_i+Z_array{iter}{i};
    end
    Z_mean_i=Z_mean_i/size(Z_array,1);
    Z_mean{i}=Z_mean_i;
end
%% Map posterior connectivities of group components
C_BAR_array=cell(size(B_BAR_array));
for iter=1:size(B_BAR_array,1)
    C_BAR_array{iter}=cell(M);
    for k1=1:M
        for k2=1:M
            if k1==k2
                C_BAR_array{iter}{k1,k2}=phi_t'*Theta_diag*B_BAR_array{iter}{k1,k2}';
            end
            if not(k1==k2)
                C_BAR_array{iter}{k1,k2}=phi_t'*Theta_offdiag*B_BAR_array{iter}{k1,k2}';
            end
        end
    end
end

labels = {'BA19/39 (+/-36,-70,23)' , 'BA31 (12,-41,-34)' , 'BA19 (-32,-70,22)' , 'BA32 (-16,13,34)' , 'BA32/ACC (1,30,29)' , 'BA24/MCC (1,-2,35)' , 'BA32 (20,7,32)' , 'BA6/preCG (52,-1,14)' , 'BA2/pCG (-33,-28,43)' , 'BA20 (-39,-9,-19)' , 'BA7/Cuneus (3,-73,32)' , 'Parietal WM (27,-35,37)'};

%% SELECT SIGNIFICANT COMPONENTS
num_subjects = length(subj_keep);
num_clusters = size(S_bar_mean,1);
T=80;
BASELINE = [-0.7 -0.5];
TAIL = 'both';
erWinCenterTimes = linspace(-0.75, 1.7188, T);

p_cmp = 0.5;  % probably threshold for cluster membership
p_sub = 0.5; % proportion of subjects that must be assigned (with probability > p_cmp) to a cluster in order to keep the cluster
p_M=zeros(num_clusters,num_subjects);  % p_M(k,i) probability that subject i has membership in cluster k
for k=1:num_clusters
    for i=1:num_subjects
        p_M(k,i)=max(Z_mean{i}(:,k));
    end
end
keep=zeros(num_clusters,1);
for k=1:num_clusters
    pr_k=sum(p_M(k,:)>p_cmp)/num_subjects;
    if pr_k>p_sub
        keep(k)=1;
    end
end
S_bar_mean=S_bar_mean(find(keep==1),:);
num_clusters = size(S_bar_mean,1);

%% PUT MNI COORDS IN DIPFIT STRUCTURE

%% insert symmetric dipole on opposite y-hemisphere
% indices of dual equivalent dipoles
dualEquivDipoles = 0;

for k=1:num_clusters
    centroids(k).momxyz = eps*ones(2,3);
    centroids(k).rv = 0;
    centroids(k).clustid = k;

    if ismember_bc(k,dualEquivDipoles)
        centroids(k).posxyz = [S_bar_mean(k,:); S_bar_mean(k,:).*[1 -1 1]];
        centroids(k).select = [1 2];
    else
        centroids(k).posxyz = [S_bar_mean(k,:); [0 0 0]];
        centroids(k).select = 1;
    end
end

%% do a dipplot of the cluster centroids

dipplot(centroids,'coordformat','Spherical','plot','on','projlines','on');

%% Create connectivity structure

M_keep=sum(keep);
ind_keep=find(keep==1);
alpha = 0.01;
if strcmpi(TAIL,'both')
    alpha=alpha/2;
end
% t_bl=10;    % time points 1:t_bl form baseline
q_l=alpha; % quantile for lower CI bound
q_u=1-alpha; % quantile for upper CI bound

baseidx = getindex(erWinCenterTimes,BASELINE);

C_bar_bl_mean=cell(size(C_BAR_array,1),1);
for iter=1:size(C_BAR_array,1)
    C_bar_bl_mean{iter}=zeros(M_keep);
    for k1=1:M_keep
        for k2=1:M_keep
            C_bar_bl_mean{iter}(k1,k2)=mean(C_BAR_array{iter}{ind_keep(k1),ind_keep(k2)}(baseidx(1):baseidx(2)));
        end
    end
end

C_bar_lower_keep=cell(M_keep);
C_bar_mean_keep=cell(M_keep);
C_bar_upper_keep=cell(M_keep);
C_bar_sgn_keep=cell(M_keep); % indicates which time points are significantly different from baseline mean
C_bar_keep=cell(M_keep);
for k1=1:M_keep
    for k2=1:M_keep
        C_bar_lower_keep{k1,k2}=zeros(T,1);
        C_bar_mean_keep{k1,k2}=zeros(T,1);
        C_bar_upper_keep{k1,k2}=zeros(T,1);
        C_bar_sgn_keep{k1,k2}=zeros(T,1);
        C_bar_keep{k1,k2}=zeros(T,1);
        for t=1:T
            tmp=zeros(size(C_BAR_array,1),1);
            for iter=1:size(C_BAR_array,1)
                tmp(iter)=C_BAR_array{iter}{ind_keep(k1),ind_keep(k2)}(t);
            end
            C_bar_lower_keep{k1,k2}(t)=prctile(tmp,100*q_l);
            C_bar_mean_keep{k1,k2}(t)=mean(tmp);
            C_bar_upper_keep{k1,k2}(t)=prctile(tmp,100*q_u);
            if strcmpi(TAIL,'both')
                if or((C_bar_lower_keep{k1,k2}(t)-C_bar_bl_mean{iter}(k1,k2))>0,(C_bar_upper_keep{k1,k2}(t)-C_bar_bl_mean{iter}(k1,k2))<0)
                    C_bar_sgn_keep{k1,k2}(t)=1; % significant
                end
            else
                if (C_bar_lower_keep{k1,k2}(t)-C_bar_bl_mean{iter}(k1,k2))>0
                    C_bar_sgn_keep{k1,k2}(t)=1; % significant
                end
            end
            C_bar_keep{k1,k2}(t)=exp(C_bar_mean_keep{k1,k2}(t))-1;
        end
    end
end

for i=1:M_keep
    for j=1:M_keep
        GroupConn.dDTF08(j,i,1,:) = C_bar_keep{i,j};
    end
end

GroupConn.erWinCenterTimes = erWinCenterTimes;
GroupConn.freqs = 5;  % 3-7 Hz

%% Create SIFT EEG structure
EEG_orig = pop_loadset('C:/aaa_wes/brains/multisubject_eeg/For_Wes/Data/eb79RespWrong_Connectivity.set');

SamplingRate = EEG_orig.srate;

EEG = eeg_emptyset;
EEG.data = zeros(EEG_orig.nbchan,T);
EEG.icaweights = eye(num_clusters,EEG_orig.nbchan);
EEG.icasphere =  EEG.icaweights';
EEG.icachansind = 1:num_clusters;
EEG.icaact = [];
EEG.srate = SamplingRate;
EEG.pnts = T;
EEG.trials = 1;
EEG.chanlocs = EEG_orig.chanlocs;
EEG.times = ((0:(EEG.pnts-1))/SamplingRate)*1000;   % ms
EEG.xmin = EEG.times(1);
EEG.xmax = EEG.times(end)/1000;  % sec
EEG.nbchan = EEG_orig.nbchan;
EEG.dipfit = EEG_orig.dipfit;
EEG.dipfit.model = centroids;
EEG.dipfit.chansel = 1:num_clusters;
EEG = eeg_checkset(EEG);
% pop_eegplot(EEG);

EEG.CAT.curComps = 1:num_clusters;
EEG.CAT.curComponentNames = labels(find(keep)); %strtrim(cellstr(num2str(EEG.CAT.curComps')))';
EEG.CAT.Conn = GroupConn;
EEG.CAT.MODEL = struct([]);
EEG.CAT.nbchan = num_clusters;
EEG.CAT.srcdata = EEG.data;

%% Make statistics
for i=1:size(EEG.CAT.Conn.dDTF08,1)
    for j=1:size(EEG.CAT.Conn.dDTF08,2)
        Stats.dDTF08.ci(1,j,i,1,:) = exp(C_bar_lower_keep{i,j})-1;  % lower bound
        Stats.dDTF08.ci(2,j,i,1,:) = exp(C_bar_upper_keep{i,j})-1;  % upper bound
        Stats.dDTF08.pval(j,i,1,:) = ~C_bar_sgn_keep{i,j}; %squeeze(Stats.dDTF08.ci(1,j,i,1,:))<=0 & squeeze(Stats.dDTF08.ci(2,j,i,1,:))>=0;  % insignificant if zero is contained within lower and upper bound
        Stats.alpha = 0.05;
    end
end

%%
pop_dipplot(EEG,1:num_clusters,'dipolelength',0,'spheres','on','projlines','on','coordformat','Spherical','num','on','dipnames',EEG.CAT.curComponentNames);

%% Visualize
[figureHandles tfgridcfg] = vis_TimeFreqGrid('ALLEEG',EEG,'Conn',EEG.CAT.Conn,'Stats',Stats,'MatrixLayout',{'Partial','UpperTriangle', 'dDTF08', 'LowerTriangle','dDTF08','Diagonal','none'},'TimesToPlot',[-0.7 1],'ColorLimits',[0 0.05],'Baseline',[],'Smooth2D',false,'Thresholding',{'Statistics','plotci',true,'ThresholdingMethod','pval','AlphaSignificance',0.05},'BackgroundColor',[0 0 0],'TextColor',[1 1 1],'LineColor',[0 0 0],'AxesFontSize',14);

%% threshold according to stats
load brainmovieconfig
EEGthresh = EEG;
EEGthresh.CAT.Conn.dDTF08(Stats.dDTF08.pval>=alpha) = 0;

cfg=pop_vis_causalBrainMovie3D(EEGthresh,cfg);


% demo_wavedet_3D_detector.m
% OVERVIEW This script demonstrates the usage of the wavedet_3D_detector function.
% The wavedet_3D_detector function detects QRS onset, Q, R, S, J fiducial points for ECG required to perform MV analysis for ECG.
%
% The inputs and outputs to the main wavedet_3D_detector function are listed below.
% INPUTS        MANDATORY           DESCRIPTION
%               sig_all (uV)            Single channel ECG in mV.
%
%               ext_anot                The reference R peaks generated using jsqi. Provided to assist in beat detection.
%
%               heasig                  Structure variable which contains
%                                       the following fields.
%               .nsamp                  Length of ecg data in sig_all in
%                                       samples.
%               .freq                   Sampling frequency for data in
%                                       sig_all.
%               .nsig                   Number of ecg channels in sig_all. Set to 1.
%
%               messages                            Strucuture variable with following field
%               .setup.wavedet.QRS_detection_only   Peforms fiducial point detection for the above listed
%                                                   points of interest when set to 1.
%
%
% OUTPUTS (of interest)
%               position                Structure variable which contains
%                                       the following fields of interest.
%               .QRSon                  QRS onset location for each beat in
%                                       sig_all variable.
%               .Q                      Q point locations for each beat in
%                                       the sig_all variable.
%               .R                      R point locations for each beat in
%                                       the sig_all variable.
%               .S                      S point locations for each beat in
%                                       the sig_all variable.
%               .QRSoff                 QRS offset locations for each beat
%                                       in the sig_all variable.
%               .Toff                   T offset locations for each beat in
%                                       the sig_all variable.
%
% The detected fiducial points may be plotted along with the ecg to verify
% the demo executed correctly.
%
%   REF:
%       The wavedet_3D_detector algorithm has been adapted from the
%       opensource ecgkit toolbox referenced below,
%       Demski AJ, Llamedo Soria M. ecg-kit a Matlab Toolbox for Cardiovascular Signal Processing.
%       Journal of Open Research Software. 2016;4(1):e8. DOI: http://doi.org/10.5334/jors.86
%
%   REPO:
%       https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox
%   ORIGINAL SOURCE AND AUTHORS:
%       Written by Ismail Sadiq
%	COPYRIGHT (C) 2019
%   LICENSE:
%       This software is offered freely and without warranty under
%       the GNU (v3 or later) public license. See license file for
%       more information. The license may be found in
%       the Documents folder of the Physionet-Cardiovascular-Signal-Toolbox.
%

% add toolbox dependencies
addpath(genpath('../../../../../PhysioNet-Cardiovascular-Signal-Toolbox-master/'));
addpath('../Tools/Annotation_generator/');
% load ecg data
sig = load('./testdata/mvm/sample_ecg_datam');
siginfo = readheader('./testdata/mvm/sample_ecg_datam.hea');
Fs = siginfo.freq;
ecg = (sig.val - siginfo.adczero)./siginfo.gain; % Adjust signal according to gain and dc offset
clear siginfo sig;

% generate annotations
HRVparams = InitializeHRVparams('MVanalysis');
[qrs_pos,sign,en_thres] = jqrs(ecg,HRVparams);
ECG_header.nsig = 1; ECG_header.freq = Fs; ECG_header.nsamp = length(ecg);
wavedet_config.setup.wavedet.QRS_detection_only = 0;
[ann,~,~] = wavedet_3D_detector(ecg, qrs_pos', ECG_header, wavedet_config );
% improve fiducial point detection
[detection_flg,ann] = improvfiducials(ann, Fs, ecg);

if(~detection_flg)
    disp('Warning: Unable to improve fiducial point detection.')
end

% Plotting annotations for verification
figure(2); plot(ecg); hold on;
stem(ann.QRSon, ecg(ann.QRSon)); stem(ann.Q, ecg(ann.Q));
stem(ann.R, ecg(ann.R)); stem(ann.S, ecg(ann.S));
stem(ann.QRSoff, ecg(ann.QRSoff)); stem(ann.Toff(~isnan(ann.Toff)), ecg(ann.Toff(~isnan(ann.Toff)))); hold off
legend('ECG','QRSon','Q','R','S','QRSoff','Toff')


% You can create a network and convert it to a format that can be viewed in
% Samiam by running this script.

pedigree = struct('parents', [0,0;1,3;0,0;1,3;2,6;0,0;2,6;4,9;0,0]);
pedigree.names = {'Ira','James','Robin','Eva','Jason','Rene','Benjamin','Sandra','Aaron'};
alleleFreqs = [0.1; 0.9];
alleleList = {'F', 'f'};
alphaList = [0.8; 0.6; 0.1];
phenotypeList = {'CysticFibrosis', 'NoCysticFibrosis'};
positions = [520, 600, 520, 500; 650, 400, 650, 300; 390, 600, 390, 500; 260, 400, 260, 300; 780, 200, 780, 100; 1040, 400, 1040, 300; 910, 200, 910, 100; 130, 200, 130, 100; 0, 400, 0, 300];

% This will construct a Bayesian network and convert it into a file that
% can be viewed in SamIam.

factorList = constructGeneticNetwork(pedigree, alleleFreqs, alphaList);
sendToSamiam(pedigree, factorList, alleleList, phenotypeList, positions, 'cysticFibrosisBayesNet');


function shepard_interp_1d_test ( )

%*****************************************************************************80
%
%% SHEPARD_INTERP_1D_TEST tests the SHEPARD_INTERP_1D library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 August 2012
%
%  Author:
%
%    John Burkardt
%
  addpath ( '../r8lib' )
  addpath ( '../test_interp' )

  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SHEPARD_INTERP_1D_TEST:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the SHEPARD_INTERP_1D library.\n' );
  fprintf ( 1, '  This test needs the TEST_INTERP library.\n' );

  prob_num = p00_prob_num ( );

  for prob = 1 : prob_num

    for p = 1 : [ 0.0, 1.0, 2.0, 4.0, 8.0 ];
      shepard_interp_1d_test01 ( prob, p );
    end

  end

  prob = 7;
  for p = 1 : [ 0.0, 1.0, 2.0, 4.0, 8.0 ];
    shepard_interp_1d_test02 ( prob, p );
  end
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SHEPARD_INTERP_1D_TEST:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  rmpath ( '../r8lib' )
  rmpath ( '../test_interp' )

  return
end


function all_XTr_pseudo = turn_training_simultaneous_data_into_pseudo_populations(all_XTr_simul, all_YTr, feature_to_siteID_mapping)

% A helper function takes simultaneously recorded training data and turns them into pseudo-populations.
%  This is useful for assessing whether training on shuffled data leads to similar performance (and decision boundaries)
%  as training with simultaneously recorded data (i.e., this allows one to compute I_diag as discussed by Averbeck, Latham and Pouget,
%  in Neural corelations, population coding, and computation, Nature Neuroscience May 2006).
%
%  Notes about the code:
%   1.  Care is taken so that if population vectors contain neuron's responses from multiple time periods,
%        when the data is shuffled, all data from the same trial (from a given site) will be permuted together.
%        This is important because mixing responses from the same trial (and site) into different population vectors could
%        lead to biased results since there are dependencies between time points in a trial.
%
%   2.  This code is slow.  It might be possible to write a faster version of the code (particularly
%        if one doesn't have totally different randomization for each label, etc).
%
%  Inputs:
%    all_XTr_simul{iTimePeriod}{iCV} = [num_features x num_points]  The simultaneously population training data
%    all_YTr The training labels  (can be a cell array for each time period or a vector having the same labels for all time periods)
%    feature_to_siteID_mapping{iTimePeriod} = a vector (length of num_features) that lists which site an a given feature
%      in all_XTr_simul came from (this is important so that all features from a given site are moved together).
%
%  Output:  all_XTr_pseudo, which is the simultaneous data converted into pseudo-populations

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

%     This code is part of the Neural Decoding Toolbox.
%     Copyright (C) 2011 by Ethan Meyers (emeyers@mit.edu)
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 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/>.

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

for iTimePeriod = 1:length(all_XTr_simul)
    for iCV = 1:length(all_XTr_simul{1})

        if iscell(all_YTr)
            curr_labels = all_YTr{iTimePeriod};
        else
            curr_labels = all_YTr;
        end
        unique_labels = unique(curr_labels);

        unique_site_numbers = unique(feature_to_siteID_mapping{iTimePeriod});

        all_XTr_pseudo{iTimePeriod}{iCV} = NaN .* ones(size(all_XTr_simul{iTimePeriod}{iCV}));

        for iLabel = unique_labels'

            curr_label_inds = find(curr_labels == iLabel);

            for iSite = unique_site_numbers

                curr_rand_label_inds = curr_label_inds(randperm(length(curr_label_inds)));

                site_feature_inds  = find(feature_to_siteID_mapping{iTimePeriod} == iSite);

                all_XTr_pseudo{iTimePeriod}{iCV}(site_feature_inds, curr_label_inds) = all_XTr_simul{iTimePeriod}{iCV}(site_feature_inds, curr_rand_label_inds);   %[num_neuron_features x num_trials]
            end
        end

    end
end


function fem = update11nbr(fem_struct,jj)
% update11nbr takes a node with 11 elements connected to it
%  (which defines a region) and addes 4 nodes and 8 elements
%  to that region then regroups so that no node has more than
%  six elements connected to it. The new nodes and elements are sprung.
%
% NOTE:  fem_struct.nei must be a component.
%
%  Variables
%  fem_struct -- finite element structure from opnml.
%  jj -- the node number that has 11 elements connected to it.
%  fem -- the updated finite element structure.
%        Note:  Only fem.x,fem.y,fem.z,fem.e, and fem.nei
%               get updated.  fem.bnd does not need to be updated.
%
%  Usage -- fem = update11nbr(fem_struct,jj)
%
%  Name: update11nbr.m
%  Written by: Ben Holladay
%  Date: June 22,2004
%  Updated:  Aug. 27, 2004 -- Chris Massey Fixed bug in .nei for the
%                                          3rd new node.
% Last Modifed:
%         Sept. 19, 2006 -- Chris Massey, NRL Code 7322, S.S.C. MS 39529
%                      % Add test to make sure the correct nodal neighbor
%                        connectivity existed for the requested update
%                        and added a test to create the nodal neighbor list
%                        if not present.
%         Aug. 13, 2007 -- Chris Massey, NRL Code 7322
%                     Fixed a bug in the code that updates nodal neighbor
%                     list for nodes getting extra connectivity.
%         July 14, 2008 -- Chris Massey, NRL Code 7322
%               moved test for 4 neighbors to after the test for nei.
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Checks if the fem_struct has an nei. If not one is generated.
try
    nei = fem_struct.nei;
catch
    fem_struct.nei = ele2nei(fem_struct.e,fem_struct.x,fem_struct.y);
    nei = fem_struct.nei;
end

tempnc = sum(~ismember((fem_struct.nei(jj,:)),0));
if tempnc ~= 11
    error(['There are ',num2str(tempnc),' nodal neighbors for node number ',...
           num2str(jj),'. This routine only works for 11 nodal neighbors.']);
end

%Sets the intial fem_struct variables.
x = fem_struct.x;
y = fem_struct.y;
z = fem_struct.z;
enodes = fem_struct.e;
vod = [1:11,1:11];

%Adds new nodes and elements and labels the bad node, neighboring nodes,
%and neighboring elements.
[nnodes,nc] = size(nei);
nelems = size(enodes,1);
newnode = nnodes + [1:4];
newelem = nelems + [1:8];
badnode = jj;
nbrnode = nei(jj,1:11);
[nbrelem,~] = find(enodes == badnode);
inrad = max(sqrt((x(nbrnode)-x(badnode)).^2 + (y(nbrnode)-y(badnode)).^2));

%First guess of the new coordinates and bathymetry.
Bx = sum(x([(nbrnode([1:3])),badnode]))/4;
By = sum(y([(nbrnode([1:3])),badnode]))/4;
Bz = sum(z([(nbrnode([1:3])),badnode]))/4;

Ax = sum([(x([(nbrnode([10,11,1]))]))',Bx])/4;
Ay = sum([(y([(nbrnode([10,11,1]))]))',By])/4;
Az = sum([(z([(nbrnode([10,11,1]))]))',Bz])/4;

Cx = sum([(x([(nbrnode([3:6]))]))',Bx])/5;
Cy = sum([(y([(nbrnode([3:6]))]))',By])/5;
Cz = sum([(z([(nbrnode([3:6]))]))',Bz])/5;

Ex = sum(x([(nbrnode([7:10])),badnode]))/5;
Ey = sum(y([(nbrnode([7:10])),badnode]))/5;
Ez = sum(z([(nbrnode([7:10])),badnode]))/5;

Dx = sum([(x([(nbrnode([6:7]))]))',Bx,Ax,Cx,Ex])/6;
Dy = sum([(y([(nbrnode([6:7]))]))',By,Ay,Cy,Ey])/6;
Dz = sum([(z([(nbrnode([6:7]))]))',Bz,Az,Cz,Ez])/6;

x(badnode) = Ax;
y(badnode) = Ay;
z(badnode) = Az;
x(newnode(1)) = Bx;
y(newnode(1)) = By;
z(newnode(1)) = Bz;
x(newnode(2)) = Cx;
y(newnode(2)) = Cy;
z(newnode(2)) = Cz;
x(newnode(3)) = Dx;
y(newnode(3)) = Dy;
z(newnode(3)) = Dz;
x(newnode(4)) = Ex;
y(newnode(4)) = Ey;
z(newnode(4)) = Ez;

%Updates the effected elements. J variables are used to represent which
%elements are connected each node.
i = 1;
while i <= 9
    j1 = ismember((enodes((nbrelem),:)),(nbrnode(vod(i))));
    j2 = ismember((enodes((nbrelem),:)),(nbrnode(vod(i+1))));
    spb = [1,1,2,2,2,3,4,4,4];
    j = sum([j1,j2],2);
    temp = nbrelem(find (j == 2));
    if ~isempty(temp)
        enodes(temp,:) = ([nbrnode(vod(i)),nbrnode(vod(i+1)),newnode(spb(i))]);
    end
    i = i + 1;
    clear j j1 j2 temp;
end

%Addes the 8 new elements.
enodes(newelem(1),:) = [nbrnode(1),newnode(1),badnode];
enodes(newelem(2),:) = [nbrnode(3),newnode(2),newnode(1)];
enodes(newelem(3),:) = [newnode(1),newnode(2),newnode(3)];
enodes(newelem(4),:) = [newnode(1),newnode(3),badnode];
enodes(newelem(5),:) = [badnode,newnode(3),newnode(4)];
enodes(newelem(6),:) = [nbrnode(10),badnode,newnode(4)];
enodes(newelem(7),:) = [nbrnode(6),newnode(3),newnode(2)];
enodes(newelem(8),:) = [nbrnode(7),newnode(4),newnode(3)];

M(1,:) = ([Ax,Ay,Az]);
M(2,:) = ([Bx,By,Bz]);
M(3,:) = ([Cx,Cy,Cz]);
M(4,:) = ([Dx,Dy,Dz]);
M(5,:) = ([Ex,Ey,Ez]);

%Springs the region.
i = 1;
imax = 20;
stoptol = 10e-8 * inrad;
tol = stoptol + 10;
while i <= imax && tol > stoptol
    M2(2,1) = sum([(x([(nbrnode([1:3])),badnode]))',M(3,1),M(4,1)]);
    M2(2,2) = sum([(y([(nbrnode([1:3])),badnode]))',M(3,2),M(4,2)]);
    M2(2,3) = sum([(z([(nbrnode([1:3])),badnode]))',M(3,3),M(4,3)]);

    M2(1,1) = sum([(x([(nbrnode([10,11,1]))]))',M(2,1),M(4,1),M(5,1)]);
    M2(1,2) = sum([(y([(nbrnode([10,11,1]))]))',M(2,2),M(4,2),M(5,2)]);
    M2(1,3) = sum([(z([(nbrnode([10,11,1]))]))',M(2,3),M(4,3),M(5,3)]);

    M2(3,1) = sum([(x([(nbrnode([3:6]))]))',M(2,1),M(4,1)]);
    M2(3,2) = sum([(y([(nbrnode([3:6]))]))',M(2,2),M(4,2)]);
    M2(3,3) = sum([(z([(nbrnode([3:6]))]))',M(2,3),M(4,3)]);

    M2(5,1) = sum([(x([(nbrnode([7:10]))]))',M(4,1),M(1,1)]);
    M2(5,2) = sum([(y([(nbrnode([7:10]))]))',M(4,2),M(1,2)]);
    M2(5,3) = sum([(z([(nbrnode([7:10]))]))',M(4,3),M(1,3)]);

    M2(4,1) = sum([(x([(nbrnode([6:7]))]))',M(2,1),M(1,1),M(3,1),M(5,1)]);
    M2(4,2) = sum([(y([(nbrnode([6:7]))]))',M(2,2),M(1,2),M(3,2),M(5,2)]);
    M2(4,3) = sum([(z([(nbrnode([6:7]))]))',M(2,3),M(1,3),M(3,3),M(5,3)]);
    M2 = M2./ 6;

    tol = max(sqrt((M2(:,1)-M(:,1)).^2 + (M2(:,2)-M(:,2)).^2));

    M = M2;
    x([badnode,([newnode(1:4)])]) = ([M(:,1)]);
    y([badnode,([newnode(1:4)])]) = ([M(:,2)]);
    z([badnode,([newnode(1:4)])]) = ([M(:,3)]);
    i = i + 1;
end

%Creates the output structure.
fem = fem_struct;
fem.e = enodes;
fem.x = x;
fem.y = y;
fem.z = z;
fem.nei = nei;

%Update the connectivity for the bad node and adds the connections for
%the new nodes.
fem.nei(badnode,1:nc) = ([newnode([1,3,4]),nbrnode([10,11,1]),zeros(1,nc-6)]);
fem.nei(newnode(1),1:nc) = ([badnode,nbrnode([1:3]),newnode([2,3]),zeros(1,nc-6)]);
fem.nei(newnode(2),1:nc) = ([newnode(1),nbrnode([3:6]),newnode(3),zeros(1,nc-6)]);
fem.nei(newnode(3),1:nc) = ([badnode,newnode([1,2]),nbrnode([6:7]),newnode(4),zeros(1,nc-6)]); %TCM 8/27/04
fem.nei(newnode(4),1:nc) = ([nbrnode([7:10]),badnode,newnode(3),zeros(1,nc-6)]);

%Updates the nei for neighbor nodes. These nodes get an additional
%connector.
spb = ([1,3,6,7,10]);
for i = 1:5
    addconn = ([badnode,newnode([1:4]),badnode]);
    tmp = nei(nbrnode(spb(i)),:);
	ij = find(tmp == badnode);
    ik = min((find(tmp == 0)) + 1);
    if isempty(ik)  % TCM 08/13/2007 -- Added this check in case ik was empty.
       ik = size(nei,2)+1;
    end
    fem.nei(nbrnode(spb(i)),1:ik) = ([tmp(1:(ij-1)),addconn(i+1),addconn(i),tmp((ij+1):(ik-1))]);
end

%Updates the nei for neighbor nodes. These nodes get different connector.
spn = ([2,4,5,8,9]);
for i = 1:5
    addnode = ([newnode(1),newnode(2),newnode(2),newnode(4),newnode(4)]);
    tmp = nei(nbrnode(spn(i)),:);
    ij = find(tmp == badnode);
    fem.nei(nbrnode(spn(i)),1:length(tmp)) = ([tmp(1:(ij-1)),addnode(i),tmp((ij+1):end)]);
end

%Determine the triqual for the final form to see if has very low quality
%elements.
tmp1 = (nbrelem);
tempL3=(fem.x(fem.e(tmp1,1))-fem.x(fem.e(tmp1,2))).^2+(fem.y(fem.e(tmp1,1))-...
   fem.y(fem.e(tmp1,2))).^2;
tempL1=(fem.x(fem.e(tmp1,2))-fem.x(fem.e(tmp1,3))).^2+(fem.y(fem.e(tmp1,2))-...
   fem.y(fem.e(tmp1,3))).^2;
tempL2=(fem.x(fem.e(tmp1,3))-fem.x(fem.e(tmp1,1))).^2+(fem.y(fem.e(tmp1,3))-...
   fem.y(fem.e(tmp1,1))).^2;
tempLs = ([tempL1 + tempL2 + tempL3]);
xnodes = fem.x(fem.e(tmp1,:));
ynodes = fem.y(fem.e(tmp1,:));
temparea = 0.5*(xnodes(:,1).*(ynodes(:,2)-ynodes(:,3))+xnodes(:,2).*...
   (ynodes(:,3)-ynodes(:,1))+xnodes(:,3).*(ynodes(:,1)-ynodes(:,2)));
fem.ar(tmp1) = temparea;
tempq = (4 * sqrt(3) * temparea) ./ tempLs;
clear tempL3 tempL2 tempL1 tempLs xnodes ynodes temparea;

fem1 = fem;
%Identify very low quality elements and attempts to use a line swap to fix.
poor = find(tempq < .1);
nflag = 1;good = 1;
if ~isempty(poor)
   for it = 1:length(poor)
      je = tmp1(poor(it));
      nodes = fem.e(je,:);
      nflag = 0;

      %Determine the angles to see if an edge can be fliped
      a2 = (x(enodes(je,3))-x(enodes(je,2))).^2+(y(enodes(je,3))-y(enodes(je,2))).^2;
      b2 = (x(enodes(je,1))-x(enodes(je,3))).^2+(y(enodes(je,1))-y(enodes(je,3))).^2;
      c2 = (x(enodes(je,2))-x(enodes(je,1))).^2+(y(enodes(je,2))-y(enodes(je,1))).^2;
      A = (180/pi)*acos((b2+c2-a2)./(2*sqrt(b2).*sqrt(c2)));
      B = (180/pi)*acos((c2+a2-b2)./(2*sqrt(c2).*sqrt(a2)));
      C = (180/pi)*acos((a2+b2-c2)./(2*sqrt(a2).*sqrt(b2)));
      [test,ind] = max([A,B,C]);
      if test > 160
         %Find the element numbers to flip the edge.
         nogood = nodes(ind);
         swap = setdiff(nodes,nogood);
         [temp1,tc] = find(enodes == swap(1) | enodes == swap(2));
         [b,j,k] = unique(temp1);
         temp2 = setdiff(1:length(temp1),j);
         swap = temp1(temp2);
         try
            fem1 = line_swap(fem,swap(1),swap(2));
         catch
            fem1 = fem;
         end

         %Spring the new mesh after the line swap.
         for itt = 1:2
             temp = find(fem1.nei(newnode(1),:) ~= 0);
             tempnei = fem1.nei(newnode(1),temp);
             fem1.x(newnode(1)) = mean(fem1.x(tempnei));
             fem1.y(newnode(1)) = mean(fem1.y(tempnei));
             fem1.z(newnode(1)) = mean(fem1.z(tempnei));
             temp = find(fem1.nei(newnode(2),:) ~= 0);
             tempnei = fem1.nei(newnode(2),temp);
             fem1.x(newnode(2)) = mean(fem1.x(tempnei));
             fem1.y(newnode(2)) = mean(fem1.y(tempnei));
             fem1.z(newnode(2)) = mean(fem1.z(tempnei));
             temp = find(fem1.nei(newnode(3),:) ~= 0);
             tempnei = fem1.nei(newnode(3),temp);
             fem1.x(newnode(3)) = mean(fem1.x(tempnei));
             fem1.y(newnode(3)) = mean(fem1.y(tempnei));
             fem1.z(newnode(3)) = mean(fem1.z(tempnei));
             temp = find(fem1.nei(newnode(4),:) ~= 0);
             tempnei = fem1.nei(newnode(4),temp);
             fem1.x(newnode(4)) = mean(fem1.x(tempnei));
             fem1.y(newnode(4)) = mean(fem1.y(tempnei));
             fem1.z(newnode(4)) = mean(fem1.z(tempnei));
             temp = find(fem1.nei(badnode,:) ~= 0);
             tempnei = fem1.nei(badnode,temp);
             fem1.x(badnode) = mean(fem1.x(tempnei));
             fem1.y(badnode) = mean(fem1.y(tempnei));
             fem1.z(badnode) = mean(fem1.z(tempnei));
         end

         %Use triqual to determine if the new mesh is better quality.
         tmp1 = nbrelem;
         tempL3=(fem1.x(fem1.e(tmp1,1))-fem1.x(fem1.e(tmp1,2))).^2+(fem1.y(fem1.e(tmp1,1))-...
            fem1.y(fem1.e(tmp1,2))).^2;
         tempL1=(fem1.x(fem1.e(tmp1,2))-fem1.x(fem1.e(tmp1,3))).^2+(fem1.y(fem1.e(tmp1,2))-...
            fem1.y(fem1.e(tmp1,3))).^2;
         tempL2=(fem1.x(fem1.e(tmp1,3))-fem1.x(fem1.e(tmp1,1))).^2+(fem1.y(fem1.e(tmp1,3))-...
            fem1.y(fem1.e(tmp1,1))).^2;
         tempLs = ([tempL1 + tempL2 + tempL3]);
         xnodes = fem1.x(fem1.e(tmp1,:));
         ynodes = fem1.y(fem1.e(tmp1,:));
         temparea = 0.5*(xnodes(:,1).*(ynodes(:,2)-ynodes(:,3))+xnodes(:,2).*...
            (ynodes(:,3)-ynodes(:,1))+xnodes(:,3).*(ynodes(:,1)-ynodes(:,2)));
         fem1.ar(tmp1) = temparea;
         tempq = (4 * sqrt(3) * temparea) ./ tempLs;
         clear tempL3 tempL2 tempL1 tempLs xnodes ynodes temparea;
         if min(tempq) > .4
            fem = fem1;
            nflag = 1;
         else
            nflag = 0;
            good = 6;
         end
      end
   end
end

% If problems with new mesh, then retriangulate

%Correct output if line swap failed to run
if sum(nflag) == 0
   fem = patch_update(fem_struct,fem1,jj);
   good = 6;
end

% Correct output if invalid elements were created.
bad = find(fem.ar < 0);
if ~isempty(bad)
    fem = patch_update(fem_struct,fem1,jj);
    good = 6;
end

%Display message if invalid elements where created.
if good == 6
   disp('The nodally updated mesh contained invalid or badly conditioned');
   disp('elements, therefore the patch was retriangulated which should');
   disp('reduce the connecitivity but is not guaranteed to do so.');
   disp(' ');
end

return


function uvTformData = sc_src_domain_tform(uvPlaneID, modelPlane, modelReg, srcPos, trgPos, sampleRandReg)

% SC_SRC_DOMAIN_TFORM: The function estimates the source patch domain
% transformation based on the source and target position, and the plane parameters
%
% Input:
%     - uvPlaneID:  numUvPix x 1, the plane label of uv pixels
%     - modelPlane: plane model
%     - modelReg:   regularity model
%     - srcPos:     numUvPix x 2, the center position of source patch
%     - trgPos:     numUvPix x 2, the center position of target patch
%     - sampleRandReg:
%         1: random sampling mode
%         0: regular sampling mode
% Output:
%     - uvTformData: numUvPix x 9

numUvPix    = size(srcPos, 1);

uvTformData = zeros(numUvPix, 9, 'single');
I = eye(3);

for indPlane = 1: modelPlane.numPlane
    % The rectifying transformation for the plane
    rectMat = modelPlane.rectMat{indPlane};
    h7 = rectMat(3,1);
    h8 = rectMat(3,2);

    % Retrieve the uv pixels that have the current plane label
    uvPlaneIndCur = uvPlaneID == indPlane;
    numPlanePixCur = sum(uvPlaneIndCur);

    if(numPlanePixCur)
        % Target patch center position in the rectified domain
        trgPosCur = trgPos(uvPlaneIndCur, :) - 1;
        trgPosCurR = sc_apply_tform_H(trgPosCur, h7, h8);

        % Get dRect
        if(sampleRandReg)    % Random sampling
            % Source patch center position in the rectified domain
            srcPosCur = srcPos(uvPlaneIndCur, :) - 1;
            srcPosCurR = sc_apply_tform_H(srcPosCur, h7, h8);

            % Displacement vector from target to source position
            dRect = srcPosCurR - trgPosCurR;
        else                 % Regularity guided sampling
            dRect = zeros(numPlanePixCur, 2, 'single');

            numDispVecCur = modelReg.numDispVec(indPlane);
            if(numDispVecCur~=0)
                randInd = randi(numDispVecCur, numPlanePixCur, 1);
                dRect = modelReg.dispVec{indPlane}(randInd, :);
            end
        end

        % Compute the transformation that maps from target to source
        % (See Eqn 8 in the paper)
        if(size(dRect,2) ~= 0)
            uvTformCur = zeros(numPlanePixCur, 9, 'single');
            uvTformCur(:,[1,4,7]) = bsxfun(@times, dRect(:,1), [h7, h8, 1]);
            uvTformCur(:,[2,5,8]) = bsxfun(@times, dRect(:,2), [h7, h8, 1]);

            dTemp = dRect*[h7;h8]; % dTemp = dx*h7 + dy*h8
            uvTformCur(:,[3,6,9]) = bsxfun(@times, dTemp, -[h7, h8, 1]);
            uvTformCur = bsxfun(@plus, uvTformCur, I(:)');

            % Apply the offset to cancel out the dependency of the target position
            % (See Eqn 9 in the paper)
            uvTformData(uvPlaneIndCur, :)   = sc_trans_tform(uvTformCur, trgPosCur);
            uvTformData(uvPlaneIndCur, 7:8) = uvTformData(uvPlaneIndCur, 7:8) + 1;
        end
    end
end

end

function y = sc_apply_tform_H(x, h7, h8)
% Apply homography H with third row [h7, h8, 1] to 2D points x

y = x(:,1)*h7 + x(:,2)*h8 + 1;
y = bsxfun(@rdivide, x(:,1:2), y + eps);

end


function [ d ] = gsp_vec2mat( d,Nf )
%GSP_VEC2MAT vector to matrix transform
%   Usage: d  = gsp_vec2mat( d,Nf );
%
%   Input parameters:
%       d       : Data
%       Nf      : Number of filter
%
%   Ouput parameter
%       d       : Data
%
%   Reshape the data from the vector form to the matrix form

% TESTING: test_filter

[M,N] = size(d);

d = reshape(d,M/Nf,Nf,N);

end


function updateBins = checkThresholds(data,params,binVals)
% function updateBins = checkThresholds(data,params,binVals)
% Checks if the binVals are still accurate.

updateBins = true;
if isempty(binVals)|| size(binVals,1)~=params.numBins,
  return;
end

nex = size(data,1);
numDim = size(data,2);
numBins = params.numBins;
temp = linspace(0,100,numBins+2);
prcValues = temp(2:end-1);
mpoint = round(numel(prcValues)/2);
% selpts = [1 mpoint numel(prcValues)];
selpts = [1 numel(prcValues)];
selValues = prcValues(selpts);
binVals = permute(binVals,[3 2 1]);
curbvals = binVals(:,:,selpts);

kk1 = bsxfun(@lt,data,curbvals);
kk2 = bsxfun(@le,data,curbvals);

tt1 = sum(kk1,1)/nex*100;
tt2 = sum(kk2,1)/nex*100;
tt1 = squeeze(tt1);
tt2 = squeeze(tt2);
mm = abs(tt1-tt2);
dd = abs(bsxfun(@minus,tt1,selValues));

dd(mm>0.2) = 0;

if max(dd(:))<(100/numBins),
  updateBins = false;
end


%% kalman tracking
function k = klmf(k)
for i      = 1 : size(k, 2)                         % for every kalman filter
k(i).s     = kalmanf(k(i).s);                       % update kalman filter
end
end
%% update kalman
function s = kalmanf(s)
s.x        = s.A * s.x;                             % prediction for state vector and covariance
s.P        = s.A * s.P * s.A' + s.Q;                % covariance of the state vector estimate
K          = s.P * s.H' / (s.H * s.P * s.H' + s.R); % compute Kalman gain factor
s.x        = s.x + K * (s.z - s.H * s.x);           % correction based on observation
s.P        = s.P - K * s.H * s.P;
end


function cnn_imagenet_minimal()
% CNN_IMAGENET_MINIMAL   Minimalistic demonstration of how to run an ImageNet CNN model

% Setup MatConvNet.
run(fullfile(fileparts(mfilename('fullpath')), ...
  '..', '..', 'matlab', 'vl_setupnn.m')) ;

% Download a pre-trained CNN from the web.
if ~exist('imagenet-vgg-f.mat', 'file')
  fprintf('Downloading the VGG-F model ... this may take a while\n') ;
  urlwrite('http://www.vlfeat.org/matconvnet/models/imagenet-vgg-f.mat', ...
    'imagenet-vgg-f.mat') ;
end

% Load the model and upgrade it to MatConvNet current version.
net = load('imagenet-vgg-f.mat') ;
net = vl_simplenn_tidy(net) ;

% Obtain and preprocess an image.
im = imread('peppers.png') ;
im_ = single(im) ; % note: 255 range
im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
im_ = im_ - net.meta.normalization.averageImage ;

% Run the CNN.
res = vl_simplenn(net, im_) ;

% Show the classification result.
scores = squeeze(gather(res(end).x)) ;
[bestScore, best] = max(scores) ;
figure(1) ; clf ; imagesc(im) ;
title(sprintf('%s (%d), score %.3f',...
   net.meta.classes.description{best}, best, bestScore)) ;


function [yOut, amp, phi]=ApplyHants(y,nb,nf,fet,dod,HiLo,low,high,delta)
if (max(size(size(y)))~=3)
    error('Input data must be three dimensional [time,lat,lon]')
end

[ni ny,nx]=size(y);

yOut= zeros(ni,ny,nx,'single');
amp = zeros(nf+1,ny,nx,'single');
phi = zeros(nf+1,ny,nx,'single');
ts=1:ni;

h= waitbar(0,'Total Progress:');
WBarOuterPosition=get(h,'OuterPosition');
WBarOuterPosition(2)=WBarOuterPosition(2)-WBarOuterPosition(4);
h2=waitbar(0,'Calculating, please wait ...');
set(h2,'OuterPosition',WBarOuterPosition);
for Sample=1:nx
    waitbar(Sample/nx,h);
    for Line=1:ny
        waitbar(Line/ny,h2,['Line:' num2str(Line) ', Sample:' num2str(Sample)]);
        data=y(:,Line,Sample);
        if (sum(isnan(data))~=ni)
            data(isnan(data))=low-1.0;
            [amp(:,Line,Sample),phi(:,Line,Sample),yOut(:,Line,Sample)] ...
                    = HANTS(ni,nb,nf,data,ts,HiLo,low,high,fet,dod,delta);
        end
    end
end
close(h);
close(h2);
end


function y = FM(x,beta)

[r, c] = size(x);
if r*c == 0
    y = [];
    return;
end;
if (r == 1)
    x = x(:);
    len = c;
else
    len = r;
end;

Df = 2*pi*beta*100;

x = interp(x,20);
x = x*Df;

Fs = 20*8000;
Fc = 40000;
t = (0:1/Fs:((size(x,1)-1)/Fs))';
t = t(:, ones(1, size(x, 2)));

    x = 2 / Fs * pi * x;
    x = [zeros(1, size(x, 2)); cumsum(x(1:size(x,1)-1, :))];
    y = cos(2 * pi * Fc * t + x );
   plot(y)


%+++ Data load
load T2DM
%+++ Subwindow Permutation Analysis
F=spa(X,y,5,5,'autoscaling',300,0.8,10);
bar(F.COSS);
xlabel('Variable index');
figure;
plotspa(F,11);
vargrouping(F,[1:21],1)


%%*****************************************************************
%% sortA: sort columns of At{p} in ascending order according to the
%%        number of nonzero elements.
%%
%% [At,C,b,X0,Z0,permA,permZ] = sortA(blk,At,C,b,X0,Z0);
%%*****************************************************************
%% SDPT3: version 4.0
%% Copyright (c) 1997 by
%% Kim-Chuan Toh, Michael J. Todd, Reha H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************

   function [At,C,Cnew,X0,Z0,permA,invpermA,permZ] = ...
             HSDsortA(blk,At,C,Cnew,b,X0,Z0);

   global spdensity smallblkdim
%%
   numblk = size(blk,1);
   m = length(b);
   nnzA = zeros(numblk,m);
   permA = kron(ones(numblk,1),[1:m]);
   invpermA = kron(ones(numblk,1),[1:m]);
   permZ = cell(size(blk,1),1);
%%
   for p=1:size(blk,1)
      pblk = blk(p,:);
      n = sum(pblk{2});
      numblk = length(pblk{2});
      if strcmp(pblk{1},'s') & (max(pblk{2}) > smallblkdim)
         n2 = sum(pblk{2}.*pblk{2});  n22 = sum(pblk{2}.*(pblk{2}+1))/2;
         m1 = size(At{p,1},2);
         if (length(pblk{2}) == 1)
            tmp = abs(C{p}) + abs(Z0{p});
            if  (~isempty(At{p,1}))
                tmp = tmp + smat(blk(p,:),abs(At{p,1})*ones(m1,1),1);
            end
            if (nnz(tmp) < spdensity*n22);
               per = symamd(tmp);
               invper = zeros(n,1); invper(per) = [1:n];
               permZ{p} = invper;
               if (~isempty(At{p,1}))
                  isspAt = issparse(At{p,1});
                  for k = 1:m1
                     Ak = smat(pblk,At{p,1}(:,k),1);
                     At{p,1}(:,k) = svec(pblk,Ak(per,per),isspAt);
                  end
               end
               C{p}  = C{p}(per,per);
               Z0{p} = Z0{p}(per,per);
               X0{p} = X0{p}(per,per);
               Cnew{p} = Cnew{p}(per,per);
            else
               per = [];
            end
            if (length(pblk) > 2) & (~isempty(per))
               m2 = length(pblk{3});
               P = spconvert([(1:n)', per', ones(n,1)]);
               At{p,2} = P*At{p,2};
            end
         end
         if ~isempty(At{p,1}) & (mexnnz(At{p,1}) < m*n22/2)
            for k = 1:m1
               Ak = At{p,1}(:,k);
               nnzA(p,k) = length(find(abs(Ak) > eps));
            end
            [dummy,permAp] = sort(nnzA(p,1:m1));
            At{p,1}  = At{p,1}(:,permAp);
            permA(p,1:m1) = permAp;
            invpermA(p,permAp) = [1:m1];
         end
      elseif strcmp(pblk{1},'q') | strcmp(pblk{1},'l') | strcmp(pblk{1},'u');
         if ~issparse(At{p,1});
            At{p,1} = sparse(At{p,1});
         end
      end
   end
%%*********************************************************************


function map = haxby(m);
%HAXBY  Haxby color map
%   HAXBY(M) returns an M-by-3 matrix containing a colormap with Haxby's
%   colors, commonly used for displaying bathymetry data.
%   HAXBY, by itself, is the same length as the current colormap.
%
%   For example, to reset the colormap of the current figure:
%
%             colormap(haxby)
%
%   Use
%             colormap(flipud(haxby))
%
%   for bathymetry data (positive downward).
%
%   Colormap is based on the colors used by W. F. Haxby's Gravity
%   field of World's oceans, 1985, developed for geoid and gravity maps.
%   The version used here is formed from a linear interpolation of
%   the GMT color table used by MB-System by David W. Caress and Dale N. Chayes.
%   <http://www.ldeo.columbia.edu/res/pi/MB-System>
%
%   See also HSV, GRAY, PINK, COOL, BONE, COPPER, FLAG, HOT
%   COLORMAP, RGBPLOT.

% Kelsey Jordahl
% Marymount Manhattan College
% Time-stamp: <Fri Oct 30 12:45:12 EDT 2009>

if nargin < 1, m = size(get(gcf,'colormap'),1); end
% mbm_grdplot Haxby color pallette
ncolors=11;
c=[ 37    57   175;    40   127   251;    50   190   255;   106   235   255;
    138   236   174;   205   255   162;   240   236   121;   255   189    87;
    255   161    68;   255   186   133;   255   255   255];
pp=1:(m-1)/(ncolors-1):m;
r=interp1(pp,c(:,1),1:m);
g=interp1(pp,c(:,2),1:m);
b=interp1(pp,c(:,3),1:m);
map=[r' g' b']/255;


function out = SD_SurrogateTest(x,surrMeth,numSurrs,extrap,theTestStat,randomSeed)
% SD_SurrogateTest   Analyzes test statistics obtained from surrogate time series
%
% This function is based on information found in:
% "Surrogate data test for nonlinearity including nonmonotonic transforms"
% D. Kugiumtzis Phys. Rev. E 62(1) R25 (2000)
%
% The generation of surrogates is done by the periphery function,
% SD_MakeSurrogates
%
%---INPUTS:
% x, the input time series
%
% surrMeth, the method for generating surrogate time series:
%       (i) 'RP': random phase surrogates that maintain linear correlations in
%                 the data but destroy any nonlinear structure through phase
%                 randomization
%       (ii) 'AAFT': the amplitude-adjusted Fourier transform method maintains
%                    linear correlations but destroys nonlinear structure
%                    through phase randomization, yet preserves the approximate
%                    amplitude distribution,
%       (iii) 'TFT': preserves low-frequency phases but randomizes high-frequency phases (as a way of dealing
%                    with non-stationarity, cf.:
%               "A new surrogate data method for nonstationary time series",
%                   D. L. Guarin Lopez et al., arXiv 1008.1804 (2010)
%
% numSurrs, the number of surrogates to compute (default is 99 for a 0.01
%         significance level 1-sided test)
%
% extrap, extra parameter, the cut-off frequency for 'TFT'
%
% theTestStat, the test statistic to evalute on all surrogates and the original
%           time series. Can specify multiple options in a cell and will return
%           output for each specified test statistic:
%           (i) 'ami': the automutual information at lag 1, cf.
%                 "Testing for nonlinearity in irregular fluctuations with
%                 long-term trends" T. Nakamura and M. Small and Y. Hirata,
%                 Phys. Rev. E 74(2) 026205 (2006)
%           (ii) 'fmmi': the first minimum of the automutual information
%                       function
%           (iii) 'o3': a third-order statistic used in: "Surrogate time
%                 series", T. Schreiber and A. Schmitz, Physica D 142(3-4) 346
%                 (2000)
%           (iv) 'tc3': a time-reversal asymmetry measure. Outputs of the
%                 function include a z-test between the two distributions, and
%                 some comparative rank-based statistics.
%
% randomSeed, whether (and how) to reset the random seed, using BF_ResetSeed

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function 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/>.
% ------------------------------------------------------------------------------

doPlot = 0; % plot outputs to a figure

% ------------------------------------------------------------------------------
%% Check inputs
% ------------------------------------------------------------------------------
if nargin < 2 || isempty(surrMeth)
    surrMeth = 'RP'; % randomize phases
end

if nargin < 3 || isempty(numSurrs)
    numSurrs = 99; % create 99 surrogates for a 0.01 significance level 1-sided test
end

if nargin < 4
    extrap = [];
end

if nargin < 5 || isempty(theTestStat)
    theTestStat = 'AMI'; % automutual information
end

if ischar(theTestStat)
    theTestStat = {theTestStat};
end

% randomSeed: how to treat the randomization
if nargin < 6
    randomSeed = [];
end

N = length(x); % time-series length

% ------------------------------------------------------------------------------
%% Generate surrogate time series using SD_MakeSurrogates:
% ------------------------------------------------------------------------------
z = SD_MakeSurrogates(x,surrMeth,numSurrs,extrap,randomSeed);

% z is matrix where each column is a surrogate time series

% ------------------------------------------------------------------------------
% Evaluate test statistic on each surrogate
% ------------------------------------------------------------------------------
if ismember('ami1',theTestStat)
    % Investigate AMI(1) of surrogates compared to that of signal itself
    % This statistic is used by Nakamura et al. (2006), PRE
    % Could use CO_HistogramAMI or TSTL, but I'll use IN_AutoMutualInfo with
    % Gaussian kernel…
    % FYI: for a histogram method, there are upper and lower bounds on the number of
    % bins to use: [1+log_2(N)], [sqrt(N)].

    % Use the gaussian approximation to estimate automutual information using the
    % Information Dynamics Toolkit:
    ami_fn = @(timeSeries,timeDelay) IN_AutoMutualInfo(timeSeries,timeDelay,'gaussian');

    AMIx = ami_fn(x,1);
    AMIsurr = zeros(numSurrs,1);
    for i = 1:numSurrs
        AMIsurr(i) = ami_fn(z(:,i),1);
    end
    % So we have a value AMIx, and a distribution for the surrogates
    % AMIsurr -- we must compare and return something meaningful
    % surrogates should always have lower AMI than original signal
    someStats = SDgivemestats(AMIx,AMIsurr,'right');
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('ami_%s',fnames{i})) = someStats.(fnames{i});
    end
end

if ismember('fmmi',theTestStat)
    % Investigate the first minimum of mutual information of surrogates compared to
    % that of signal itself
    fmmix = CO_FirstMin(x,'mi');
    fmmiSurr = zeros(numSurrs,1);
    for i = 1:numSurrs
        try
            fmmiSurr(i) = CO_FirstMin(z(:,i),'mi');
        catch
            fmmiSurr(i) = NaN;
        end
    end
    if any(isnan(fmmiSurr))
        error('fmmi failed');
    end

    % FMMI should be higher for signal than surrogates
    someStats = SDgivemestats(fmmix,fmmiSurr,'right');
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('fmmi_%s',fnames{i})) = someStats.(fnames{i});
    end
end

if ismember('o3',theTestStat)
    % Third-order statistic in Schreiber, Schmitz (Physica D)
    tau = 1;
    o3x = 1/(N-tau)*sum((x(1+tau:end) - x(1:end-tau)).^3);
    o3surr = zeros(numSurrs,1);
    for i = 1:numSurrs
        o3surr(i) = 1/(N-tau)*sum((z(1+tau:end,i) - z(1:end-tau,i)).^3);
    end
    someStats = SDgivemestats(o3x,o3surr,'both');
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('o3_%s',fnames{i})) = someStats.(fnames{i});
    end
end

if ismember('tc3',theTestStat)
    % TC3 statistic -- another time-reversal asymmetry measure
    tau = 1;
    tmp = CO_tc3(x,tau);
    tc3x = tmp.raw;
    tc3surr = zeros(numSurrs,1);
    for i = 1:numSurrs
        tmp = CO_tc3(z(:,i),tau);
        tc3surr(i) = tmp.raw;
    end

    someStats = SDgivemestats(tc3x,tc3surr,'both');
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('tc3_%s',fnames{i})) = someStats.(fnames{i});
    end
end

if ismember('nlpe',theTestStat)
    % Locally constant phase space prediction error
    warning('''nlpe'' can be very time consuming...')
    de = 3; tau = 1; % embedding parameters: fixed like a dummy!
    tmp = NL_MS_nlpe(x,de,tau);
    nlpex = tmp.msqerr;
    nlpesurr = zeros(numSurrs,1);
    for i = 1:numSurrs
        res = MS_nlpe(z(:,i),de,tau);
        msqerr = sum(res.^2);
        nlpesurr(i) = msqerr;
    end

    someStats = SDgivemestats(nlpex,nlpesurr,'right'); % NLPE should be higher than surrogates
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('nlpe_%s',fnames{i})) = someStats.(fnames{i});
    end
end

if ismember('fnn',theTestStat)
    warning('fnn takes like *literally forever*...')

    % false nearest neighbours at d=2;
    tmp = NL_MS_fnn(x,2,1,5,1);
    fnnx = tmp.pfnn_2;
    fnnsurr = zeros(numSurrs,1);
    for i = 1:numSurrs
        tmp = NL_MS_fnn(z(:,i),2,1,5,1);
        fnnsurr(i) = tmp.pfnn_2;
    end

    someStats = SDgivemestats(fnnx,fnnsurr,'right'); % FNN(2) should be higher than surrogates?
    fnames = fieldnames(someStats);
    for i = 1:length(fnames)
        out.(sprintf('fnn_%s',fnames{i})) = someStats.(fnames{i});
    end
end

% ------------------------------------------------------------------------------
function someStats = SDgivemestats(statx,statsurr,leftrightboth)
    numSurrs = length(statsurr);
    if any(isnan(statsurr))
        error('SDgivemestats failed');
    end
%         leftrightboth = {'left','right','both'}
    % have a distribution of some statistic with samples statsurr
    % and we have the value of the statistic for a given process in
    % statx. Want to return measures of how consistant the measured
    % statistic is with the sample statsurr.

    % ASSUME GAUSSIAN DISTRIBUTION:
    % so can use 1/2-sided z-statistic
    [~, p, ~, zStat] = ztest(statx, mean(statsurr), std(statsurr), 0.05, leftrightboth);
    someStats.p = p; % pvalue
    someStats.zscore = zStat; % z-statistic

    % fit a kernel distribution to zscored distribution:
    if std(statsurr) == 0
        % all surrogates have same value of this statistic
        % cannot do a meaningful zscore -- do it raw
        [f, xi] = ksdensity(statsurr);
        % find where the statx value would be:
        if statx < min(xi) || statx > max(xi)
            someStats.f = 0; % out of range -- assume p=0 here
        else
            [~, minhere] = min(abs(statx-xi));
            someStats.f = f(minhere); % return probability density where the point is
        end
    else
        zscstatsurr = (statsurr-mean(statsurr))/std(statsurr);
        zscstatx = (statx-mean(statsurr))/std(statsurr);
        [f, xi] = ksdensity(zscstatsurr);

        % find where the statx value would be:
        if (zscstatx < min(xi)) || (zscstatx > max(xi))
            someStats.f = 0; % out of range -- assume p=0 here
        else
            [~, minhere] = min(abs(zscstatx-xi));
            someStats.f = f(minhere); % return probability density where the point is
        end
    end

    % What fraction of the range is the sample in?
    medsurr = median(statsurr);
    iqrsurr = iqr(statsurr);
    if iqrsurr == 0
        someStats.mediqr = NaN;
    else
        someStats.mediqr = abs(statx-medsurr)/iqrsurr;
    end

    % rank statistic
    [~, ix] = sort([statx; statsurr]);
    xfitshere = find(ix == 1) - 1;
    if strcmp(leftrightboth,'right') % x statistic smaller than distribution
        xfitshere = numSurrs + 1 - xfitshere; % how far from highest ranked value
    elseif strcmp(leftrightboth,'both')
        xfitshere = min(xfitshere,numSurrs+1-xfitshere);
    end

    if isempty(xfitshere)
        someStats.prank = 1/(numSurrs+1); % rank-based p-value
    else
        someStats.prank = (1+xfitshere)/(numSurrs+1); % rank-based p-value
    end
    if strcmp(leftrightboth,'both')
        someStats.prank = someStats.prank*2; % I think this factor should be in here
    end

    % DO PLOTTING:
    if doPlot
        figure('color','w')
        plot(statsurr,ones(numSurrs,1),'.k');
        hold('on');
        plot(statx*ones(2,1),[0,2],'r')
    end
end
% ------------------------------------------------------------------------------

end


function[varargout]=polysmooth_sortfield(varargin)
%POLYSMOOTH_SORTFIELD  Returns sorted field values for a mapping problem.
%
%   ZS=POLYSMOOTH_SORTFIELD(INDEXS,Z), where INDEXS is a cell array of
%   indices as output by SPHERESORT or TWODSORT, applies INDEXS to the
%   input field Z, leading to the output ZS.
%
%   ZS contains the elements of Z, sorted in terms of increasing distance
%   from a set of grid points, as specified by SPHERESORT or TWODSORT.
%
%   [ZS1,ZS2,...,ZSK]=POLYSMOOTH_SORTFIELD(INDEXS,Z1,Z2,...,ZK) also works.
%
%   This is mainly an auxillary function used with SPHERESORT or TWODSORT.
%   However, it is useful to call directly for the "One grid, many fields"
%   case described in POLYSMOOTH.
%
%   Usage: zs=polysmooth_sortfield(indexs,z);
%          [zs1,zs2,zs3]=polysmooth_sortfield(indexs,z1,z2,z3);
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2018--2020 J.M. Lilly --- type 'help jlab_license' for details

indexs=varargin{1};
varargin=varargin(2:end);

varargout=cell(length(varargin),1);
for k=1:length(varargin)
    temp=indexs;
    for j=1:length(indexs)
        nonnani=~isnan(indexs{j});
        temp{j}(nonnani)=varargin{k}(indexs{j}(nonnani));
        %adjustment for missing data in complex-valued fields
        if ~isreal(varargin{k})
            temp{j}(~nonnani)=temp{j}(~nonnani)+1i*nan;
        end
    end
    varargout{k}=temp;
end


function [cIX,gIX,numK] = AllCentroidRegression(hfig)
M_0 = getappdata(hfig,'M_0');
thres_reg = getappdata(hfig,'thres_reg');

Reg = FindCentroid(hfig);

Corr = corr(Reg',M_0');

[corr_max,IX] = max(Corr,[],1);
% cIX = find(corr_max>thres_reg)';

if thres_reg>=0
    cIX = (find(corr_max>thres_reg))';
elseif thres_reg<0
    cIX = (find(corr_max<thres_reg))';
end

gIX = IX(cIX)';
numK = length(unique(gIX));
end


function [sys,x0,str,ts]=NLSEF_fhan(t,x,u,flag,r,h1)

if flag==0
    sys = [0;0;1;2;0;0;1];
    x0 = [];
    str = [ ];
    ts = [0 0];

elseif flag==3
    sys=-fhan(u(1),u(2),r,h1);

else
    sys=[];
end


classdef nme_bus_ld_acp_node_test < mp.nme_bus_nld_acp_node_test

%   MATPOWER
%   Copyright (c) 2021-2022, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%     end

    methods
        function name = name(obj)
            name = 'bus_ld';
        end

        function np = np(obj)
            np = 1;     %% this is a 1 port element
        end

        function obj = build_params(obj, nm, dm)
            build_params@mp.nme_bus_nld_acp_node_test(obj, nm, dm); %% call parent

            dme = obj.data_model_element(dm);

            %% bus shunts
            Ysh = dme.gs + 1j * dme.bs;             %% shunt admittances
            obj.Y = sparse(1:obj.nk, 1:obj.nk, Ysh, obj.nk, obj.nk);

            %% constant power loads
            obj.s = dme.pd + 1j * dme.qd;           %% complex power demand
        end
    end     %% methods
end         %% classdef


function [lambda, RGB] = createSpectrum(matchingFcn)
%createSpectrum   Get the wavelengths and RGB values for a spectrum.
%
%    [LAMBDA, RGB] = CREATESPECTRUM(MATCHINGFCN) returns the wavelengths
%    LAMBDA (in nanometers) and RGB values for the visible spectrum.  The
%    string MATCHINGFCN determines which color matching functions are used
%    to generate the spectrum.
%
%    See also colorMatchFcn, spectrumRGB.

%    Copyright 1993-2005 The MathWorks, Inc.

% Get the color matching functions.
[lambda, xFcn, yFcn, zFcn] = colorMatchFcn(matchingFcn);

% For the equal-energy illuminant, the XYZ values are the same as the
% concatenated matching functions.
XYZ = permute([xFcn; yFcn; zFcn], [2 3 1]);

% Convert the XYZ values to RGB.
XYZ2sRGB = makecform('xyz2srgb');
RGB = applycform(XYZ, XYZ2sRGB);
RGB = repmat(RGB, [1, 30, 1]);
RGB = permute(RGB, [2 1 3]);


function [ reoriented_data ] = reorient_chipper_data( symmetry, data_in)
%REORIENT_CHIPPER_ARGS Applies a transform to the chipper indexing
%
% This function transforms the actual data that a chipper function outputs
% based on the symmetry specified.
%
% A chipper function is a simplified function of a file reader.  It takes
% only three arguments: [minIndexInDimension1 maxIndexInDimension1],
% [minIndexInDimension2 maxIndexInDimension2], [subsampleInDimension1,
% subsampleInDimension2].  All other information such as the file handle
% and other auxilliary information must be contained within the chipper
% function.
%
% The SYMMETRY parameter is used to perform symmetry operations on the
% imported image data.  A combination of mirroring in the first dimension
% (m1), mirroring in the second dimension (m2) and transpose(tr) is used to
% accomplish the symmetry operations.  The 'symmetry' input parameter is
% defined as [ 1m m2 tr ], where each of the elements can be either 0 or 1
% to indicate whether to apply a transformation or not.
%
%   [ 0 0 0 ] - default setting; successive pixels on disk are interpreted
%               to fill the first dimension in a MATLAB array (vertical, if
%               viewed in imagesc/imshow without any reorienting)
%   [ 1 0 1 ] -  90 degrees CCW from [ 0 0 0 ]
%   [ 0 1 1 ] -  90 degrees  CW from [ 0 0 0 ]
%   [ 1 1 0 ] - 180 degrees     from [ 0 0 0 ]
%
%   [ 0 0 1 ] - transpose of [ 0 0 0 ];
%   [ 0 1 0 ] -  90 degrees CCW from [ 0 0 1 ]
%   [ 1 0 0 ] -  90 degrees  CW from [ 0 0 1 ]
%   [ 1 1 1 ] - 180 degrees     from [ 0 0 1 ]
%
% Written by: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

%% Transform data
reoriented_data=data_in;
if symmetry(1)
    reoriented_data=flipud(reoriented_data);
end
if symmetry(2)
    reoriented_data=fliplr(reoriented_data);
end
if symmetry(3)
    reoriented_data=permute(reoriented_data,[2 1 3:ndims(reoriented_data)]);
end

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function [h_marker,txtcoord]=clusterhull(mode,coord,partition,color)
%function [h_marker,txtcoord]=clusterhull(mode,coord,partition,[color])
%
%PURPOSE
%
%To draw a cluster visualization where the objects (represented by
%points) belonging to the same cluster are presented by "cluster hulls",
%polygons where the edge of the polygon is the convex hull of the
%points that belong to the same cluster.
%
%INPUT
%
%%[An argument in brackets is optional. If it isn't  given or it's
% an empty matrix/string, the function will use a default value.]
%
%mode      (string) 'edge' | 'fill'
%coord     (Mx2 matrix) coordinates of points (objects)
%partition (Mx1 vector) partition vector of objects (see
%            explanation for 'partition vector' in function hcluster)
%[color]   (Kx3 matrix) each line is a 1x3 RGB vector that defines
%           color for each cluster. Default color is red for all
%           clusters color(i,:)=[NaN NaN NaN] means that cluster(i)
%           is not drawn at all.
%
%OUTPUT
%
% h_marker (vector) graphic handles to all clusters. h_marker(i)=NaN if
%           color(i,:)=[NaN NaN NaN]
% txtcoord (Kx2 matrix) suggested coordinates for text labels.
%            txtcoord(i,:)=[NaN NaN] if cluster i is not drawn.
%            Meaningful only in mode 'edge', returns always a
%            matrix of NaNs in mode 'fill'.
%
%DETAILS
%
%In mode 'edge' each cluster is represented by a convex hull if
%there are more than two points in the cluster. A two point cluster is
%represented by a line segment and a one point cluster by a small
%cross. The face of the convex hull is invisible.
%
%In mode 'fill' the cluster hulls are filled with the specified
%color. Clusters having less than three members are ignored.
%
%NOTE The function always adds to a plot (turns 'hold on' temporarily).
%
%USED IN
%  icassoGraph

%COPYRIGHT NOTICE
%This function is a part of Icasso software library
%Copyright (C) 2003-2005 Johan Himberg
%
%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 any later version.
%
%This program is distributed in the hope that it will be useful,
%but WITHOUT ANY WARRANTY; without even the implied warranty of
%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%GNU General Public License for more details.
%
%You should have received a copy of the GNU General Public License
%along with this program; if not, write to the Free Software
%Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

% ver 1.2 100105 johan

holdStat=ishold;
hold on;

Ncluster=max(partition);

if nargin<4|isempty(color),
  color=repmat([1 0 0],Ncluster,1);
end

switch mode
 case 'edge'
  [h_marker,txtcoord]=clusteredge(coord,partition,color);
 case 'fill'
  h_marker=clusterfill(coord,partition,color);
  txtcoord=repmat(NaN,Ncluster,1);
 otherwise
  error('Unknown operation mode.');
end

% Some graphic settings

set(gca,'xtick',[],'ytick',[]);
axis equal;

if ~holdStat,
  hold off;
end

function [h_marker,txtcoord]=clusteredge(coord,partition,color);

%% Number of clusters
Ncluster=max(partition);

%% Line width and +-sign size
LINEWIDTH=2;
MARKERSIZE=6;

for cluster=1:Ncluster,
  hullCoord=[];
  index=partition==cluster; Npoints=sum(index);
  coord_=coord(index,:);
  isVisible=all(isfinite(color(cluster,:)));
  if isVisible,
    if Npoints>=3,
      I=convhull(coord_(:,1),coord_(:,2));
      hullCoord=enlargehull([coord_(I,1) coord_(I,2)]);
      h_marker(cluster,1)=patch(hullCoord(:,1),hullCoord(:,2),0);
      set(h_marker(cluster,1),'edgecolor',color(cluster,:),'facecolor','none', ...
			'linewidth',LINEWIDTH);
    elseif size(coord_,1)==2,
      hullCoord(:,1)=[coord_(1,1) coord_(2,1)]'; hullCoord(:,2)=[coord_(1,2) coord_(2,2)]';
      h_marker(cluster,1)=plot(hullCoord(:,1)',hullCoord(:,2)','-');
      set(h_marker(cluster,1),'color',color(cluster,:),'linewidth',LINEWIDTH);
    else
      hullCoord(:,1)=coord_(1,1); hullCoord(:,2)=coord_(1,2);
      h_marker(cluster,1)=plot(coord_(1,1),coord_(1,2),'+');
      set(h_marker(cluster),'color',color(cluster,:),'markersize',MARKERSIZE);
  end
  txtcoord(cluster,:)=gettextcoord(hullCoord);
  else
    txtcoord(cluster,1:2)=NaN; h_marker(cluster,1)=NaN;
  end
end

function h_marker=clusterfill(coord,partition,color)

Ncluster=max(partition);

k=0;
for cluster=1:Ncluster,
  hullCoord=[];
  index=cluster==partition; Npoints=sum(index);
  coord_=coord(index,:);
  isVisible=all(isfinite(color(cluster,:)));
  if Npoints>=3 & isVisible,
    I=convhull(coord_(:,1),coord_(:,2));
    hullCoord=enlargehull([coord_(I,1) coord_(I,2)]);
    h_marker(cluster,1)=patch(hullCoord(:,1),hullCoord(:,2),0);
    set(h_marker(cluster),'edgecolor','none','facecolor',color(cluster,:));
  else
    h_marker(cluster,1)=NaN;
  end
end

function c=gettextcoord(coord)

[tmp,i]=min(coord(:,1));
c=coord(i,:);

function coord=enlargehull(coord)

S=1.1;

m=repmat(mean(coord(1:end-1,:),1),size(coord,1),1);

coord_=coord-m;

coord_=coord_.*S;
coord=coord_+m;


function [xUpdate,SUpdate,innov,Szz,W]=sqrtEKFUpdateWithPred(z,SR,zPred,otherInfo,innovTrans,stateTrans)
%%SQRTEKFUPDATEWITHPRED Given the output of the measurement prediction step
%           from sqrtEKFMeasPred and a measurement, complete the measurement
%           update step of the first-order square root extended Kalman
%           filter. Separating the measurement prediction step from the
%           rest of the update step can make the creation of multiple
%           measurement association hypotheses from a single target
%           prediction more efficient. The full measurement update function
%           is sqrtEKFUpdate.
%
%INPUTS: z The zDimX1 measurement vector.
%       SR The zDimXzDim lower-triangular square root of the measurement
%          covariance matrix in the native coordinate system of the
%          measurement.
%    zPred The zDimXnumComp measurement prediction from the filter.
% otherInfo The intermediate results returned in the otherInfo output of
%          the sqrtEKFMeasPred function.
% innovTrans An optional function handle that computes and optionally
%          transforms the value of the difference between the observation
%          and any predicted points. This is called as innovTrans(a,b) and
%          the default if omitted or an empty matrix is passed is
%          @(a,b)bsxfun(@minus,a,b). This must be able to handle sets of
%          values. For a zDimX1 measurement, either of the inputs could be
%          zDimXN in size while one of the inputs could be zDimX1 in size.
%          This only needs to be supplied when a measurement difference
%          must be restricted to a certain range. For example, the
%          innovation between two angles will be 2*pi if one angle is zero
%          and the other 2*pi, even though they are the same direction. In
%          such an instance, a function handle to the
%          wrapRange(bsxfun(@minus,a,b),-pi,pi) function with the
%          appropriate parameters should be passed for innovTrans.
% stateTrans An optional function that takes a state estimate and
%          transforms it. This is useful if one wishes the elements of the
%          state to be bound to a certain domain. For example, if an
%          element of the state is an angle, one should generally want to
%          bind it to the region +/-pi.
%
%OUTPUTS: xUpdate The xDimXnumComp updated state vectors.
%         SUpdate The updated xDimXxDimXnumComp lower-triangular square-
%                 root state covariance matrices.
%      innov, Szz The zDimXnumComp innovations and the zDimXzDimXnumComp
%                 square-root innovation covariance matrices are returned
%                 in case one wishes to analyze the consistency of the
%                 estimator or use those values in gating or likelihood
%                 evaluation.
%               W The xDimXzDimXnumComp gains used in the update.
%
%See the comments to the function sqrtEKFMeasPred for an example of usage
%of this function. See the comments to sqrtEKFUpdate for more information
%on the algorithm.
%
%June 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<6||isempty(stateTrans))
    stateTrans=@(x)x;
end

if(nargin<5||isempty(innovTrans))
    innovTrans=@(a,b)bsxfun(@minus,a,b);
end

H=otherInfo.H;
Pxz=otherInfo.Pxz;
xPred=otherInfo.xPred;
SPred=otherInfo.SPred;

xDim=size(xPred,1);
numComp=size(xPred,2);
zDim=size(z,1);

xUpdate=zeros(xDim,numComp);
SUpdate=zeros(xDim,xDim,numComp);
innov=zeros(zDim,numComp);
Szz=zeros(zDim,zDim,numComp);
W=zeros(xDim,zDim,numComp);
for k=1:numComp
    Szz(:,:,k)=tria([H(:,:,k)*SPred(:,:,k),SR]);
    W(:,:,k)=(Pxz(:,:,k)/Szz(:,:,k)')/Szz(:,:,k);

    innov(:,k)=innovTrans(z,zPred(:,k));
    xUpdate(:,k)=stateTrans(xPred(:,:,k)+W(:,:,k)*innov(:,k));

    temp=W(:,:,k)*H(:,:,k);
    SUpdate=tria([(eye(size(temp))-temp)*SPred(:,:,k),W(:,:,k)*SR]);
end
end

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


% gps.m
%   Compute the output of gps sensor
%
%  Revised:
%   3/5/2010 - RB
%   5/14/2010 - RB

function y = gps(uu, P)

    % relabel the inputs
    Va      = uu(1);
%    alpha   = uu(2);
%    beta    = uu(3);
    wn      = uu(4);
    we      = uu(5);
%    wd      = uu(6);
    pn      = uu(7);
    pe      = uu(8);
    pd      = uu(9);
%    u       = uu(10);
%    v       = uu(11);
%    w       = uu(12);
%    phi     = uu(13);
%    theta   = uu(14);
    psi     = uu(15);
%    p       = uu(16);
%    q       = uu(17);
%    r       = uu(18);
    t       = uu(19);

    persistent v_n;
    persistent v_e;
    persistent v_h;

    if t==0
        v_n = 0;
        v_e = 0;
        v_h = 0;
    else
        v_n = exp(-P.k_gps * P.Ts_gps) * v_n + P.sigma_gps_n * randn;
        v_e = exp(-P.k_gps * P.Ts_gps) * v_e + P.sigma_gps_e * randn;
        v_h = exp(-P.k_gps * P.Ts_gps) * v_h + P.sigma_gps_altitude * randn;
    end

    % construct North, East, and altitude GPS measurements
    y_gps_n = pn + v_n;
    y_gps_e = pe + v_e;
    y_gps_h = -pd + v_h;

    % construct groundspeed and course measurements
    V_n = Va * cos(psi) + wn;
    V_e = Va * sin(psi) + we;
    V_g = sqrt(V_n^2 + V_e^2);

    sigma_course = P.sigma_gps_V_g / V_g;

    y_gps_Vg     = sqrt(V_n^2 + V_e^2) + P.sigma_gps_V_g * randn;
    y_gps_course = atan2(V_e, V_n) + sigma_course * randn;

    % construct total output
    y = [...
        y_gps_n;...
        y_gps_e;...
        y_gps_h;...
        y_gps_Vg;...
        y_gps_course;...
        ];

end


%
%  Context-Aware Correlation Filters
%
%  Written by Matthias Mueller, 2016
%
%  This function takes care of setting up parameters,
%  and interfacing with the online tracking benchmark.

function results=run_MOSSE_CA(seq, res_path, bSaveImage)

%default settings
kernel.type =  'linear';

padding = 2;%1.75;  %extra area surrounding the target
lambda1 = 1e-4;     %regularization
lambda2 = 20;%0.8;
interp_factor = 0.05;%0.025;  %linear interpolation factor for adaptation
output_sigma_factor = 0.1; %0.06;  %spatial bandwidth (proportional to target)

features.gray = true;
features.hog = false;

cell_size = 1;

target_sz = seq.init_rect(1,[4,3]);
pos = seq.init_rect(1,[2,1]) + floor(target_sz/2);
img_files = seq.s_frames;
video_path = [];

%call tracker function with all the relevant parameters
[positions, time] = tracker(video_path, img_files, pos, target_sz, ...
    padding, kernel, lambda1, lambda2, output_sigma_factor, interp_factor, ...
    cell_size, features, false);

%return results to benchmark, in a workspace variable
rects = [positions(:,2) - target_sz(2)/2, positions(:,1) - target_sz(1)/2];
rects(:,3) = target_sz(2);
rects(:,4) = target_sz(1);
fps = numel(seq.s_frames) / time;
disp(['fps: ' num2str(fps)])
results.type = 'rect';
results.res = rects;
results.fps = fps;
%assignin('base', 'res', res);

end


function [rsvn,rsvp,rsvnSS,rsvpSS]=realized_semivariance(price,time,timeType,samplingType,samplingInterval,subsamples)
% Estimates Realized Semivariance and subsampled Realized Semivariance
%
% USAGE:
%   [RSVN,RSVP,RSVNSS,RSVPSS] = realized_semivariance(PRICE,TIME,TIMETYPE,SAMPLINGTYPE,SAMPLINGINTERVAL,SUBSAMPLES)
%
% INPUTS:
%   PRICE            - m by 1 vector of high frequency prices
%   TIME             - m by 1 vector of times where TIME(i) corresponds to PRICE(i)
%   TIMETYPE         - String describing the way times are measured
%                       'wall'    24-hour clock of the form HHMMSS, e.g. 101543 or 153217
%                       'seconds' Time measured in seconds past midnight on the first day.
%                       'unit'  Unit normalized date format, e.g. .1, .234, .9
%                         Unit normalized times are more general than the other types and can be
%                         applied to data from more than one calendar day
%   SAMPLINGTYPE     - String describing the type of sampling to use when
%                        filtering PRICE
%                        'CalendarTime' - Sample in calendar time using observations separated by SAMPLINGINTERVAL seconds
%                        'CalendarUniform' - Sample in calendar time using SAMPLINGINTERVAL
%                          observations spread uniformly between TIME(1) and TIME(m)
%                        'BusinessTime' - Sample in business (tick) time using observation separated
%                          by SAMPLINGINTERVAL ticks
%                        'BusinessUniform' - Sample in business (tick) time using observations
%                          uniformly spaced in business time.
%                        'Fixed' - Sample at specific points in time. When using fixed,
%                          SAMPLINGINTERVAL must be a n by 1 vector of times with the same TIMETYPE
%                          as TIME (i.e. seconds if TIME is in seconds)
%   SAMPLINGINTERVAL  - Scalar integer or n by 1 vector whose meaning depends on the selected SAMPLINGTYPE
%   SUBSAMPLES        - [OPTIONAL] Scalar integer indicating the number of subsample realized
%                         semivariance estimators to average with the original realized semivariance.
%                         Subsample realized semivariances are based on prices uniformly spaced between
%                         the times (Calendar sampling) or ticks (Business sampling).  SUBSAMPLES=1
%                         will compute a subsample realized semivariance using the mid-point of the
%                         price sample points, 2 will use 1/3 and 2/3, and so on. In general this
%                         number should be small so the subsample estimators will be "sparse".
%
% OUTPUTS:
%   RSVN              - Negative-part realized semivariance estimate
%   RSVP              - Positive-part realized semivariance estimate
%   RSVNSS            - Subsample averaged negative-part realized semivariance estimate
%   RSVPSS            - Subsample averaged positive-part realized semivariance estimate
%
% COMMENTS:
%
% EXAMPLES:
%  % 5-minute realized semivariance using wall time returns and fixed increments
%  fixedInterval = seconds2wall(wall2seconds(93000):300:wall2seconds(160000));
%  [RSVN,RSVP] = realized_semivariance(PRICE,TIME,'wall','Fixed',fixedInterval)
%
%  % 10-tick realized semivariance
%  [RSVN,RSVP] = realized_semivariance(PRICE,TIME,'wall','BusinessTime',10)
%
%  % 5-minute realized semivariance with subsampling every minute
%  fixedInterval = seconds2wall(wall2seconds(93000):300:wall2seconds(160000));
%  [RSVN,RSVP,RSVNSS,RSVPSS] = realized_semivariance(PRICE,TIME,'wall','Fixed',fixedInterval,5)
%
%  See also REALIZED_VARIANCE, REALIZED_KERNEL, REALIZED_QUANTILE_VARIANCE, REALIZED_RANGE,
%  REALIZED_PRICE_FILTER

% Copyright: Kevin Sheppard
% kevin.sheppard@economics.ox.ac.uk
% Revision: 1    Date: 5/1/2008

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input Checking
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin<5 || nargin>6
    error('Five or Six inputs required.')
end
if size(price,2)>size(price,1)
    price=price';
end
if size(price,2)>1
    error('PRICE must be a m by 1 vector.')
end
if size(time,2)>size(time,1)
    time=time';
end
if any(diff(time)<0)
    error('TIME must be sorted and increasing')
end
if size(time,2)>1 || length(time)~=length(price)
    error('TIME must be a m by 1 vector.')
end
% Inserted to protect against inputing integer times
time = double(time);

timeType=lower(timeType);
if ~ismember(timeType,{'wall','seconds','unit'})
    error('TIMETYPE must be one of ''wall'', ''seconds'' or ''unit''.');
end
samplingType=lower(samplingType);
if ~ismember(samplingType,{'calendartime','calendaruniform','businesstime','businessuniform','fixed'})
    error('SAMPLINGTYPE must be one of ''CalendarTime'', ''CalendarUniform'', ''BusinessTime'', ''BusinessUniform'' or ''Fixed''.');
end

m=size(price,1);
t0=time(1);
tT=time(m);
if ismember(samplingType,{'calendartime','calendaruniform','businesstime','businessuniform'})
    % Must be a scalar integer if timeType is seconds or wall
    if ismember(timeType,{'wall','seconds'})
        if ~isscalar(samplingInterval) || floor(samplingInterval)~=samplingInterval || samplingInterval<1
            error('SAMPLINGINTERVAL must be a positive integer for the SAMPLINGTYPE selected when using ''wall'' or ''seconds'' as TIMETYPE.')
        end
    else
        if ~isscalar(samplingInterval) || samplingInterval<0
            error('SAMPLINGINTERVAL must be a positive value for the SAMPLINGTYPE selected when using ''unit'' as TIMETYPE.')
        end
    end
else
    if size(samplingInterval,2)>size(samplingInterval,1)
        samplingInterval=samplingInterval';
    end
    if ~(any(samplingInterval>=t0) && any(samplingInterval<=tT))
        error('At least one sampling interval must be between min(TIME) and max(TIME) when using ''Fixed'' as SAMPLINGTYPE.')
    end
    if any(diff(samplingInterval)<=0)
        error('When using ''Fixed'' as SAMPLINGTYPE the vector of sampling times in SAMPLINGINTERVAL must be sorted and strictly increasing.')
    end
end

if nargin<6 || isempty(subsamples)
    subsamples = 1;
end
if nargin==6 && ~isempty(subsamples)
    if ~isscalar(subsamples) || subsamples<0 || floor(subsamples)~=subsamples
        error('SUBSAMPLES must be a non-negative scalar.')
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input Checking
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Convert times to unit if not already unit
if ~strcmp(timeType,'unit')
    [time,~,~,samplingInterval]=realized_convert2unit(time,timeType,samplingType,samplingInterval);
end
% Since everything is converted to unit, set timeType to unit
timeType='unit';

% Filter prices and compute the RV
logPrice = log(price);
filteredLogPrice = realized_price_filter(logPrice,time,timeType,samplingType,samplingInterval);
returns = diff(filteredLogPrice);
rsvn=sum((returns.^2).*(returns<0));
rsvp=sum((returns.^2).*(returns>0));

subsampledLogPrices = realized_subsample(logPrice,time,timeType,samplingType,samplingInterval,subsamples);
rsvns = zeros(subsamples,1);
rsvps = zeros(subsamples,1);
totalCount = 0;
for i=1:subsamples
    returns = diff(subsampledLogPrices{i});
    rsvns(i) = sum((returns.^2).*(returns<0));
    rsvps(i) = sum((returns.^2).*(returns>0));
     if i==1
        baseCount = length(returns);
    end
    totalCount = totalCount + length(returns);
end
rsvnSS = sum(rsvns)  * (baseCount / totalCount);
rsvpSS = sum(rsvps)  * (baseCount / totalCount);


function range= visutil_commonRangeForGA(erp, varargin)
%VISUTIL_COMMONRANGEFORGA - Determine plotting range for grand average ERPs
%
%Synposis:
% RANGE= visutil_commonRangeForGA(ERP, <OPT>)
%
%Input:
% ERP: cell of size [N x C] containing ERPs of N subjects and C conditions,
%      plotting ranges are determined for each condition separately
% OPT: struct or property/value list of optional properties:
%  .CLabERP, CLabScalp - channels to be considered for ERP/scalp plots,
%                        default: '*' (all channels)
%  .IvalERP, IvalScalp - interval for ERP/scalp plots to be considered,
%                        default: [] (whole ERP)
%  .SymERP, SymScalp   - make ERP/scalp range symmetric,
%                        default: false/true
%
%Output:
% RANGE: struct containing the two fields:
%  .erp   - plotting range for single channel ERPs
%  .scalp - plotting range for scalp maps

props= {'CLabERP'         '*'    'CELL{CHAR}|CHAR';
        'CLabScalp'       '*'    'CELL{CHAR}|CHAR';
        'IvalERP'         []     'DOUBLE[2]';
        'IvalScalp'       []     'DOUBLE';
        'SymERP'          0      'BOOL';
        'SymScalp'        1      'BOOL'
        'NiceRangeERP'    0      'DOUBLE';
        'EnlageRangeERP'  0.02   'DOUBLE';
       };

if nargin==0,
  range= props; return
end

misc_checkType(erp, 'CELL{STRUCT(x fs clab)}');
opt= opt_proplistToStruct(varargin{:});
[opt, isdefault]= opt_setDefaults(opt, props);
opt_checkProplist(opt, props);

if opt.NiceRangeERP && isdefault.EnlageRangeERP,
  opt.EnlageRangeERP= 0;
end

range.erp= [inf -inf];
if ~isempty(opt.IvalScalp),
  range.scalp= [inf -inf];
end

for ff= 1:size(erp,2),
  erp_ga= proc_grandAverage(erp{:,ff});

  tmp= proc_selectChannels(erp_ga, opt.CLabERP);
  if ~isempty(opt.IvalERP),
    tmp= proc_selectIval(tmp, opt.IvalERP);
  end
  range.erp(1)= min(range.erp(1), min(tmp.x(:)));
  range.erp(2)= max(range.erp(2), max(tmp.x(:)));

  if ~isempty(opt.IvalScalp),
    tmp= proc_jumpingMeans(erp_ga, opt.IvalScalp);
    tmp= proc_selectChannels(tmp, opt.CLabScalp);
    range.scalp(1)= min(range.scalp(1), min(tmp.x(:)));
    range.scalp(2)= max(range.scalp(2), max(tmp.x(:)));
  end

end

if opt.SymERP,
  range.erp= [-1 1]*max(abs(range.erp));
end
if opt.EnlageRangeERP>0,
  range.erp= range.erp + [-1 1]*opt.EnlageRangeERP*diff(range.erp);
end
if opt.NiceRangeERP>0,
  res= opt.NiceRangeERP;
  range.erp(1)= floor(res*range.erp(1))/res;
  range.erp(2)= ceil(res*range.erp(2))/res;
end
if ~isempty(opt.IvalScalp) && opt.SymScalp,
  range.scalp= [-1 1]*max(abs(range.scalp));
end


% std_readtopo() - returns the scalp map of a specified ICA component, assumed
%                  to have been saved in a Matlab file, [dataset_name].icatopo,
%                  in the same directory as the dataset file. If this file does
%                  not exist, use std_topo() to create it, else a pre-clustering
%                  function that calls it: pop_preclust() or eeg_preclust().
% Usage:
%   >> [grid, y, x ] = std_readtopo(ALLEEG, setindx, component);
%   >> [grid, y, x ] = std_readtopo(ALLEEG, setindx, component, transform, mode);
%
% Inputs:
%   ALLEEG     - vector of EEG datasets (can also be one EEG set).
%                must contain the dataset of interest (see 'setindx' below).
%   setindx    - [integer] an index of an EEG dataset in the ALLEEG
%                structure, for which to get the component ERP.
%   component  - [integer] index of the component for which the scalp map
%                grid should be returned.
%   transform  - ['none'!'laplacian'|'gradient'] transform scalp map to
%                laplacian or gradient map. Default is 'none'.
%   mode       - ['2dmap'|'preclust'] return either a 2-D array for direct
%                plotting ('2dmap') or an array formated for preclustering
%                with all the NaN values removed (ncomps x points). Default
%                is '2dmap' for 1 component and 'preclust' for several.
%
% Outputs:
%   grid      - square scalp-map color-value grid for the requested ICA component
%               in the specified dataset, an interpolated Cartesian grid as output
%               by topoplot().
%   y         - y-axis values for the interpolated grid
%   x         - x-axis values of the interpolated grid
%
%  See also  std_topo(), std_preclust()
%
% Authors: Arnaud Delorme, Hilit Serby, SCCN, INC, UCSD, February, 2005

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, October 11, 2004, hilit@sccn.ucsd.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function [X, yi, xi ] = std_readtopo(ALLEEG, abset, comps, option, mode)

X = [];
yi = [];
xi = [];
if nargin < 4
    option = 'none';
end;
if nargin < 5
    mode = '2Dmap';
end;
filename = correctfile(fullfile( ALLEEG(abset).filepath,[ ALLEEG(abset).filename(1:end-3) 'icatopo']));
tmpfile  = which(filename);
if ~isempty(tmpfile), filename = tmpfile; end;

while getfield(dir(filename), 'bytes') < 1000
    topo = load( '-mat', filename);
    filename = correctfile(topo.file);
    tmpfile  = which(filename);
    if ~isempty(tmpfile), filename = tmpfile; end;
end;

for k = 1:length(comps)

    if length(comps) < 3
        warning off;
        try
            topo = load( '-mat', filename, ...
                         [ 'comp' int2str(comps(k)) '_grid'], ...
                         [ 'comp' int2str(comps(k)) '_x'], ...
                         [ 'comp' int2str(comps(k)) '_y'] );
        catch
            error( [ 'Cannot read file ''' filename '''' ]);
        end;
        warning on;
    elseif k == 1
        try
            topo = load( '-mat', filename);
        catch
            error( [ 'Cannot read file ''' filename '''' ]);
        end;
    end;

    tmp =  getfield(topo, [ 'comp' int2str(comps(k)) '_grid' ]);

    if strcmpi(option, 'gradient')
        [tmpx, tmpy]  = gradient(tmp); % Gradient
        tmp        = tmpx;
        tmp(:,:,2) = tmpy;
    elseif strcmpi(option, 'laplacian')
        tmp = del2(tmp); % Laplacian
    end;

    if length(comps) > 1 | strcmpi(mode, 'preclust')
        tmp = tmp(find(~isnan(tmp))); % remove NaN for more than 1 component
    end;
    if k == 1
        X = zeros([ length(comps) size(tmp) ]) ;
    end
    X(k,:,:,:) =  tmp;
    if k == 1
        yi   = getfield(topo, [ 'comp' int2str(comps(k)) '_y']);
        xi   = getfield(topo, [ 'comp' int2str(comps(k)) '_x']);
    end;
end
X = squeeze(X);

return;

function filename = correctfile(filename)
    comp = computer;
    if filename(2) == ':' & ~strcmpi(comp(1:2), 'PC')
        filename = [filesep filename(4:end) ];
        filename(find(filename == '\')) = filesep;
    end;

    if ~exist(filename)
        [tmpp tmpf ext] = fileparts(filename);
        if exist([tmpf ext])
            filename = [tmpf ext];
        else
            [tmpp2 tmpp1] = fileparts(tmpp);
            if exist(fullfile(tmpp1, [ tmpf ext ]))
                filename = fullfile(tmpp1, [ tmpf ext ]);
            else
                error([ 'Cannot load file ''' [ tmpf ext ] '''' ]);
            end;
        end;
    end;


function img = imresizecrop(img, M, METHOD)
%
% img = imresizecrop(img, M, METHOD);
%
% Output an image of size M(1) x M(2).
%
% URL: http://labelme.csail.mit.edu/Release3.0/browserTools/php/matlab_toolbox.php

if nargin < 3
    METHOD = 'bilinear';
end

if length(M) == 1
    M = [M(1) M(1)];
end

scaling = max([M(1)/size(img,1) M(2)/size(img,2)]);

%scaling = M/min([size(img,1) size(img,2)]);

newsize = round([size(img,1) size(img,2)]*scaling);
img = imresize(img, newsize, METHOD);

[nr nc cc] = size(img);

sr = floor((nr-M(1))/2);
sc = floor((nc-M(2))/2);

img = img(sr+1:sr+M(1), sc+1:sc+M(2),:);


function [s_train, s_test, vocab_item, vocab_user, ui_train] = load_data(train_path, test_path, L, T)
    % Codes for loading data from local file
    %
    % ARGS:
    % train_path    : the given path to training file
    % test_path     : the given path to test file
    % L             : the length of sequence
    % T             : number of targets
    %
    % RETURN:
    % s_train       : the resulted training instances
    % s_test        : the resulted test instances
    % vocab_item    : the relationship vocabulary between new item id and origin item id
    % vocab_user    : the relationship vocabulary between new user id and origin user id
    % ui_train      : rated item of each user

    max_length = L + T;
    train_ratio = L/max_length;

    fid_train = fopen(train_path);
    fid_test = fopen(test_path);

    % train
    data = textscan(fid_train, '%f\t%f\t%f');
    fclose(fid_train);
    train = cell2mat(data);
    clear data;

    vocab_user = unique(train(:, 1));
    vocab_item = unique(train(:, 2));

    s_train = cell(1e+6, 3); % data, label, user
    s_test = cell(1e+6, 3);
    ui_train = cell(length(vocab_user), 1);

    cnt = 1;
    for i=1:length(vocab_user)
        new_user_id = i;
        old_user_id = vocab_user(i);
        ind = train(:, 1) == old_user_id;
        items = train(ind, 2);
        [~, items_] = ismember(items, vocab_item);
        ui_train{new_user_id} = items_;
        if length(items_) <= max_length
            items_new = zeros(max_length,1);
            items_new(max_length - length(items_)+1:end) = items_;
            ind_train = floor(length(items_new) * train_ratio);

            s_train{cnt, 1} = items_new(1:ind_train);
            s_train{cnt, 2} = items_new(ind_train+1:end);
            s_train{cnt, 3} = new_user_id;
            cnt = cnt + 1;

            s_test{new_user_id, 1} = items_new(end-floor(max_length*train_ratio)+1:end);
            s_test{new_user_id, 3} = new_user_id;
        else
            ind_label = max_length:1:length(items_);
            for j=ind_label
                inds = (j-max_length+1) : j;
                ind_ = floor(max_length * train_ratio);
                ind_train = inds(1: ind_);
                ind_test = inds(ind_+1:end);
                s_train{cnt, 1} = items_(ind_train);
                s_train{cnt, 2} = items_(ind_test);
                s_train{cnt, 3} = new_user_id;
                cnt = cnt + 1;
            end

            s_test{new_user_id, 1} = items_(end-floor(max_length*train_ratio)+1:end);
            s_test{new_user_id, 3} = new_user_id;
        end
    end

    % test
    data = textscan(fid_test, '%f\t%f\t%f');
    fclose(fid_test);
    test = cell2mat(data);
    clear data;

    for i=1:length(vocab_user)
        new_user_id = i;
        old_user_id = vocab_user(i);

        ind = test(:, 1) == old_user_id;
        items = test(ind, 2);
        [~, items_] = ismember(items, vocab_item);
        s_test{new_user_id, 2} = items_;
    end

    empty_cells = cellfun(@isempty, s_train);
    empty_rows = empty_cells(:,1) == 1;
    s_train(empty_rows, :) = [];

    empty_cells = cellfun(@isempty, s_test);
    empty_rows = empty_cells(:,1) == 1;
    s_test(empty_rows, :) = [];
end


% This demo shows the working steps for artefact reduction using MARA.
% It requires
%    - the function <fastica.m>
%    - the data fiels which contain the classifier,
%       <fv_training_MARA.mat>  and  <inv_matrix_icbm152.mat>
%       http://www.user.tu-berlin.de/irene.winkler/artifacts/MARAtrdata.zip

eeg_file= fullfile(BTB.DataDir, 'demoMat', 'VPiac_10_10_13', ...
                   'calibration_CenterSpellerMVEP_VPiac');

% Load data
try
  [cnt, mrk, mnt] = file_loadMatlab(file);
catch
  error('You need to run ''demo_convert_ERPSpeller'' first');
end

%High-pass filter the data (ICA otherwise finds drifts)
high_pass_fs = 1; %at 1 Hz in this example
[b, a] = butter(2, high_pass_fs/(cnt.fs/2), 'high');
cnt = proc_filtfilt(cnt, b, a);

%Do FastICA
[icasig, A_ica, W_ica] = fastica(cnt.x'); % 'maxNumIterations', 50);
cnt_ica = cnt; cnt_ica.x = cnt.x *W_ica';

%Classify components (artefact vs. neuro) using MARA
disp('MARA Artefact Classification ...')
[goodcomp, info] = proc_MARA(cnt_ica,mnt.clab,A_ica);
fprintf('MARA identified %d artifactual components. \n', ... ...
        length(A_ica(1,:))- length(goodcomp));
fprintf('Kept %d components \n',length(goodcomp));

%Plot each classified components to check if ICA separation and MARA
%classification was successful
plot_BSScomponents(cnt_ica, mnt, W_ica, A_ica, 'goodcomp', goodcomp, 'out', info.out_p);

%Remove activity to get (hopefully) cleaner EEG signals: Reconstruct EEG
%only with the good components in goodcomp
cnt_clean = cnt;
cnt_clean.x =  cnt.x * W_ica(goodcomp, :)' * A_ica(:, goodcomp)';


function modelOut = addExoMetToEFBA(model,exoMet,param)
% generates H and h to add a min (alpha/2)(v-h)'*H*(v-h) term to an EFBA problem
%
% USAGE:
%   modelOut = addExoMetToEFBA(model,exoMet,param)
%
% INPUTS:
%  model.S:
%  model.rxns:
%
%  exoMet.rxns:
%  exoMet.mean:
%  exoMet.SD:
%
% OPTIONAL INPUT
%  param.printLevel:
%  param.alpha:              alpha in (alpha/2)(v-h)'*H*(v-h), default = 10000;
%  param.metabolomicWeights: String indicating the type of weights to be applied to penalise the difference
%                            between of predicted and experimentally measured fluxes by, where
%                            'SD'   weights = 1/(1+exoMet.SD^2)
%                            'mean' weights = 1/(1+exoMet.mean^2)  (Default)
%                            'RSD'  weights = 1/((exoMet.SD./exoMet.mean)^2)
%  param.relaxBounds: True to relax bounds on reaction whose fluxes are to be fitted to exometabolomic data
%
% OUTPUTS:
%  modelOut:
%
% EXAMPLE:
%
% NOTE:
%
% Author(s):

if ~exist('param','var')
    param=struct;
end
if ~isfield(param,'printLevel')
    param.printLevel=0;
end
if ~isfield(param,'alpha')
    param.alpha=10000;
end
if ~isfield(param,'relaxBounds')
    param.relaxBounds=1;
end
if ~isfield(param,'metabolomicWeights')
    param.metabolomicWeights = 'mean';
end

[bool, locb] = ismember(exoMet.rxns, model.rxns);
if any(locb == 0)
    if printLevel > 0
        fprintf('%s\n','The following exometabolomic exchange reactions were not found in the model:')
        disp(exoMet.rxns(locb == 0))
    end
end

if length(unique(exoMet.rxns)) ~= length(exoMet.rxns) && printLevel > 0
    disp('There are duplicate rxnID entries in the metabolomic data! Only using data corresponding to first occurance')
end

% Assume mean model flux is equal to the mean experimental reaction flux.
[~,nRxn] = size(model.S);
vExp = NaN * ones(nRxn,1);
vExp(locb(bool)) = exoMet.mean(bool);

vSD = NaN * ones(nRxn,1);
vSD(locb(bool)) = exoMet.SD(bool);

% Set the weight on the Euclidean distance of the predicted steady state
% flux from the experimental steady state flux. Uniform at first.
weightExp = ones(nRxn,1);
% The weight penalty on relaxation from the experimental flux vector should be greater than that
% on the lower and upper bounds, if the experimental data is considered more reliable
% than the lower and upper bounds of the model.
% Assumes the lower and upper bound of standard deviation of
% experimental reaction flux are separated by two standard
% deviations.

% Penalise the relaxation from the experimental flux value by 1/(1+weights^2)
switch param.metabolomicWeights
    case 'SD'
        weightExp(locb(bool)) = 1 ./ (1 +  (vSD(locb(bool))).^2);
    case 'mean'
        weightExp(locb(bool)) = 1 ./ (1 + (vExp(locb(bool))).^2);
    case 'RSD'
        weightExp(locb(bool)) = 1 ./ ((vSD(locb(bool))./vExp(locb(bool))).^2);
    otherwise
        weightExp(locb(bool)) = 2;
end
% Weights are ignored on the reactions without experimental data, i.e. vExp(n) == NaN.
weightExp(~isfinite(vExp)) = 0;

%add
model.H=diag(sparse(weightExp*param.alpha));
model.h=vExp;
if param.printLevel>1
    figure;
    histogram(weightExp)
    xlabel('weights on the diagonal of model.H')
    ylabel('#reactions')
end

if param.relaxBounds
    bool=ismember(model.rxns,exoMet.rxns);
    model.lb(bool) = model.lb_preconstrainRxns(bool);
    model.ub(bool) = model.ub_preconstrainRxns(bool);
end

modelOut = model;
end


function value = i4vec_any_negative ( n, a )

%*****************************************************************************80
%
%% I4VEC_ANY_NEGATIVE: ( any A < 0 ) for I4VEC's.
%
%  Discussion:
%
%    An I4VEC is a vector of I4's.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries.
%
%    Input, integer A(N), the vector.
%
%    Output, logical VALUE is TRUE if any entry is negative.
%
  value = any ( a(1:n) < 0 );

  return
end