function M = getmassmatvec(elem2edge,area,Dlambda,elemType,K)
%% GETMASSMATVEC Get the mass matrix of vector finite element space
%
% M = GETMASSMATVEC(elem2edge,area,Dlambda,elemType,K) get mass matrix of
% the finite element space specified by elemType. The coefficient K is
% piecewise constant.
%
% The elemType can be:
%
% - "RT0": The lowest order Raviart-Thomas element
% - "BDM1": The lowest order Brezzi-Douglas-Michel element
% - "BDM1B": The BDM element enriched by the curl of cubic bubble function
% - "ND0": The lowest order Nedelec element
% - "RT1": Linear-Quadratic Rvairart-Thomas element
%
% Note that RT0 and ND0 share the same mass matrix.
%
% RT0, BMD1 are created by Ming Wang at July, 2012. Improved by Long Chen.
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

if ~exist('K','var'), K = []; end
NE = double(max(elem2edge(:)));
NT = size(elem2edge,1);
DiDj = zeros(NT,3,3);
for i = 1:3
    for j = i:3
        if isempty(K)
            DiDj(:,i,j) = dot(Dlambda(:,:,i),Dlambda(:,:,j),2);
        else
            switch size(K,2)
                case 1 % scalar K
                    DiDj(:,i,j) = dot(Dlambda(:,:,i),Dlambda(:,:,j),2)./K;
                case 2 % diagonal matrix
                    DiDj(:,i,j) =  Dlambda(:,1,i).*Dlambda(:,1,j)./K(:,1) ...
                                 + Dlambda(:,2,i).*Dlambda(:,2,j)./K(:,2);
                case 3 % K is 2 by 2 SPD matrix
                    detK = K(:,1).*K(:,2) - K(:,3).^2;
                    DiDj(:,i,j) = (Dlambda(:,1,i).*Dlambda(:,1,j).*K(:,2) ...
                                 + Dlambda(:,2,i).*Dlambda(:,2,j).*K(:,1) ...
                                 - Dlambda(:,1,i).*Dlambda(:,2,j).*K(:,3) ...
                                 - Dlambda(:,2,i).*Dlambda(:,1,j).*K(:,3))./detK;

            end
        end
        DiDj(:,j,i) = DiDj(:,i,j);
    end
end
localEdge = [2 3; 1 3; 1 2]; % ascend ordering

%% RT0 and ND0
if strcmp(elemType,'RT0') || strcmp(elemType,'ND0')
    M = sparse(NE,NE);
    for i = 1:3
        for j = i:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2); % [i1,i2] is the edge opposite to vertex i.
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % computation of mass matrix --- (phi_i, phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             - (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if (j==i)
                M = M + sparse(ii,jj,Mij,NE,NE);
            else
                M = M + sparse([ii;jj],[jj;ii],[Mij; Mij],NE,NE);
            end
        end
    end
end

%% BDM1
if strcmp(elemType,'BDM1') || strcmp(elemType,'BDM1B') || strcmp(elemType,'RT1')
    M = sparse(2*NE,2*NE);
    for i = 1:3
        for j = i:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2); % [i1,i2] is the edge opposite to vertex i.
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % computation of mass matrix, note that (rot u, rot v) = (grad u, grad v)
            % (phi_i, phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             - (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if (j==i)
                M = M + sparse(ii,jj,Mij,2*NE,2*NE);
            else
                M = M + sparse([ii;jj],[jj;ii],[Mij; Mij],2*NE,2*NE);
            end
            % (psi_i,psi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             + (1+(i1==j2))*DiDj(:,i2,j1) ...
                             + (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if (j==i)
                M = M + sparse(ii+NE,jj+NE,Mij,2*NE,2*NE);
            else
                M = M + sparse([ii;jj]+NE,[jj;ii]+NE,[Mij; Mij],2*NE,2*NE);
            end
        end
    end
    for i = 1:3
        for j = 1:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2);
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % (psi_i,phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             + (1+(i2==j1))*DiDj(:,i1,j2) ...
                             - (1+(i2==j2))*DiDj(:,i1,j1));
            M = M + sparse([ii+NE;jj],[jj;ii+NE],[Mij; Mij],2*NE,2*NE);
        end
    end
end

%% BDM1B
if strcmp(elemType,'BDM1B')
    newM = sparse(2*NE+NT,2*NE+NT);
    newM(1:2*NE,1:2*NE) = M;
    M = newM;
    % (phi_i, bubble)
    for i = 1:3
        ii = double(elem2edge(:,i));
        jj = double((1:NT)');
        i1 = localEdge(i,1); i2 = localEdge(i,2); i3 = 6-i1-i2;
        Mij = 9/10*area.*(DiDj(:,i2,i3)...
                         +DiDj(:,i2,i2)...
                         -DiDj(:,i1,i3)...
                         -DiDj(:,i1,i1));
        M = M + sparse([ii;jj+2*NE],[jj+2*NE;ii],[Mij;Mij],2*NE+NT,2*NE+NT);
    end
    clear ii jj i1 i2 i3 Mij;
    % (psi_i, bubble)
    for i = 1:3
        ii = double(elem2edge(:,i));
        jj = double((1:NT)');
        i1 = localEdge(i,1); i2 = localEdge(i,2); i3 = 6-i1-i2;
        Mij = 9/10*area.*(DiDj(:,i2,i3)...
                        + DiDj(:,i1,i3)...
                        + DiDj(:,i2,i2)...
                        + DiDj(:,i1,i1)...
                        + DiDj(:,i1,i2));
        M = M + sparse([ii+NE;jj+2*NE],[jj+2*NE;ii+NE],[Mij;Mij],2*NE+NT,2*NE+NT);
    end
    clear ii jj i1 i2 i3 Mij;
    % (bubble, bubble)
    ii = 1+2*NE:NT+2*NE;
    Mij = 81/10*area.*(DiDj(:,1,1)...
                    + DiDj(:,1,2)...
                    + DiDj(:,1,3)...
                    + DiDj(:,2,2)...
                    + DiDj(:,2,3)...
                    + DiDj(:,3,3));
    if ~isempty(K)
        Mij = Mij./K;
    end
    M = M + sparse(ii,ii,Mij,2*NE+NT,2*NE+NT);
end

%% RT1
elem2dof = [elem2edge elem2edge+NE (1:NT)'+2*NE (1:NT)'+2*NE+NT];
locBasesIdx = [1 2 0; 1 3 0; 2 3 0; ... % phi and psi
               2 1 3; 3 1 2];           % chi
if strcmp(elemType,'RT1')
    newM = sparse(2*NE+2*NT,2*NE+2*NT);
    newM(1:2*NE,1:2*NE) = M;
    M = newM;
    % (phi_i, chi_j)
    for i = 1:3
        for j = 1:2
            ii = double(elem2dof(:,i));
            jj = double(elem2dof(:,j+6));
            i1 = locBasesIdx(i,1); i2 = locBasesIdx(i,2); %i3 = locBasesIdx(i,3);
            j1 = locBasesIdx(j,1); j2 = locBasesIdx(j,2); j3 = locBasesIdx(j,3);
            Mij = intlambda([j1,i1,j2],2)*DiDj(:,i2,j3) ...
                 -intlambda([j1,i1,j3],2)*DiDj(:,i2,j2) ...
                 -intlambda([j1,i2,j2],2)*DiDj(:,i1,j3) ...
                 +intlambda([j1,i2,j3],2)*DiDj(:,i1,j2);
            M = M + sparse([ii;jj],[jj;ii],[Mij;Mij],2*NE+2*NT,2*NE+2*NT);
        end
    end
    clear ii jj i1 i2 i3 Mij;
    % (psi_i, chi_j)
    for i = 1:3
        for j = 1:2
            ii = double(elem2dof(:,i+3));
            jj = double(elem2dof(:,j+6));
            i1 = locBasesIdx(i,1); i2 = locBasesIdx(i,2); %i3 = locBasesIdx(i,3);
            j1 = locBasesIdx(j,1); j2 = locBasesIdx(j,2); j3 = locBasesIdx(j,3);
            Mij = intlambda([j1,i1,j2],2)*DiDj(:,i2,j3) ...
                 -intlambda([j1,i1,j3],2)*DiDj(:,i2,j2) ...
                 +intlambda([j1,i2,j2],2)*DiDj(:,i1,j3) ...
                 -intlambda([j1,i2,j3],2)*DiDj(:,i1,j2);
            M = M + sparse([ii;jj],[jj;ii],[Mij;Mij],2*NE+2*NT,2*NE+2*NT);
        end
    end
    clear ii jj i1 i2 i3 Mij;
    for i = 1:2
        for j = 1:2
            % (chi_j,chi_i)
            ii = double(elem2dof(:,i+3));
            jj = double(elem2dof(:,j+6));
            i1 = locBasesIdx(i,1); i2 = locBasesIdx(i,2); i3 = locBasesIdx(i,3);
            j1 = locBasesIdx(j,1); j2 = locBasesIdx(j,2); j3 = locBasesIdx(j,3);
            Mij = intlambda([i1,j1,i2,j2],2)*DiDj(:,i3,j3) ...
                 -intlambda([i1,j1,i2,j3],2)*DiDj(:,i3,j2) ...
                 -intlambda([i1,j1,i3,j2],2)*DiDj(:,i2,j3) ...
                 +intlambda([i1,j1,i3,j3],2)*DiDj(:,i2,j2);
            M = M + sparse([ii;jj],[jj;ii],[Mij;Mij],2*NE+2*NT,2*NE+2*NT);
        end
    end
end


% Local Regression and Likelihood, Figure 4.1.
% Author: Catherine Loader
%
% Local Likelihood (Poisson Regression).

load mine;
fit = locfit(extrp,frac,'family','poisson','deg',1,'alpha',0.6);
figure('Name','fig4_1: Poisson Regression');
lfplot(fit);
lfband(fit);


function [B,twom] = multiord_f(A,gamma,omega)
%MULTIORD_F  returns multilayer Newman-Girvan modularity matrix for ordered undirected layers, function handle version
% Only works for undirected networks
%
% Version: 2.2.0
% Date: Thu 11 Jul 2019 12:25:42 CEST
%
%   Input: A: Cell array of NxN adjacency matrices for each layer of an
%          ordered undirected multilayer network
%          gamma: intralayer resolution parameter
%          omega: interlayer coupling strength
%
%   Output: B: function handle where B(i) returns the ith column of
%          [NxT]x[NxT] flattened modularity tensor for the
%           multilayer network with uniform ordinal coupling (T is
%           the number of layers of the network)
%           twom: normalisation constant
%
%   Example of usage: [B,twom]=multiord_f(A,gamma,omega);
%          [S,Q]= genlouvain(B); % see iterated_genlouvain.m and
%          postprocess_ordinal_multilayer.m for how to improve output
%          multilayer partition
%          Q=Q/twom;
%          S=reshape(S,N,T);
%
%   [B,twom] = MULTIORD_F(A,GAMMA, OMEGA) with A a cell array of square
%   symmetric matrices of equal size each representing an undirected network
%   "layer" computes the multilayer Newman-Girvan modularity matrix using
%   the quality function described in Mucha et al. 2010, with intralayer
%   resolution parameter GAMMA, and with interlayer coupling OMEGA connecting
%   nearest-neighbor ordered layers.  The null model used for the quality
%   function is the Newman-Girvan null model (see e.g. Bazzi et al. for other
%   possible null models). Once the mulilayer modularity matrix is computed,
%   optimization can be performed by the generalized Louvain code GENLOUVAIN
%   or ITERATED_GENLOUVAIN. The output B can be used with other heuristics,
%   provided the same mapping is used to go from the multilayer tensor to
%   the multilayer flattened matrix. That is, the node-layer tuple (i,s)
%   is mapped to i + (s-1)*N. [Note that we can define a mapping between a
%   multilayer partition S_m stored as an N by T matrix and the corresponding
%   flattened partition S stored as an NT by 1 vector. In particular
%   S_m = reshape(S,N,T) and S = S_m(:).]
%
%
%   See also
%       genlouvain heuristics:      GENLOUVAIN, ITERATED_GENLOUVAIN
%       multilayer wrappers:        MULTICAT, MULTICATF, MULTIORD
%       other heuristics:           SPECTRAL23
%       Kernighan-Lin improvement:  KLNB
%
%   Notes:
%     The matrices in the cell array A are assumed to be square,
%     symmetric, and of equal size.  These assumptions are not checked here.
%
%     For smaller systems, it is potentially more efficient (and easier) to
%     directly use the sparse quality/modularity matrix B in MULTIORD. For
%     large systems with directed layer networks, use MULTIORDDIR_F.
%
%     This code serves as a template and can be modified for situations
%     with other wrinkles (e.g., different intralayer null models,
%     different numbers of nodes from layer-to-layer, or systems which are
%     both multiplex and longitudinal).  That is, this code is only a
%     starting point; it is by no means exhaustive.
%
%     By using this code, the user implicitly acknowledges that the authors
%     accept no liability associated with that use.  (What are you doing
%     with it anyway that might cause there to be a potential liability?!?)
%
%   References:
%     Blondel, Vincent D., Jean-Loup Guillaume, Renaud Lambiotte, and
%     Etienne Lefebvre, "Fast unfolding of communities in large networks,"
%     Journal of Statistical Mechanics: Theory and Experiment, P10008
%     (2008).
%
%     Fortunato, Santo, "Community detection in graphs," Physics Reports
%     486, 75-174 (2010).
%
%     Good, Benjamin H., Yves-Alexandre de Montjoye, and Aaron Clauset,
%     "Performance of modularity maximization in practical contexts,"
%     Physical Review E 81, 046106 (2010).
%
%     Newman, Mark E. J. and Michelle Girvan. "Finding and Evaluating
%     Community Structure in Networks", Physical Review E 69, 026113 (2004).
%
%     Mucha, Peter J., Thomas Richardson, Kevin Macon, Mason A. Porter, and
%     Jukka-Pekka Onnela. "Community Structure in Time-Dependent,
%     Multiscale, and Multiplex Networks," Science 328, 876-878 (2010).
%
%     Bazzi, Marya, Mason A. Porter, Stacy Williams, Mark McDonald, Daniel
%     J. Fenn, and Sam D. Howison. "Community Detection in Temporal
%     Multilayer Networks, with an Application to Correlation Networks",
%     MMS: A SIAM Interdisciplinary Journal 14, 1-41 (2016).
%
%     Porter, M. A., J. P. Onnela, and P. J. Mucha, "Communities in
%     networks," Notices of the American Mathematical Society 56, 1082-1097
%     & 1164-1166 (2009).
%
%   Acknowledgments:
%     Thank you to Dani Bassett, Jesse Blocher, Bruce Rogers, and Simi Wang
%     for their collaborative help which led to significant cleaning up
%     of earlier versions of our multilayer community detection codes.

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

if nargin<3
    omega=1;
end

N=length(A{1});
T=length(A);

if length(gamma)==1
    gamma=repmat(gamma,T,1);
end

ii=[]; jj=[]; vv=[];
ki=[]; kj=[]; kv=[];
twom=0;
for s=1:T
    indx=(1:N)'+(s-1)*N;
    [i,j,v]=find(A{s});
    ii=[ii;indx(i)]; jj=[jj;indx(j)]; vv=[vv;v];
    k=sum(A{s});
    mm=sum(k);
    twom=twom+mm;
    ki=[ki;indx];
    kj=[kj;ones(N,1)*s];
    kv=[kv;k(:)./mm];
end
AA = sparse(ii,jj,vv,N*T,N*T);
K=sparse(ki,kj,kv,N*T,T);
clear ii jj vv ki kj kv
kvec = full(sum(AA));
AA = AA + omega*spdiags(ones(N*T,2),[-N,N],N*T,N*T);
B = @(i) AA(:,i) - gamma(ceil(i/(N+eps)))*K(:,ceil(i/(N+eps)))*kvec(i);
twom=twom+2*N*(T-1)*omega;

end


function plotData(X, y)
%PLOTDATA Plots the data points X and y into a new figure
%   PLOTDATA(x,y) plots the data points with + for the positive examples
%   and o for the negative examples. X is assumed to be a Mx2 matrix.

% Create New Figure
figure; hold on;

% ====================== YOUR CODE HERE ======================
% Instructions: Plot the positive and negative examples on a
%               2D plot, using the option 'k+' for the positive
%               examples and 'ko' for the negative examples.
%

% Find Indices of Positive and Negative Examples
pos = find(y==1); neg = find(y==0);

% Plot Examples
plot(X(pos, 1), X(pos, 2), 'k+', 'LineWidth', 2, 'MarkerSize', 7);
plot(X(neg, 1), X(neg, 2), 'ko', 'MarkerFaceColor', 'y', 'MarkerSize', 7);

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

hold off;

end


function holdout_sets = xval_select_holdout_set_categoricalcovs(covs)

u = unique(covs, 'rows');
nu = size(u, 1);  % number of unique cells; also size of holdout sets

[N, k] = size(covs);

onevec = ones(N, 1);

% indices for each cell
for i = 1:nu
    cell_indices{i} = all(covs - u(i * onevec, :) == 0, 2);
end

nobs_per_cell = sum(cat(2, cell_indices{:}));
nfolds = max(nobs_per_cell);  % number of folds; max() leaves some unbalanced holdout sets; min keeps balance but does not test all obs

% random selection of one obs per cell for each fold
for i = 1:nu
    wh_obs{i} = find(cell_indices{i});
    wh_obs{i} = wh_obs{i}(randperm(nobs_per_cell(i)));
end

% deal observations into folds
for i = 1:nfolds
    wh = [];
    for j = 1:nu
        if nobs_per_cell(j) >= i
            wh = [wh wh_obs{j}(i)];
        end
    end

    holdout_sets{i} = logical(false * onevec);
    holdout_sets{i}(wh) = true;

end

end  % function

% checking stuff
% allsets = cat(2, holdout_set{:});
% sum(allsets)
% sum(allsets, 2)
% covs(holdout_set{1}, :)
% covs(holdout_set{2}, :)
% covs(holdout_set{3}, :)
% covs(holdout_set{4}, :)
% covs(holdout_set{end}, :)


function x = simuARMA(a,b,nobs)
% x = simuARMA(a,b,nobs)
% simulation of nobs observations of an ARMA process with parameters
% a,b en standard deviation 1.
%
% No transients in finite signal
% Paper:
%
%   Broersen, P.M.T. and S. de Waele
% 	Generating Data with Prescribed Power Spectral Density.
%	IEEE Trans. on Instrumentation and Measurement, vol. 52, no. 4, p 1061-1067, 2003.
%
%
% uses randn( , )
%

aro = length(a)-1;
mao = length(b)-1;
[cor,g]=arma2cor(a,b);
[cor2,gar]=arma2cor(a,1);

if ~aro,
   v = randn(nobs+mao,1)/sqrt(g);
else
   z = randn(aro,1);
   vs = zeros(aro,1);
   [at rc] = ar2arset(a);
   f = 1;
   vs(1) = f*z(1);
   al = [];
   for i = 2:aro,
   	f = sqrt(1-rc(i)^2)*f;
      al = [al 0] + rc(i)*[fliplr(al) 1];
      vs(i) = f*z(i)-al*vs(i-1:-1:1);
   end %for i = 2:aro,
   vs = vs*sqrt(gar/g);
   v = armafilter(randn(nobs+mao,1)/sqrt(g),a,1,vs,z);
end %if ~aro,
x = armafilter(v,1,b);
x = x(mao+1:mao+nobs);


#!/usr/bin/env octave
%% Machine Learning Online Class
%  Exercise 6 | Support Vector Machines
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the
%  exercise. You will need to complete the following functions:
%
%     gaussianKernel.m
%     dataset3Params.m
%     processEmail.m
%     emailFeatures.m
%
%  For this exercise, you will not need to change any code in this file,
%  or any other files other than those mentioned above.
%

%% Initialization
clear ; close all; clc

%% =============== Part 1: Loading and Visualizing Data ================
%  We start the exercise by first loading and visualizing the dataset.
%  The following code will load the dataset into your environment and plot
%  the data.
%

fprintf('Loading and Visualizing Data ...\n')

% Load from ex6data1:
% You will have X, y in your environment
load('ex6data1.mat');

% Plot training data
plotData(X, y);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% ==================== Part 2: Training Linear SVM ====================
%  The following code will train a linear SVM on the dataset and plot the
%  decision boundary learned.
%

% Load from ex6data1:
% You will have X, y in your environment
load('ex6data1.mat');

fprintf('\nTraining Linear SVM ...\n')

% You should try to change the C value below and see how the decision
% boundary varies (e.g., try C = 1000)
C = 1;
model = svmTrain(X, y, C, @linearKernel, 1e-3, 20);
visualizeBoundaryLinear(X, y, model);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% =============== Part 3: Implementing Gaussian Kernel ===============
%  You will now implement the Gaussian kernel to use
%  with the SVM. You should complete the code in gaussianKernel.m
%
fprintf('\nEvaluating the Gaussian Kernel ...\n')

x1 = [1 2 1]; x2 = [0 4 -1]; sigma = 2;
sim = gaussianKernel(x1, x2, sigma);

fprintf(['Gaussian Kernel between x1 = [1; 2; 1], x2 = [0; 4; -1], sigma = 0.5 :' ...
         '\n\t%f\n(this value should be about 0.324652)\n'], sim);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% =============== Part 4: Visualizing Dataset 2 ================
%  The following code will load the next dataset into your environment and
%  plot the data.
%

fprintf('Loading and Visualizing Data ...\n')

% Load from ex6data2:
% You will have X, y in your environment
load('ex6data2.mat');

% Plot training data
plotData(X, y);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% ========== Part 5: Training SVM with RBF Kernel (Dataset 2) ==========
%  After you have implemented the kernel, we can now use it to train the
%  SVM classifier.
%
fprintf('\nTraining SVM with RBF Kernel (this may take 1 to 2 minutes) ...\n');

% Load from ex6data2:
% You will have X, y in your environment
load('ex6data2.mat');

% SVM Parameters
C = 1; sigma = 0.1;

% We set the tolerance and max_passes lower here so that the code will run
% faster. However, in practice, you will want to run the training to
% convergence.
model= svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));
visualizeBoundary(X, y, model);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% =============== Part 6: Visualizing Dataset 3 ================
%  The following code will load the next dataset into your environment and
%  plot the data.
%

fprintf('Loading and Visualizing Data ...\n')

% Load from ex6data3:
% You will have X, y in your environment
load('ex6data3.mat');

% Plot training data
plotData(X, y);

fprintf('Program paused. Press enter to continue.\n');
pause;

%% ========== Part 7: Training SVM with RBF Kernel (Dataset 3) ==========

%  This is a different dataset that you can use to experiment with. Try
%  different values of C and sigma here.
%

% Load from ex6data3:
% You will have X, y in your environment
load('ex6data3.mat');

% Try different SVM Parameters here
[C, sigma] = dataset3Params(X, y, Xval, yval);

% Train the SVM
model= svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma));
visualizeBoundary(X, y, model);

fprintf('Program paused. Press enter to continue.\n');
pause;


function [x,flag,relres,iter,resvec] = Pgmres_deflation(A,b,restart,tol,maxit,M1,M2,x,varargin)
%GMRES   Generalized Minimum Residual Method.
%   X = GMRES(A,B) attempts to solve the system of linear equations A*X = B
%   for X.  The N-by-N coefficient matrix A must be square and the right
%   hand side column vector B must have length N. This uses the unrestarted
%   method with MIN(N,10) total iterations.
%
%   X = GMRES(AFUN,B) accepts a function handle AFUN instead of the matrix
%   A. AFUN(X) accepts a vector input X and returns the matrix-vector
%   product A*X. In all of the following syntaxes, you can replace A by
%   AFUN.
%
%   X = GMRES(A,B,RESTART) restarts the method every RESTART iterations.
%   If RESTART is N or [] then GMRES uses the unrestarted method as above.
%
%   X = GMRES(A,B,RESTART,TOL) specifies the tolerance of the method.  If
%   TOL is [] then GMRES uses the default, 1e-6.
%
%   X = GMRES(A,B,RESTART,TOL,MAXIT) specifies the maximum number of outer
%   iterations. Note: the total number of iterations is RESTART*MAXIT. If
%   MAXIT is [] then GMRES uses the default, MIN(N/RESTART,10). If RESTART
%   is N or [] then the total number of iterations is MAXIT.
%
%   X = GMRES(A,B,RESTART,TOL,MAXIT,M) and
%   X = GMRES(A,B,RESTART,TOL,MAXIT,M1,M2) use preconditioner M or M=M1*M2
%   and effectively solve the system inv(M)*A*X = inv(M)*B for X. If M is
%   [] then a preconditioner is not applied.  M may be a function handle
%   returning M\X.
%
%   X = GMRES(A,B,RESTART,TOL,MAXIT,M1,M2,X0) specifies the first initial
%   guess. If X0 is [] then GMRES uses the default, an all zero vector.
%
%   [X,FLAG] = GMRES(A,B,...) also returns a convergence FLAG:
%    0 GMRES converged to the desired tolerance TOL within MAXIT iterations.
%    1 GMRES iterated MAXIT times but did not converge.
%    2 preconditioner M was ill-conditioned.
%    3 GMRES stagnated (two consecutive iterates were the same).
%
%   [X,FLAG,RELRES] = GMRES(A,B,...) also returns the relative residual
%   NORM(B-A*X)/NORM(B). If FLAG is 0, then RELRES <= TOL. Note with
%   preconditioners M1,M2, the residual is NORM(M2\(M1\(B-A*X))).
%
%   [X,FLAG,RELRES,ITER] = GMRES(A,B,...) also returns both the outer and
%   inner iteration numbers at which X was computed: 0 <= ITER(1) <= MAXIT
%   and 0 <= ITER(2) <= RESTART.
%
%   [X,FLAG,RELRES,ITER,RESVEC] = GMRES(A,B,...) also returns a vector of
%   the residual norms at each inner iteration, including NORM(B-A*X0).
%   Note with preconditioners M1,M2, the residual is NORM(M2\(M1\(B-A*X))).
%
%   Example:
%      n = 21; A = gallery('wilk',n);  b = sum(A,2);
%      tol = 1e-12;  maxit = 15; M = diag([10:-1:1 1 1:10]);
%      x = gmres(A,b,10,tol,maxit,M);
%   Or, use this matrix-vector product function
%      %-----------------------------------------------------------------%
%      function y = afun(x,n)
%      y = [0; x(1:n-1)] + [((n-1)/2:-1:0)'; (1:(n-1)/2)'].*x+[x(2:n); 0];
%      %-----------------------------------------------------------------%
%   and this preconditioner backsolve function
%      %------------------------------------------%
%      function y = mfun(r,n)
%      y = r ./ [((n-1)/2:-1:1)'; 1; (1:(n-1)/2)'];
%      %------------------------------------------%
%   as inputs to GMRES:
%      x1 = gmres(@(x)afun(x,n),b,10,tol,maxit,@(x)mfun(x,n));
%
%   Class support for inputs A,B,M1,M2,X0 and the output of AFUN:
%      float: double
%
%   See also BICG, BICGSTAB, BICGSTABL, CGS, LSQR, MINRES, PCG, QMR, SYMMLQ,
%   TFQMR, ILU, FUNCTION_HANDLE.

%   References
%   H.F. Walker, "Implementation of the GMRES Method Using Householder
%   Transformations", SIAM J. Sci. Comp. Vol 9. No 1. January 1988.

%   Copyright 1984-2011 The MathWorks, Inc.
%   $Revision: 1.21.4.15 $ $Date: 2011/05/17 02:33:07 $
global ZH AH
if (nargin < 2)
    error(message('MATLAB:gmres:NumInputs'));
end

% Determine whether A is a matrix or a function.
[atype,afun,afcnstr] = iterchk(A);
if strcmp(atype,'matrix')
    % Check matrix and right hand side vector inputs have appropriate sizes
    [m,n] = size(A);
    if (m ~= n)
        error(message('MATLAB:gmres:SquareMatrix'));
    end
    if ~isequal(size(b),[m,1])
        error(message('MATLAB:gmres:VectorSize', m));
    end
else
    m = size(b,1);
    n = m;
    if ~iscolumn(b)
        error(message('MATLAB:gmres:Vector'));
    end
end

% Assign default values to unspecified parameters
if (nargin < 3) || isempty(restart) || (restart == n)
    restarted = false;
else
    restarted = true;
end
if (nargin < 4) || isempty(tol)
    tol = 1e-6;
end
warned = 0;
if tol < eps
    warning(message('MATLAB:gmres:tooSmallTolerance'));
    warned = 1;
    tol = eps;
elseif tol >= 1
    warning(message('MATLAB:gmres:tooBigTolerance'));
    warned = 1;
    tol = 1-eps;
end
if (nargin < 5) || isempty(maxit)
    if restarted
        maxit = min(ceil(n/restart),10);
    else
        maxit = min(n,10);
    end
end

if restarted
    outer = maxit;
    if restart > n
        warning(message('MATLAB:gmres:tooManyInnerItsRestart',restart, n));
        restart = n;
    end
    inner = restart;
else
    outer = 1;
    if maxit > n
        warning(message('MATLAB:gmres:tooManyInnerItsMaxit',maxit, n));
        maxit = n;
    end
    inner = maxit;
end

% Check for all zero right hand side vector => all zero solution
n2b = norm(b);                   % Norm of rhs vector, b
if (n2b == 0)                    % if    rhs vector is all zeros
    x = zeros(n,1);              % then  solution is all zeros
    flag = 0;                    % a valid solution has been obtained
    relres = 0;                  % the relative residual is actually 0/0
    iter = [0 0];                % no iterations need be performed
    resvec = 0;                  % resvec(1) = norm(b-A*x) = norm(0)
    if (nargout < 2)
        itermsg('gmres',tol,maxit,0,flag,iter,NaN);
    end
    return
end

if ((nargin >= 6) && ~isempty(M1))
    existM1 = 1;
    [m1type,m1fun,m1fcnstr] = iterchk(M1);  %Check the size of Precondioner.
    if strcmp(m1type,'matrix')
        if ~isequal(size(M1),[m,m])
            error(message('MATLAB:gmres:PreConditioner1Size', m));
        end
    end
else
    existM1 = 0;
    m1type = 'matrix';
end

if ((nargin >= 7) && ~isempty(M2))
    existM2 = 1;
    [m2type,m2fun,m2fcnstr] = iterchk(M2);
    if strcmp(m2type,'matrix')
        if ~isequal(size(M2),[m,m])
            error(message('MATLAB:gmres:PreConditioner2Size', m));
        end
    end
else
    existM2 = 0;
    m2type = 'matrix';
end

if ((nargin >= 8) && ~isempty(x))
    if ~isequal(size(x),[n,1])
        error(message('MATLAB:gmres:XoSize', n));
    end
else
    x = zeros(n,1);
end

if ((nargin > 8) && strcmp(atype,'matrix') && ...
        strcmp(m1type,'matrix') && strcmp(m2type,'matrix'))
    error(message('MATLAB:gmres:TooManyInputs'));
end

% Set up for the method
flag = 1;
xmin = x;                        % Iterate which has minimal residual so far
imin = 0;                        % "Outer" iteration at which xmin was computed
jmin = 0;                        % "Inner" iteration at which xmin was computed
tolb = tol * n2b;                % Relative tolerance
evalxm = 0;
stag = 0;
moresteps = 0;
maxmsteps = min([floor(n/50),5,n-maxit]);
maxstagsteps = 3;
minupdated = 0;

x0iszero = (norm(x) == 0);
r = b - iterapp('mtimes',afun,atype,afcnstr,x,varargin{:});
normr = norm(r);                 % Norm of initial residual
if (normr <= tolb)               % Initial guess is a good enough solution
    flag = 0;
    relres = normr / n2b;
    iter = [0 0];
    resvec = normr;
    if (nargout < 2)
        itermsg('gmres',tol,maxit,[0 0],flag,iter,relres);
    end
    return
end
minv_b = b;

if existM1

%    r = P*r;
    r = r-A*(ZH*(AH\(ZH'*r)));
    r = iterapp('mldivide',m1fun,m1type,m1fcnstr,r,varargin{:});
    if ~x0iszero

        b0 = b-A*(ZH*(AH\(ZH'*b)));
        minv_b = iterapp('mldivide',m1fun,m1type,m1fcnstr,b0,varargin{:});
    else
        minv_b = r;
    end
    if ~all(isfinite(r)) || ~all(isfinite(minv_b))
        flag = 2;
        x = xmin;
        relres = normr / n2b;
        iter = [0 0];
        resvec = normr;
        return
    end
end

if existM2
    r = iterapp('mldivide',m2fun,m2type,m2fcnstr,r,varargin{:});
    if ~x0iszero
        minv_b = iterapp('mldivide',m2fun,m2type,m2fcnstr,minv_b,varargin{:});
    else
        minv_b = r;
    end
    if ~all(isfinite(r)) || ~all(isfinite(minv_b))
        flag = 2;
        x = xmin;
        relres = normr / n2b;
        iter = [0 0];
        resvec = normr;
        return
    end
end

normr = norm(r);                 % norm of the preconditioned residual
n2minv_b = norm(minv_b);         % norm of the preconditioned rhs
clear minv_b;
tolb = tol * n2minv_b;
if (normr <= tolb)               % Initial guess is a good enough solution
    flag = 0;
    relres = normr / n2minv_b;
    iter = [0 0];
    resvec = n2minv_b;
    if (nargout < 2)
        itermsg('gmres',tol,maxit,[0 0],flag,iter,relres);
    end
    return
end

resvec = zeros(inner*outer+1,1);  % Preallocate vector for norm of residuals
resvec(1) = normr;                % resvec(1) = norm(b-A*x0)
normrmin = normr;                 % Norm of residual from xmin

%  Preallocate J to hold the Given's rotation constants.
J = sparse(2,inner);

U = sparse(n,inner);
R = sparse(inner,inner);
w = sparse(inner+1,1);

for outiter = 1 : outer
    %  Construct u for Householder reflector.
    %  u = r + sign(r(1))*||r||*e1
    u = r;
    normr = norm(r);
    beta = scalarsign(r(1))*normr;
    u(1) = u(1) + beta;
    u = u / norm(u);

    U(:,1) = u;

    %  Apply Householder projection to r.
    %  w = r - 2*u*u'*r;
    w(1) = -beta;

    for initer = 1 : inner
        %  Form P1*P2*P3...Pj*ej.
        %  v = Pj*ej = ej - 2*u*u'*ej
        v = -2*(u(initer)')*u;
        v(initer) = v(initer) + 1;
        %  v = P1*P2*...Pjm1*(Pj*ej)
        for k = (initer-1):-1:1
            v = v - U(:,k)*(2*(U(:,k)'*v));
        end
        %  Explicitly normalize v to reduce the effects of round-off.
        v = v/norm(v);

        %  Apply A to v.
        v = iterapp('mtimes',afun,atype,afcnstr,v,varargin{:});
        %  Apply Preconditioner.
        if existM1

            v = v-A*(ZH*(AH\(ZH'*v)));
            v = iterapp('mldivide',m1fun,m1type,m1fcnstr,v,varargin{:});
            %v = P*v;
            if ~all(isfinite(v))
                flag = 2;
                break
            end
        end

        if existM2
            v = iterapp('mldivide',m2fun,m2type,m2fcnstr,v,varargin{:});
            if ~all(isfinite(v))
                flag = 2;
                break
            end
        end
        %  Form Pj*Pj-1*...P1*Av.
        for k = 1:initer
            v = v - U(:,k)*(2*(U(:,k)'*v));
        end

        %  Determine Pj+1.
        if (initer ~= length(v))
            %  Construct u for Householder reflector Pj+1.
            u = [zeros(initer,1); v(initer+1:end)];
            alpha = norm(u);
            if (alpha ~= 0)
                alpha = scalarsign(v(initer+1))*alpha;
                %  u = v(initer+1:end) +
                %        sign(v(initer+1))*||v(initer+1:end)||*e_{initer+1)
                u(initer+1) = u(initer+1) + alpha;
                u = u / norm(u);
                U(:,initer+1) = u;

                %  Apply Pj+1 to v.
                %  v = v - 2*u*(u'*v);
                v(initer+2:end) = 0;
                v(initer+1) = -alpha;
            end
        end

        %  Apply Given's rotations to the newly formed v.
        for colJ = 1:initer-1
            tmpv = v(colJ);
            v(colJ)   = conj(J(1,colJ))*v(colJ) + conj(J(2,colJ))*v(colJ+1);
            v(colJ+1) = -J(2,colJ)*tmpv + J(1,colJ)*v(colJ+1);
        end

        %  Compute Given's rotation Jm.
        if ~(initer==length(v))
            rho = norm(v(initer:initer+1));
            J(:,initer) = v(initer:initer+1)./rho;
            w(initer+1) = -J(2,initer).*w(initer);
            w(initer) = conj(J(1,initer)).*w(initer);
            v(initer) = rho;
            v(initer+1) = 0;
        end

        R(:,initer) = v(1:inner);

        normr = abs(w(initer+1));
        resvec((outiter-1)*inner+initer+1) = normr;
        normr_act = normr;

        if (normr <= tolb || stag >= maxstagsteps || moresteps)
            if evalxm == 0
                ytmp = R(1:initer,1:initer) \ w(1:initer);
                additive = U(:,initer)*(-2*ytmp(initer)*conj(U(initer,initer)));
                additive(initer) = additive(initer) + ytmp(initer);
                for k = initer-1 : -1 : 1
                    additive(k) = additive(k) + ytmp(k);
                    additive = additive - U(:,k)*(2*(U(:,k)'*additive));
                end
                if norm(additive) < eps*norm(x)
                    stag = stag + 1;
                else
                    stag = 0;
                end
                xm = x + additive;
                evalxm = 1;
            elseif evalxm == 1
                addvc = [-(R(1:initer-1,1:initer-1)\R(1:initer-1,initer))*...
                    (w(initer)/R(initer,initer)); w(initer)/R(initer,initer)];
                if norm(addvc) < eps*norm(xm)
                    stag = stag + 1;
                else
                    stag = 0;
                end
                additive = U(:,initer)*(-2*addvc(initer)*conj(U(initer,initer)));
                additive(initer) = additive(initer) + addvc(initer);
                for k = initer-1 : -1 : 1
                    additive(k) = additive(k) + addvc(k);
                    additive = additive - U(:,k)*(2*(U(:,k)'*additive));
                end
                xm = xm + additive;
            end
            r = b - iterapp('mtimes',afun,atype,afcnstr,xm,varargin{:});
            if norm(r) <= tol*n2b
                x = xm;
                flag = 0;
                iter = [outiter, initer];
                break
            end
            minv_r = r;
            if existM1

                %minv_r = P*minv_r;
                minv_r = r-A*(ZH*(AH\(ZH'*r)));
                minv_r = iterapp('mldivide',m1fun,m1type,m1fcnstr,minv_r,varargin{:});
                if ~all(isfinite(minv_r))
                    flag = 2;
                    break
                end
            end
            if existM2
                minv_r = iterapp('mldivide',m2fun,m2type,m2fcnstr,minv_r,varargin{:});
                if ~all(isfinite(minv_r))
                    flag = 2;
                    break
                end
            end

            normr_act = norm(minv_r);
            resvec((outiter-1)*inner+initer+1) = normr_act;

            if normr_act <= normrmin
                normrmin = normr_act;
                imin = outiter;
                jmin = initer;
                xmin = xm;
                minupdated = 1;
            end

            if normr_act <= tolb
                x = xm;
                flag = 0;
                iter = [outiter, initer];
                break
            else
                if stag >= maxstagsteps && moresteps == 0
                    stag = 0;
                end
                moresteps = moresteps + 1;
                if moresteps >= maxmsteps
                    if ~warned
                        warning(message('MATLAB:gmres:tooSmallTolerance'));
                    end
                    flag = 3;
                    iter = [outiter, initer];
                    break;
                end
            end
        end

        if normr_act <= normrmin
            normrmin = normr_act;
            imin = outiter;
            jmin = initer;
            minupdated = 1;
        end

        if stag >= maxstagsteps
            flag = 3;
            break;
        end
    end         % ends inner loop

    evalxm = 0;

    if flag ~= 0
        if minupdated
            idx = jmin;
        else
            idx = initer;
        end
        y = R(1:idx,1:idx) \ w(1:idx);
        additive = U(:,idx)*(-2*y(idx)*conj(U(idx,idx)));
        additive(idx) = additive(idx) + y(idx);
        for k = idx-1 : -1 : 1
            additive(k) = additive(k) + y(k);
            additive = additive - U(:,k)*(2*(U(:,k)'*additive));
        end
        x = x + additive;
        xmin = x;
        r = b - iterapp('mtimes',afun,atype,afcnstr,x,varargin{:});
        minv_r = r;
        if existM1

            minv_r = r-A*(ZH*(AH\(ZH'*r)));
            minv_r = iterapp('mldivide',m1fun,m1type,m1fcnstr,minv_r,varargin{:});
            if ~all(isfinite(minv_r))
                flag = 2;
                break
            end
        end
        if existM2
            minv_r = iterapp('mldivide',m2fun,m2type,m2fcnstr,minv_r,varargin{:});
            if ~all(isfinite(minv_r))
                flag = 2;
                break
            end
        end
        normr_act = norm(minv_r);
        r = minv_r;
    end

    if normr_act <= normrmin
        xmin = x;
        normrmin = normr_act;
        imin = outiter;
        jmin = initer;
    end

    if flag == 3
        break;
    end
    if normr_act <= tolb
        flag = 0;
        iter = [outiter, initer];
        break;
    end
    minupdated = 0;
end         % ends outer loop

% returned solution is that with minimum residual
if flag == 0
    relres = normr_act / n2minv_b;
else
    x = xmin;
    iter = [imin jmin];
    relres = normr_act / n2minv_b;
end

% truncate the zeros from resvec
if flag <= 1 || flag == 3
    resvec = resvec(1:(outiter-1)*inner+initer+1);
    indices = resvec==0;
    resvec = resvec(~indices);
else
    if initer == 0
        resvec = resvec(1:(outiter-1)*inner+1);
    else
        resvec = resvec(1:(outiter-1)*inner+initer);
    end
end

% only display a message if the output flag is not used
% if nargout < 2
%     if restarted
%         itermsg(sprintf('gmres(%d)',restart),tol,maxit,[outiter initer],flag,iter,relres);
%     else
%         itermsg(sprintf('gmres'),tol,maxit,initer,flag,iter(2),relres);
%     end
% end

function sgn = scalarsign(d)
sgn = sign(d);
if (sgn == 0)
    sgn = 1;
end

function y = iterapp(op,afun,atype,afcnstr,x,varargin)
%ITERAPP   Apply matrix operator to vector and error gracefully.
%   ITERAPP(OP,AFUN,ATYPE,AFCNSTR,X) applies matrix operator AFUN to vector
%   X. If ATYPE is 'matrix, then AFUN is a matrix and the OP is applied
%   directly. OP is either 'mtimes' or 'mldivide'.
%   ATYPE and AFCNSTR are used in case of error.
%   ITERAPP(OP,AFUN,ATYPE,AFCNSTR,X,P1,P2,...) allows extra arguments to
%   AFUN(X,P1,P2,...) although this usage is now discouraged in favor of
%   using anonymous functions.
%   AFUN(X,P1,P2,...,PN,TFLAG) should accept a TFLAG as its final input if
%   the calling function is BICG, LSQR or QMR. TFLAG is either 'transp' or
%   'notransp' depending on whether A' OP X or A OP X is required.
%   ITERAPP is designed for use by iterative methods like PCG which
%   require matrix operators AFUN representing matrices A to operate on
%   vectors X and return A*X and may also have operators MFUN representing
%   preconditioning matrices M operate on vectors X and return M\X.
%
%   See also BICG, BICGSTAB, CGS, GMRES, LSQR, MINRES, PCG, QMR, SYMMLQ.

%   Copyright 1984-2011 The MathWorks, Inc.
%   $Revision: 1.7.4.8 $ $Date: 2011/05/17 02:33:16 $

if strcmp(atype,'matrix')
    switch lower(op)
        case 'mtimes'
            if (nargin >= 6) && isequal(varargin{end},'transp')
                y = afun' * x;
            else
                y = afun * x;
            end
        case 'mldivide'
            if (nargin >= 6) && isequal(varargin{end},'transp')
                y = afun' \ x;
            else
                y = afun \ x;
            end
        otherwise
            error(message('MATLAB:iterapp:InvalidOp'))
    end
else
    try
        if (nargin >= 6) && isequal(varargin{end},'notransp')
            % A request for A*x coming from BICG, LSQR and QMR
            try
                % New syntax: we now request afun(x,P1,P2,...,PN,'notransp')
                y = afun(x,varargin{:});
            catch
                % Old syntax: we used to accept afun(x,P1,P2,...,PN)
                y = afun(x,varargin{1:end-1});
            end
        else
            % A request for A*x
            % coming from BICGSTAB, CGS, GMRES, MINRES, PCG or SYMMLQ
            % with the call always afun(P1,P2,...,PN)
            % or a request for A'*x coming from
            % BICG, LSQR and QMR in the afun(x,P1,P2,...,PN,'transp') case
            y = afun(x,varargin{:});
        end
    catch ME
        error(message('MATLAB:iterapp:InvalidInput', atype,afcnstr, ME.message));
    end

    if ~iscolumn(y)
        error(message('MATLAB:iterapp:MustReturnColumn', atype, afcnstr));
    end
end

function [atype,afun,afcnstr] = iterchk(A)
%ITERCHK  Checks arguments to iterative methods.
%   [ATYPE,AFUN,AFCNSTR] = ITERCHK(A) returns the following:
%   ATYPE is either 'matrix', 'function', 'expression' or 'inline object'.
%   AFUN is the function name or inline object.
%   AFUN is '' if ATYPE is 'matrix'.
%   AFCNSTR is the function name if ATYPE is 'function'.
%   AFCNSTR is the formula of the function if ATYPE is 'expression' or
%   'inline object'.  AFCNSTR is '' if ATYPE is 'matrix'.
%
%   See also BICG, BICGSTAB, CGS, GMRES, LSQR, MINRES, PCG, QMR, SYMMLQ.

%   Copyright 1984-2004 The MathWorks, Inc.
%   $Revision: 1.8.4.3 $ $Date: 2010/08/23 23:12:57 $

[afun,afunmsg] = fcnchk(A);
if isempty(afunmsg)
   if isa(afun,'inline')
      if isa(A,'inline')
         atype = 'inline object';
      else
         atype = 'expression';
      end
      afcnstr = formula(afun);
   else % both function_handles @fun and function names 'fun'
      atype = 'function';
      if isa(A,'function_handle')
          afcnstr = func2str(A);
      else
          afcnstr = A;
      end
   end
elseif isa(A,'float')
   afun = A;
   atype = 'matrix';
   afcnstr = '';
else
   error(message('MATLAB:iterchk:InvalidInput'));
end


function [ PD ] = PD_Orthogonal( X,a,SNR )
%UNTITLED2 Summary of this function goes here
%   Detailed explanation goes here
[N,L] = size(X);
Rs = X*X'/L;
rou = SNR*abs(a'*Rs.'*a)^2;
Pfa = 1e-7;
ita = chi2inv(1-Pfa,2);
PD = 1-ncx2cdf(ita,2,rou);
end

github-repos/MATLAB/yuanhao-cui-Must-Reading-on-ISAC/Must-Reading-on-ISAC-34cd6615c52ebca121428a979e756c608b195040/Codes/Fan2018TSP/Codes for DFRC Waveform Design/Waveform Design With Given Radar Beampatterns/PD_Orthogonal.m


function y=rfft(x,n,d)
%RFFT     Calculate the DFT of real data Y=(X,N,D)
% Data is truncated/padded to length N if specified.
%   N even:	(N+2)/2 points are returned with
% 			the first and last being real
%   N odd:	(N+1)/2 points are returned with the
% 			first being real
% In all cases fix(1+N/2) points are returned
% D is the dimension along which to do the DFT

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

s=size(x);
if prod(s)==1
    y=x
else
    if nargin <3 || isempty(d)
        d=find(s>1,1);
        if nargin<2
            n=s(d);
        end
    end
    if isempty(n)
        n=s(d);
    end
    y=fft(x,n,d);
    y=reshape(y,prod(s(1:d-1)),n,prod(s(d+1:end)));
    s(d)=1+fix(n/2);
    y(:,s(d)+1:end,:)=[];
    y=reshape(y,s);
end


function hc = binHistIndep(mu)
% hc = binHistIndep(mu)
% 	Computes expected histogram under independence assumption
%   P(X)=PROD(P(x_i))
%
% Code from the paper: 'Generating spike-trains with specified
% correlations', Macke et al., submitted to Neural Computation
%
% www.kyb.mpg.de/bethgegroup/code/efficientsampling

% generate all possible binary patterns
n = size(mu,1);
c = 0:2^n-1;
pattern = zeros(n,size(c,2));

for i=n:-1:1
    idx = c>=2^(i-1);
    pattern(i,idx)=1;
    c(idx) = c(idx) - 2^(i-1);
end

pattern = flipud(pattern);

% transform to probabilities
mu = mu/2+.5;

% find relevant probabilities for independent model
pMat = (repmat(mu,1,size(pattern,2)).*pattern) + (repmat(1-mu,1,size(pattern,2)).* (~pattern));

% calculate histogram
hc = prod(pMat);


function ret = nonlinear(chrom,sizepop)

for i=1:sizepop
    x=fmincon(inline('-5*sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))'),chrom(i,:)',[],[],[],[],[0 0 0 0 0],[2.8274 2.8274 2.8274 2.8274 2.8274]);
    ret(i,:)=x';
end


function [cIX,gIX] = GrowClustersFromSeedsItr(thres_merge,thres_cap,thres_minsize,cIX,gIX,M_0)
%disp('find ROIs')

% Set params

% may be determined by hist of distances between all cells (in a sample)
% in correlation distance, i.e. 1 - corr.coeff
% thres_merge = 0.4;
% thres_cap = 0.5;

% thres_minsize = 10; % cell number in final clusters

%%
gIX = SqueezeGroupIX(gIX);
M = M_0(cIX,:);
C = FindCentroid_Direct(gIX,M); % import functional supervoxels ('foxel')
nFoxels = size(C,1);

%% Calculate correlation distance between all cluster-centroids
temp = pdist(C,'correlation');
Dist = squareform(temp);
for i = 1:nFoxels,
    Dist(i,i) = NaN;
end

%% ITERATION:
% initialize
ROI = [];
ROI(nFoxels).fxlist = []; % not capping
ROI(nFoxels).numcell = [];
ROIcount = 0;

% analogy ~ mask to store new ROI
BW = zeros(nFoxels,1);

%%

while true, % loop through all qualified seeds
    % look for next seed
    [~,ix] = min(Dist(:));
    [I,J] = ind2sub(size(Dist),ix);
    % and add seed position to mask
    BW(I) = 1;
    BW(J) = 1;

    if Dist(I,J)>(1-thres_merge),
        break;
    end

    while true % grow ROI: expand mask and examine next neighbors
        IX_in = find(BW);
        IX_out = find(BW==0);

        % find next closest foxel
        D = 1-corr(C(IX_in,:)',C(IX_out,:)'); % distance matrix between potential foxels to foxels already included in ROI
        if isempty(D),
            break;
        end
        D2 = min(D,[],1);
        [a,ix] = min(D2);
        ix_pretend = IX_out(ix);

        BW_pretend = BW;
        BW_pretend(ix_pretend) = 1;

        % find correlation between potential foxel and new core
        list = find(BW_pretend);
        IX = [];
        for i_gIX = 1:length(list),
            IX = [IX;find(gIX==list(i_gIX))];
        end
        M_core = M(IX,:);
        [~,newCore] = kmeans(M_core,1,'distance','correlation');
        coredist = 1-corr(C(ix_pretend,:)',newCore');

        if a<(1-thres_merge) && coredist<(1-thres_cap),
            BW(ix_pretend) = 1;
        else
            break; % finished expanding this seed
        end
    end

    % save this ROI if bigger than thres
    list = find(BW);
    IX = [];
    for i_gIX = 1:length(list),
        IX = [IX;find(gIX==list(i_gIX))]; %#ok<AGROW>
    end
    numcell = length(IX);
    if numcell >= thres_minsize,
        ROIcount = ROIcount+1;
        ROI(ROIcount).fxlist = find(BW);
        ROI(ROIcount).numcell = numcell;
    end

    % update/reset
    Dist(list,:) = NaN;
    Dist(:,list) = NaN;
    C(list,:) = NaN;
    BW = zeros(nFoxels,1);

    if isempty(find(isnan(Dist)==0)),
        break;
    end
end

ROI(ROIcount+1:end) = [];

%% Merge accordingly
for i = 1:ROIcount,
    fxlist = ROI(i).fxlist;
    for j = 2:length(fxlist),
        gIX(gIX==fxlist(j)) = fxlist(1);
    end
end
[gIX,numU] = SqueezeGroupIX(gIX);
%disp(numU);

end


function calpak_test636 ( )

%*****************************************************************************80
%
%% CALPAK_TEST636 tests YEAR_TO_SCALIGER_COMMON.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 April 2013
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CALPAK_TEST636\n' );
  fprintf ( 1, '  For a Common year,\n' );
  fprintf ( 1, '  YEAR_TO_SCALIGER_COMMON determines the Scaliger indices.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Year  Julian / Metonic / Indiction\n' );
  fprintf ( 1, '\n' );

  for y = -4713 : -4675

    y2 = y_astronomical_to_common ( y );
    sy = y_to_s_common ( y2 );
    [ c1, c2, c3, r1, r2, r3 ] = year_to_scaliger_common ( y2 );
    fprintf ( 1, '  %10s  %3d  %3d    %3d  %3d    %3d  %3d\n', ...
    sy, c1, r1, c2, r2, c3, r3 );

  end

  return
end


function varargout = fastind2sub(siz,ndx)
%"fastind2sub"
%   FAST ind2sub is a faster version of ind2sub, based off the ind2sub that
%   ships with matlab.  Only one line is changed, and the original doc for
%   ind2sub is included below.
%
%   JRA 2/26/04
%
%IND2SUB Multiple subscripts from linear index.
%
%   IND2SUB is used to determine the equivalent subscript values
%   corresponding to a given single index into an array.
%
%   [I,J] = IND2SUB(SIZ,IND) returns the arrays I and J containing the
%   equivalent row and column subscripts corresponding to the index
%   matrix IND for a matrix of size SIZ.
%   For matrices, [I,J] = IND2SUB(SIZE(A),FIND(A>5)) returns the same
%   values as [I,J] = FIND(A>5).
%
%   [I1,I2,I3,...,In] = IND2SUB(SIZ,IND) returns N subscript arrays
%   I1,I2,..,In containing the equivalent N-D array subscripts
%   equivalent to IND for an array of size SIZ.
%
%   See also SUB2IND, FIND.

%   Copyright 1984-2002 The MathWorks, Inc.
%   $Revision: 1.3 $  $Date: 2008/10/08 21:38:59 $
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

nout = max(nargout,1);
if length(siz)<=nout,
  siz = [siz ones(1,nout-length(siz))];
else
  siz = [siz(1:nout-1) prod(siz(nout:end))];
end
n = length(siz);
k = [1 cumprod(siz(1:end-1))];
ndx = ndx - 1;
for i = n:-1:1,
  varargout{i} = floor(ndx/k(i))+1;
  ndx = ndx - (varargout{i}-1)*k(i);

%  This is the old method: slow because it
%  recalculates the division after it has already been found above.
%  ndx = rem(ndx,k(i));
end


function [ t, rank ] = ksubset_colex_successor ( k, n, t, rank )

%*****************************************************************************80
%
%% KSUBSET_COLEX_SUCCESSOR computes the K subset colex successor.
%
%  Discussion:
%
%    In the original code, there is a last element with no successor.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer K, the number of elements each K subset must
%    have.  1 <= K <= N.
%
%    Input, integer N, the number of elements in the master set.
%    N must be positive.
%
%    Input/output, integer T(K), describes a K subset.  T(I) is the
%    I-th element.  The elements must be listed in DESCENDING order.
%    On input, T describes a K subset.
%    On output, T describes the next K subset in the ordering.
%    If the input T was the last in the ordering, then the output T
%    will be the first.
%
%    Input/output, integer RANK, the rank.
%    If RANK = -1 on input, then the routine understands that this is
%    the first call, and that the user wishes the routine to supply
%    the first element in the ordering, which has RANK = 0.
%    In general, the input value of RANK is increased by 1 for output,
%    unless the very last element of the ordering was input, in which
%    case the output value of RANK is 0.
%

%
%  Return the first element.
%
  if ( rank == -1 )
    for i = 1 : k
      t(i) = k + 1 - i;
    end
    rank = 0;
    return
  end
%
%  Check.
%
  ierror = ksubset_colex_check ( k, n, t );

  if ( ierror ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'KSUBSET_COLEX_SUCCESSOR - Fatal error!\n' );
    fprintf ( 1, '  The input array is illegal.\n' );
    fprintf ( 1, '  IERROR = %d\n', ierror );
    error ( 'KSUBSET_COLEX_SUCCESSOR - Fatal error!' );
  end

  for i = k - 1 : -1 : 1
    if ( t(k+1-i) + 1 < t(k-i) )
      t(k+1-i) = t(k+1-i) + 1;
      rank = rank + 1;
      return
    end
  end

  if ( t(1) < n )
    t(1) = t(1) + 1;
    for i = 1 : k - 1
      t(k+1-i) = i;
    end
    rank = rank + 1;
    return
  end
%
%  The last K subset was input.
%  Return the first one.
%
  for i = 1 : k
    t(i) = k + 1 - i;
  end

  rank = 0;

  return
end


function [dpsi, deps] = nut2000a (date1, date2)

% nutation based on iau 2000a theory

% input

%  date1, date2 = tt julian date
%  (julian date = date1 + date2)

% output

%  dpsi = nutation in longitude in radians

%  deps = nutation in obliquity in radians

% reference

%  Nutation Series Evaluation in NOVAS 3.0
%  USNO Circular No. 181, December 15, 2009

% ported from NOVAS 3.0 Fortran subroutine

% Orbital Mechanics with MATLAB

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

global jplephem_inutate nals napl icpl cls

if (jplephem_inutate == 1)

    % read data files

    nals = csvread('nals.csv');

    napl = csvread('napl.csv');

    icpl = csvread('icpl.csv');

    cls = csvread('cls.csv');

    % transpose matrices

    nals = nals';

    napl = napl';

    icpl = icpl';

    cls = cls';

    % reset flag

    jplephem_inutate = 0;

end

% arc seconds to radians

das2r = 4.848136811095359935899141d-6;

% arc seconds in a full circle

turnas = 1296000.0d0;

% 2 * pi

d2pi = 6.283185307179586476925287d0;

% units of 0.1 microarcsecond to radians

u2r = das2r / 1.0d7;

% reference epoch (j2000)

dj0 = 2451545.0d0;

% days per julian century

djc = 36525.0d0;

% -------------------------
% luni-solar nutation model
% -------------------------

%  ---------------
%  planetary terms
%  ---------------

% interval between fundamental epoch j2000.0 and given date (jc)

t = ((date1 - dj0) + date2) / djc;

% -------------------
% luni-solar nutation
% -------------------

% fundamental (delaunay) arguments from simon et al. (1994)

% mean anomaly of the moon (radians)

el = mod (485868.249036d0 + t * (1717915923.2178d0 ...
    + t * (31.8792d0 + t * (0.051635d0 ...
    + t * (-0.00024470d0)))), turnas) * das2r;

% mean anomaly of the sun (radians)

elp = mod (1287104.79305d0 + t * (129596581.0481d0 ...
    + t * (-0.5532d0 + t * (0.000136d0 ...
    + t * (-0.00001149d0)))), turnas) * das2r;

% mean argument of the latitude of the moon (radians)

f = mod (335779.526232d0 + t * (1739527262.8478d0 ...
    + t * (-12.7512d0 + t * (-0.001037d0 ...
    + t * (0.00000417d0)))), turnas) * das2r;

% mean elongation of the moon from the sun (radians)

d = mod (1072260.70369d0 + t * (1602961601.2090d0 ...
    + t * (-6.3706d0 + t * (0.006593d0 ...
    + t * (-0.00003169d0)))), turnas) * das2r;

% mean longitude of the ascending node of the moon (radians)

om = mod (450160.398036d0 + t * (-6962890.5431d0 ...
    + t * (7.4722d0 + t * (0.007702d0 ...
    + t * (-0.00005939d0)))), turnas) * das2r;

% summation of luni-solar nutation series (in reverse order)

arg = mod ((nals(1, :)) * el  + (nals(2, :)) * elp + (nals(3, :)) * f ...
    + (nals(4, :)) * d  + (nals(5, :)) * om, d2pi);

sarg = sin(arg);

carg = cos(arg);

dp = sum((cls(1,:) + cls(2,:) * t) .* sarg + cls(3,:) .* carg);

de = sum((cls(4,:) + cls(5,:) * t) .* carg + cls(6,:) .* sarg);

% convert from 0.1 microarcsec units to radians

dpsils = dp * u2r;

depsls = de * u2r;

% ------------------
% planetary nutation
% ------------------

% mean anomaly of the moon (radians)

al = mod (2.35555598d0 + 8328.6914269554d0 * t, d2pi);

% mean anomaly of the sun (radians)

alsu = mod (6.24006013d0 + 628.301955d0 * t, d2pi);

% mean argument of the latitude of the moon (radians)

af = mod (1.627905234d0 + 8433.466158131d0 * t, d2pi);

% mean elongation of the moon from the sun (radians)

ad = mod (5.198466741d0 + 7771.3771468121d0 * t, d2pi);

% mean longitude of the ascending node of the moon (radians)

aom = mod (2.18243920d0 - 33.757045d0 * t, d2pi);

% general accumulated precession in longitude (radians)

apa = (0.02438175d0 + 0.00000538691d0 * t) * t;

% planetary longitudes, mercury through neptune (souchay et al. 1999)

alme = mod (4.402608842d0 + 2608.7903141574d0 * t, d2pi);

alve = mod (3.176146697d0 + 1021.3285546211d0 * t, d2pi);

alea = mod (1.753470314d0 +  628.3075849991d0 * t, d2pi);

alma = mod (6.203480913d0 +  334.0612426700d0 * t, d2pi);

alju = mod (0.599546497d0 +   52.9690962641d0 * t, d2pi);

alsa = mod (0.874016757d0 +   21.3299104960d0 * t, d2pi);

alur = mod (5.481293871d0 +    7.4781598567d0 * t, d2pi);

alne = mod (5.321159000d0 +    3.8127774000d0 * t, d2pi);

% summation of planetary nutation series (in reverse order)

arg = mod ((napl(1, :)) * al + (napl(2, :)) * alsu + (napl(3, :)) * af ...
    + (napl(4, :)) * ad + (napl(5, :)) * aom  + (napl(6, :)) * alme ...
    + (napl(7, :)) * alve + (napl(8, :)) * alea + (napl(9, :)) * alma ...
    + (napl(10, :)) * alju + (napl(11, :)) * alsa + (napl(12, :)) * alur ...
    + (napl(13, :)) * alne + (napl(14, :)) * apa, d2pi);
sarg = sin(arg);

carg = cos(arg);

dp = sum((icpl(1,:)) .* sarg + (icpl(2,:)) .* carg);

de = sum((icpl(3,:)) .* sarg + (icpl(4,:)) .* carg);

% convert from 0.1 microarcsec units to radians

dpsipl = dp * u2r;

depspl = de * u2r;

% add planetary and luni-solar components

dpsi = dpsipl + dpsils;

deps = depspl + depsls;

end


function test_example_glm_nirs

% MEM 4gb
% WALLTIME 00:10:00

%% Using GLM to analyze NIRS timeseries data
%
% This is an example MATLAB script that demonstrates how to compute a simple GLM on the fingertapping NIRS data that is also used in the tutorial on [preprocessing and averaging of single-channel NIRS data](/tutorial/nirs_singlechannel). The data is available from our [FTP server](ftp://ftp.fieldtriptoolbox.org/pub/fieldtrip/tutorial/nirs_singlechannel/).
%
% We start with reading the NIRS data from disk.
%
cfg = [];
cfg.dataset = dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/nirs_singlechannel/motor_cortex.oxy3');
data_nirs = ft_preprocessing(cfg);

%% # Construct a number of additional channels with the task/stimulus details
%
% Then we read the events, which are represented as markers or triggers, indicating the samples in the data in which the fingertapping started or stopped. We use these to make some additional continuously represented channels that represent the onset, offset, and the motion. Furthermore, we can add two channels for a constant offset, and for a slope. These can be used to remove the baseline and a constant drift in the signal over time.
%
event = ft_read_event(cfg.dataset);

data_stim = [];
data_stim.time = data_nirs.time;
data_stim.label = {
  'onset'
  'offset'
  'motion'
  'constant'
  'slope'
  };
data_stim.chantype = repmat({'stimulus'}, size(data_stim.label));  % Homer stires the experimental design as stimulus (s)
data_stim.chanunit = repmat({'unknown'}, size(data_stim.label));

move_onset  = [event(strcmp({event.value}, 'A')).sample]; % this indicates the beginning of the movement
move_offset = [event(strcmp({event.value}, 'B')).sample]; % this indicates the end of the movement

nchans   = length(data_stim.label);
nsamples = length(data_stim.time{1}); % it is a continous representation, hence one trial/segment

data_stim.trial{1} = zeros(nchans, nsamples);
data_stim.trial{1}(1,move_onset)  = 1;
data_stim.trial{1}(2,move_offset) = 1;
for i=1:numel(move_onset)
  data_stim.trial{1}(3,move_onset(i):move_offset(i)) = 1;
end
data_stim.trial{1}(4,:) = ones(1,nsamples);
data_stim.trial{1}(5,:) = linspace(0,1,nsamples);

% show the experimental design as a matrix
figure
imagesc(data_stim.trial{1})

%
% You actually have to zoom in a lot to see all details, since there are more samples than horizontal pixels on your screen
%
%% # Combine the NIRS data and the description of the task/stimulus details
%
cfg = [];
data_combined = ft_appenddata(cfg, data_nirs, data_stim);

% also keep the optode structure, we need it further down for fieldtrip2homer and plotting
data_combined.opto = data_nirs.opto;

%% # Perform a GLM analysis
%
% This is explained on http://mri-q.com/general-linear-model.html with an excelent introduction, and
% on https://www.brainvoyager.com/bv/doc/UsersGuide/StatisticalAnalysis/TheGeneralLinearModel.html.
%
close all

% take the data from the FieldTrip data structures
y = cat(2, data_nirs.trial{:})';
x = cat(2, data_stim.trial{:})';

% After further processing and artifact removal you could also take them from the `data_combined` structure, which would ensure that they keep nicely aligned - also when you discard artifact segments. But here we simply include all samples.
%
% use the default canonical haemodynamic response function (HRF) from SPM
ft_hastoolbox('spm12', 1);
h = spm_hrf(1/data_nirs.fsample);

% plot the original regressor
figure
plot(x(:,3), 'b')
hold on
title('model')

% convolve the design with the HRF
xc = convn(x', h')';
xc = xc(1:nsamples,:); % remove the trailing part
% replace the first three columns of the design with the HRF convolved version
x(:,1:3) = xc(:,1:3);

% plot the HRF convolved regressor
plot(x(:,3), 'r-')

%
% Remove the baseline, see also **[ft_preproc_baselinecorrect](https://github.com/fieldtrip/fieldtrip/blob/release/preproc/ft_preproc_baselinecorrect.m)** and **[ft_preproc_detrend](https://github.com/fieldtrip/fieldtrip/blob/release/preproc/ft_preproc_detrend.m)**. This is beneficial here, since the experimental regressors are not orthogonal to the confound regressors.
%
y = ft_preproc_polyremoval(y', 2)';

% fit the general linear model (GLM)
% y = x * b + e
b     = x \ y;
model = x * b;
e     = y - model;

chan = find(strcmp(data_nirs.label, 'Rx4b-Tx5 [860nm]'));

figure
hold on
plot(y(:,chan), 'b')
plot(e(:,chan), 'g')
plot(model(:,chan), 'r', 'linewidth', 2)
%set(h, 'LineWidth', 1)
legend({'data', 'noise', 'model'});
title('fit to data')

%
%% # Convert the fitted model into statistical parameters
%
[n,p] = size(x);
r2 = var(model)./var(y);
f = r2*(n-p) ./ ((1-r2)*(p-1));
c = [0 0 1 0 0]';
t = (c' * b) ./ sqrt(var(e) * (c' * (x'*x) * c));

% It would be possible to make topographic maps of these t-values.
%
%% # Doing the same using the Homer data representation
%
% We can also do this analysis using the Homer data representation. For that we can convert the data from FieldTrip to Homer
%
nirs = fieldtrip2homer(data_combined);

% and then take the data matrix |y| and the experimental design matrix |x|
%
y = nirs.d;
x = nirs.s;

% Subsequently we could continue as above ...


function [nautmi] = ft2nautmi(ft)
% Convert length from feet to nautical miles.
% Chad Greene 2012
nautmi = ft*0.0001645788336933;


function varargout = drawVector3d(pos, vect, varargin)
%DRAWVECTOR3D Draw vector at a given position
%
%   drawVector3d(POS, VECT)
%   Draws the vector VECT starting at the position POS. Both VECT and POS
%   are N-by-3 arrays.
%
%   drawVector3d(..., PNAME, PVALUE)
%   Specifies additional optional parameters that will be given to the
%   quiver3 function.
%
%   Example
%     figure; hold on;
%     drawVector3d([2 3 4], [1 0 0]);
%     drawVector3d([2 3 4], [0 1 0]);
%     drawVector3d([2 3 4], [0 0 1]);
%     view(3);
%
%   See also
%   vectors3d, quiver3
%

% ------
% Author: David Legland
% e-mail: david.legland@nantes.inra.fr
% Created: 2011-12-19,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

h = quiver3(pos(:, 1), pos(:, 2), pos(:, 3), ...
    vect(:, 1), vect(:, 2), vect(:, 3), 0, varargin{:});

% format output
if nargout > 0
    varargout{1} = h;
end


function bvec_mul_test ( )

%*****************************************************************************80
%
%% BVEC_MUL_TEST tests BVEC_MUL;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 January 2015
%
%  Author:
%
%    John Burkardt
%
  n = 15;
  seed = 123456789;
  test_num = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'BVEC_MUL_TEST\n' );
  fprintf ( 1, '  BVEC_MUL multiplies binary vectors \n' );
  fprintf ( 1, '  representing integers;\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '        I        J        I * J   BVEC_MUL\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num

    [ i, seed ] = i4_uniform_ab ( -100, 100, seed );
    [ j, seed ] = i4_uniform_ab ( -100, 100, seed );

    k = i * j;

    bvec1 = i4_to_bvec ( i, n );
    bvec2 = i4_to_bvec ( j, n );
    bvec3 = bvec_mul ( n, bvec1, bvec2 );
    l = bvec_to_i4 ( n, bvec3 );

    fprintf ( 1, '  %8d  %8d  %8d  %8d\n', i, j, k, l );

  end

  return
end


function [s, m_v, zero_idx] = get_central_ula_size(diffs)
%GET_CENTRAL_ULA_SIZE Obtains the size of the ULA centered at the origin
%from the difference coarray.
%Syntax:
%   s = GET_CENTRAL_ULA_SIZE(diffs);
%   [s, m_v, zero_idx] = GET_CENTRAL_ULA_SIZE(diffs);
%Input:
%   diffs - A vector of integer differences, or array design.
%Outputs:
%   s - Entire array size = 2*M_v - 1.
%   m_v - The size of the ULA after trimming the negative part.
%   zero_idx - Index of the zero element in diffs.

if isstruct(diffs)
    % convert array design to unique differences
    diffs = unique_differences(diffs.element_indices);
end

w = 0;
zero_idx = find(diffs == 0);
n_diff = length(diffs);
while zero_idx + w < n_diff && zero_idx - w > 1
    w = w + 1;
    if (diffs(zero_idx+w) - diffs(zero_idx+w-1) ~= 1) || (diffs(zero_idx-w+1) - diffs(zero_idx-w)) ~= 1
        w = w - 1;
        break;
    end
end
m_v = w + 1;
s = 2*m_v - 1;

end


%% file example_rMTFL.m
% this file shows the usage of Least_rMTFL.m function
% and study how to detect outlier tasks.
%
%% OBJECTIVE
%  argmin_W ||X(P+Q) - Y||_F^2 + lambda1*||P||_{1,2} + lambda2*||Q^T||_{1,2}
%   s.t. W = P + Q
%
%% Copyright (C) 2012 Jiayu Zhou, and Jieping Ye
%
% You are suggested to first read the Manual.
% For any problem, please contact with Jiayu Zhou via jiayu.zhou@asu.edu
%
% Last modified on April 16, 2012.
%
%% Related papers
%
% [1] Gong, P. and Ye, J. and Zhang, C. Robust Multi-Task Feature Learning,
% Submitted, 2012
%

clear;
clc;
close all;

addpath('../MALSAR/functions/rMTFL/'); % load function
addpath('../MALSAR/utils/'); % load utilities

%rng('default');     % reset random generator. Available from Matlab 2011.

%generate synthetic data.
dimension = 500;
sample_size = 50;
task = 50;
X = cell(task ,1);
Y = cell(task ,1);
for i = 1: task
    X{i} = rand(sample_size, dimension);
    Y{i} = rand(sample_size, 1);
end

opts.init = 0;      % guess start point from data.
opts.tFlag = 1;     % terminate after relative objective value does not changes much.
opts.tol = 10^-6;   % tolerance.
opts.maxIter = 500; % maximum iteration number of optimization.

rho_1 = 90;%   rho1: P
rho_2 = 280; %   rho2: Q

[W funcVal P Q] = Least_rMTFL(X, Y, rho_1, rho_2, opts);

% draw figure
close;
figure();
subplot(3,1,1);
%imshow(1- (abs(S')~=0), 'InitialMagnification', 'fit');
imshow(P'==0, 'InitialMagnification', 'fit')
ylabel('P^T (feature)');
title('Visualization of Robust Multi-Task Feature Learning Model');
subplot(3,1,2);
%imshow(1- (zscore(L')), 'InitialMagnification', 'fit')
imshow(Q'==0, 'InitialMagnification', 'fit')
ylabel('Q^T (outliers)');
subplot(3,1,3);
%imshow(1- (zscore(W')), 'InitialMagnification', 'fit')
imshow(W'==0, 'InitialMagnification', 'fit')
ylabel('W^T');
xlabel('Dimension')
print('-dpdf', '-r600', 'LeastrMTFLExp');


function [assignment, cost] = assignmentoptimal(distMatrix)
%ASSIGNMENTOPTIMAL    Compute optimal assignment by Munkres algorithm
%		ASSIGNMENTOPTIMAL(DISTMATRIX) computes the optimal assignment for the
%		given rectangular distance (or weight) matrix, for example the assignment
%		of tracks (in rows) to observations (in columns). The result is a column
%		vector containing the assigned column number in each row (or 0 if no
%		assignment could be done).
%
%		[ASSIGNMENT, COST] = ASSIGNMENTOPTIMAL(DISTMATRIX) returns the assignment
%		vector and the overall cost.
%
%		The distance matrix may contain infinite values (forbidden
%		assignments). Internally, the infinite values are set to a very large
%		finite number, so that the Munkres algorithm itself works on finite-number
%		matrices. Before returning the assignment, all assignments with infinite
%		distance are deleted (i.e. set to zero).
%
%		A description of Munkres algorithm (also called Hungarian algorithm) can
%		easily be found on the web.
%
%		Written by Markus Buehren, www.Lss.uni-stuttgart.de
%		Last modified 14.12.2004

% save original distMatrix for cost computation
originalDistMatrix    = distMatrix;

% check for negative elements
if any(distMatrix(:) < 0)
	error('All matrix elements have to be non-negative.');
end

% get matrix dimensions
[nOfRows, nOfColumns] = size(distMatrix);

% check for infinite values
finiteIndex   = isfinite(distMatrix);
infiniteIndex = find(~finiteIndex);
if ~isempty(infiniteIndex)
	% set infinite values to large finite value
	maxFiniteValue = max(max(distMatrix(finiteIndex)));
	if maxFiniteValue > 0
		infValue = abs(10 * maxFiniteValue * nOfRows * nOfColumns);
	else
		infValue = 10;
	end
	if isempty(infValue)
		% all elements are infinite
		assignment = zeros(nOfRows, 1);
		cost       = 0;
		return
	end
	distMatrix(infiniteIndex) = infValue;
end

% memory allocation
coveredColumns = zeros(1,nOfColumns);
coveredRows    = zeros(nOfRows,1);
starMatrix     = zeros(nOfRows, nOfColumns);
primeMatrix    = zeros(nOfRows, nOfColumns);

% preliminary steps
if nOfRows <= nOfColumns
	minDim = nOfRows;

	% find the smallest element of each row
	minVector = min(distMatrix,[],2);

	% subtract the smallest element of each row from the row
	distMatrix = distMatrix - repmat(minVector, 1, nOfColumns);

	% Steps 1 and 2
	for row = 1:nOfRows
		for col = find(distMatrix(row,:)==0)
			if ~coveredColumns(col)%~any(starMatrix(:,col))
				starMatrix(row, col) = 1;
				coveredColumns(col)  = 1;
				break
			end
		end
	end

else % nOfRows > nOfColumns
	minDim = nOfColumns;

	% find the smallest element of each column
	minVector = min(distMatrix);

	% subtract the smallest element of each column from the column
	distMatrix = distMatrix - repmat(minVector, nOfRows, 1);

	% Steps 1 and 2
	for col = 1:nOfColumns
		for row = find(distMatrix(:,col)==0)'
			if ~coveredRows(row)
				starMatrix(row, col) = 1;
				coveredColumns(col)  = 1;
				coveredRows(row)     = 1;
				break
			end
		end
	end
	coveredRows(:) = 0; % was used auxiliary above

end

if sum(coveredColumns) == minDim
	% algorithm finished
	assignment = buildassignmentvector__(starMatrix);
else
	% move to step 3
	[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step3__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim);
end

% compute cost and remove invalid assignments
[assignment, cost] = computeassignmentcost__(assignment, originalDistMatrix, nOfRows);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function assignment = buildassignmentvector__(starMatrix)

[maxValue, assignment] = max(starMatrix, [], 2);
assignment(maxValue == 0) = 0;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [assignment, cost] = computeassignmentcost__(assignment, distMatrix, nOfRows)

rowIndex   = find(assignment);
costVector = distMatrix(rowIndex + nOfRows * (assignment(rowIndex)-1));
finiteIndex = isfinite(costVector);
cost = sum(costVector(finiteIndex));
assignment(rowIndex(~finiteIndex)) = 0;

% Step 2: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step2__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim)

% cover every column containing a starred zero
maxValue = max(starMatrix);
coveredColumns(maxValue == 1) = 1;

if sum(coveredColumns) == minDim
	% algorithm finished
	assignment = buildassignmentvector__(starMatrix);
else
	% move to step 3
	[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step3__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim);
end

% Step 3: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step3__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim)

zerosFound = 1;
while zerosFound

	zerosFound = 0;
	for col = find(~coveredColumns)
		for row = find(~coveredRows')
			if distMatrix(row,col) == 0

				primeMatrix(row, col) = 1;
				starCol = find(starMatrix(row,:));
				if isempty(starCol)
					% move to step 4
					[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step4__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, row, col, minDim);
					return
				else
					coveredRows(row)        = 1;
					coveredColumns(starCol) = 0;
					zerosFound              = 1;
					break % go on in next column
				end
			end
		end
	end
end

% move to step 5
[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step5__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim);

% Step 4: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step4__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, row, col, minDim)

newStarMatrix          = starMatrix;
newStarMatrix(row,col) = 1;

starCol = col;
starRow = find(starMatrix(:, starCol));

while ~isempty(starRow)

	% unstar the starred zero
	newStarMatrix(starRow, starCol) = 0;

	% find primed zero in row
	primeRow = starRow;
	primeCol = find(primeMatrix(primeRow, :));

	% star the primed zero
	newStarMatrix(primeRow, primeCol) = 1;

	% find starred zero in column
	starCol = primeCol;
	starRow = find(starMatrix(:, starCol));

end
starMatrix = newStarMatrix;

primeMatrix(:) = 0;
coveredRows(:) = 0;

% move to step 2
[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step2__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim);

% Step 5: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step5__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim)

% find smallest uncovered element
uncoveredRowsIndex    = find(~coveredRows');
uncoveredColumnsIndex = find(~coveredColumns);
[s, index1] = min(distMatrix(uncoveredRowsIndex,uncoveredColumnsIndex));
[s, index2] = min(s);
h = distMatrix(uncoveredRowsIndex(index1(index2)), uncoveredColumnsIndex(index2));

% add h to each covered row
index = find(coveredRows);
distMatrix(index, :) = distMatrix(index, :) + h;

% subtract h from each uncovered column
distMatrix(:, uncoveredColumnsIndex) = distMatrix(:, uncoveredColumnsIndex) - h;

% move to step 3
[assignment, distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows] = step3__(distMatrix, starMatrix, primeMatrix, coveredColumns, coveredRows, minDim);


function uvTformDataT = sr_src_domain_tform(uvPlaneID, modelPlane, uvTformAData, srcPos, trgPos)
% SR_SRC_DOMAIN_TFORM
%
% The function estimates the source patch domain transformation based on
% the source and target position, the plane parameters and apply the affine
% transformation
%
% Input:
%     - uvPlaneID:    [numUvPix] x [1], the plane label of uv pixels
%     - modelPlane:   plane model
%     - uvTformAData: [numUvPix] x 4, affine transformation
%     - srcPos:       [numUvPix] x [2], the center position of source patch
%     - trgPos:       [numUvPix] x [2], the center position of target patch
% Output:
%     - uvTformDataT: [numUvPix] X [9]
%
% The function of computing homography transformation induced by plane
% is modified from the following paper:
%
% Jia-Bin Huang, Sing Bing Kang, Narendra Ahuja, and Johannes Kopf,
% Image Completion using Planar Structure Guidance,
% ACM Transactions on Graphics (Proceedings of SIGGRAPH 2014), 33(4), 2014
% =========================================================================

% TO-DO: Make sure that the predicted transformation can point it
% the desired source patch position

% =========================================================================
% Compute homography transformation induced by plane
% =========================================================================

numUvPix = size(srcPos, 1);
uvTformDataH = 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 = sr_apply_tform_H(trgPosCur, h7, h8);

        % Source patch center position in the rectified domain
        srcPosCur = srcPos(uvPlaneIndCur, :) - 1;
        srcPosCurR = sr_apply_tform_H(srcPosCur, h7, h8);

        % Displacement vector from target to source position
        dRect = srcPosCurR - trgPosCurR;

        % Compute the transformation that maps from target to source
        % (See Eqn 8 in the paper [Huang et al. TOG 2014])
        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 [Huang et al. TOG 2014])
        uvTformDataH(uvPlaneIndCur, :)   = sr_trans_tform(uvTformCur, trgPosCur);
        uvTformDataH(uvPlaneIndCur, 7:8) = uvTformDataH(uvPlaneIndCur, 7:8) + 1;
    end
end

% =========================================================================
% Apply the similarity transformation
% =========================================================================
% The transformation T first map from original reference points to affine
% transformation coordinate using A, and then map to the desired target
% position using H
% -> T = H * A
uvTformDataT = uvTformDataH;
uvTformDataT(:,1:3) = bsxfun(@times, uvTformDataH(:,1:3), uvTformAData(:,1)) + ...
    bsxfun(@times, uvTformDataH(:,4:6), uvTformAData(:,2));
uvTformDataT(:,4:6) = bsxfun(@times, uvTformDataH(:,4:6), uvTformAData(:,3)) + ...
    bsxfun(@times, uvTformDataH(:,4:6), uvTformAData(:,4));

uvTformDataT = bsxfun(@rdivide, uvTformDataT, uvTformDataT(:,9));

end

function x = sr_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;
x = bsxfun(@rdivide, x(:,1:2), y + eps);

% numPix = size(x, 1);
% x = cat(2, x, ones(numPix, 1, 'single'));
% x = x*H';
% x = bsxfun(@rdivide, x(:,1:2), x(:,3) + eps);

end


% add the path of RBM code
addpath('..');

% load CBCL train
load 'faces.train.mat';
X = X_tra;

% shuffle the training data
perm_idx = randperm (size(X,1));
X = X(perm_idx, :);

% construct RBM and use default configurations
R = default_rbm (size(X, 2), 300);

% use continuous values
R.data.binary = 0;

% set grbm parameters
R.grbm.do_vsample = 1;
R.grbm.do_normalize = 0;
R.grbm.do_normalize_std = 1;
R.grbm.learn_sigmas = 1;

% max. 100 epochs
R.iteration.n_epochs = 100;

% set the stopping criterion
R.stop.criterion = 1;
R.stop.recon_error.tolerate_count = 1000;

% save the intermediate data after every epoch
R.hook.per_epoch = {@save_intermediate, {'grbm_faces.mat'}};

% print learining process
R.verbose = 1;

% display the progress
R.debug.do_display = 0;
R.debug.display_interval = 5;
R.debug.display_fid = 1;
R.debug.display_function = @visualize_grbm;

% train RBM
fprintf(1, 'Training GB-RBM\n');
tic;
R = train_rbm (R, X);
fprintf(1, 'Training is done after %f seconds\n', toc);

% grab some samples from RBM
S = grbm_sample(normrnd(zeros(10,size(X,2)), ones(10,size(X,2))), R, 30, 1000);

figure;
for i=1:10
    subplot(10, 1, i);
    visualize_adv(squeeze(S(i,:,:)), 0, 1, 30, 0, 0);
end


#computes the pose vector v from an homogeneous transform A
function v=t2v(A)
  v = [A(1:2,3); atan2(A(2,1),A(1,1))];
end


function [E,J]=SynthMeasWatsonSHCylSingleRadTortIsoV_GPD_B0(x, protocol, fibredir, roots)
% Substrate: Impermeable cylinders with one radius in a homogeneous background.
% Orientation distribution: Watson's distribution with SH approximation
% Signal approximation: Gaussian phase distribution.
% Notes: This version estimates the hindered diffusivity from the free diffusivity
% and packing density using Szafer et al's tortuosity model for randomly
% packed cylinders.
% This version includes an isotropic diffusion compartment with its own
% diffusivity.
% Includes a free parameter for the measurement at b=0.
%
% [E,J]=SynthMeasWatsonSHCylSingleRadTortIsoV_GPD_B0(x, protocol, fibredir, roots)
% returns the measurements E according to the model and the Jacobian J of the
% measurements with respect to the parameters.  The Jacobian does not
% include derivates with respect to the fibre direction.
%
% x is the list of model parameters in SI units:
% x(1) is the volume fraction of the intracellular space.
% x(2) is the free diffusivity of the material inside and outside the cylinders.
% x(3) is the radius of the cylinders.
% x(4) is the concentration parameter of the Watson's distribution.
% x(5) is the volume fraction of the isotropic compartment.
% x(6) is the diffusivity of the isotropic compartment.
% x(7) is the measurement at b=0.
%
% protocol is the object containing the acquisition protocol.
%
% fibredir is a unit vector along the symmetry axis of the Watson's
% distribution.  It must be in Cartesian coordinates [x y z]' with size [3 1].
%
% roots contains solutions to the Bessel function equation from function
% BesselJ_RootsCyl.
%
% author: Gary Hui Zhang (gary.zhang@ucl.ac.uk)
%

S0 = x(7);

% Call the other function to get normalized measurements.
if(nargout == 1)
    Enorm=SynthMeasWatsonSHCylSingleRadTortIsoV_GPD(x, protocol, fibredir, roots);
else
    [Enorm,Jnorm]=SynthMeasWatsonSHCylSingleRadTortIsoV_GPD(x, protocol, fibredir, roots);
end

E = Enorm*S0;

if(nargout>1)
    J = Jnorm*S0;
    [meas, params] = size(J);
    J(:,params+1) = Enorm;
end


function [irf_record]=irf(beta_gibbs,It,Bu,IRFperiods,n,m,p,k)

% function [irf_record]=irf(beta_gibbs,It,Bu,IRFperiods,n,m,p,k)
% runs the gibbs sampler to obtain draws from the posterior distribution of IRFs
% inputs:  - matrix 'beta_gibbs': record of the gibbs sampler draws for the beta vector
%          - integer 'It': total number of iterations of the Gibbs sampler (defined p 28 of technical guide)
%          - integer 'Bu': number of burn-in iterations of the Gibbs sampler (defined p 28 of technical guide)
%          - integer 'IRFperiods': number of periods for IRFs
%          - integer 'n': number of endogenous variables in the BVAR model (defined p 7 of technical guide)
%          - integer 'm': number of exogenous variables in the BVAR model (defined p 7 of technical guide)
%          - integer 'p': number of lags included in the model (defined p 7 of technical guide)
%          - integer 'k': number of coefficients to estimate for each equation in the BVAR model (defined p 7 of technical guide)
% outputs: -  cell 'irf_record': record of the gibbs sampler draws for the IRFs

% this function implements algorithm 2.2.1

% create the cell aray that will store the values from the simulations
irf_record=cell(n,n);

Bgibbs=reshape(beta_gibbs,k,n,It-Bu);

% deal with shocks in turn
for ii=1:n

   % step 1: repeat the simulation process a number of times equal to the number of Gibbs iterations
   for kk=1:It-Bu

   % step 3: draw beta from its posterior distribution
   B=squeeze(Bgibbs(:,:,kk));
   % create a matrix of zeros of dimension p*n
   Y=zeros(p,n);
   %  step 2: set the value of the last row, column i, equal to 1
   Y(p,ii)=1;

% if prior~=61
      % step 4: for each iteration kk, repeat the algorithm for periods T+1 to T+h
      for jj=1:IRFperiods-1
      % use the function lagx to obtain a matrix temp, containing the endogenous regressors
      temp=bear.lagx(Y,p-1);
      % define the vector X
      X=[temp(end,:) zeros(1,m)];
      % obtain the predicted value for T+jj
      yp=X*B;
      % concatenate yp at the top of Y
      Y=[Y;yp];
      % repeat until values are obtained for T+h
      end
% elseif prior==61 %for prior=61 mean adjusted model
% 	  % for each iteration kk, repeat the algorithm for periods T+1 to T+h
%       for jj=1:IRFperiods
%       % use the function lagx to obtain the matrix X
%       X=bear.lagx(Y,p-1);
%       X=X(end,:);
%       % obtain predicted value for T+jj
%       yp=X*B;
%       % concatenate yp at the top of Y
%       Y=[Y;yp];
%       % repeat until values are obtained for T+h
%       end
% end

   % step 5: record the results from current iteration in cell irf_record
      % loop over variables
      for jj=1:n
      % consider column jj of matrix 'Y' and trim the (p-1) initial periods: what remains is the series of IRFs for period T to period T+h-1, for variable jj
      temp=Y(p:end,jj);
      % record these values in the corresponding matrix of irf_record
      irf_record{jj,ii}(kk,:)=temp';
      end

   % then go for next iteration
   end

% conduct the same process with shocks in other variables
end


function f = fracInt(f, mu)
%FRACINT  Fractional integral of a CHEBFUN.
%   FRACINT(F, MU) gives the order MU fractional integral of a CHEBFUN object F.
%
%   Currently this only supports the situation where F is smooth (i.e., it has
%   no breakpoints or endpoint singularities) and on a finite domain.

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

% No piecewise support yet:
if ( numel(domain(f)) > 2 )
    error('CHEBFUN:CHEBFUN:fracInt:breakpoints', ...
        'FRACINT does not currently support piecewise functions.');
end

% Extract the fractional part of mu:
mu_int = floor(mu);
mu_frac = mu - mu_int;

% Computer the integer CUMSUMs:
if ( mu_int > 0 )
    % Ensure mu is in [0, 1):
    f = cumsum(f, mu_int);
    f = fracInt(f, mu_frac);
    return
elseif ( mu_frac == 0 )
    % Nothing more to do (non-fractional integral).
    return
end

% Quasimatrix / Array-valued support:
% TODO: This should be overhauled once SINGFUN supports array-valuedness.
m = numColumns(f);
if ( m > 1 )
    % Convert to cell-array of scalar CHEBFUNs.
    f = mat2cell(f);
    % Loop over columns:
    for k = 1:m
        f{k} = fracInt(f{k}, mu_frac);
    end
    % Convert from cell array to quasimatrix.
    f = cat(2-f{1}.isTransposed, f{:});
    return
end

% From here on f is scalar-valued:

% Call BNDFUN/FRACINT():
f.funs{1} = fracInt(f.funs{1}, mu_frac);

% Update the pointValues:
f.pointValues = chebfun.getValuesAtBreakpoints(f.funs);

end


% Semantic Soft Segmentation
% This function implements the soft segmentation approach described in
% Yagiz Aksoy, Tae-Hyun Oh, Sylvain Paris, Marc Pollefeys, Wojciech Matusik
% "Semantic Soft Segmentation", ACM TOG (Proc. SIGGRAPH) 2018

function [softSegments, initSoftSegments, Laplacian, affinities, features, superpixels, eigenvectors, eigenvalues] = SemanticSoftSegmentation(image, features)

    disp('Semantic Soft Segmentation')
    % Prepare the inputs and superpixels
    image = im2double(image);
    if size(features, 3) > 3 % If the features are raw, hyperdimensional, preprocess them
        features = preprocessFeatures(features, image);
    else
        features = im2double(features);
    end
    superpixels = Superpixels(image);
    [h, w, ~] = size(image);

    disp('     Computing affinities')
    % Compute the affinities and the Laplacian
    affinities{1} = mattingAffinity(image);
    affinities{2} = superpixels.neighborAffinities(features); % semantic affinity
    affinities{3} = superpixels.nearbyAffinities(image); % non-local color affinity
    Laplacian = affinityMatrixToLaplacian(affinities{1} + 0.01 * affinities{2} + 0.01 * affinities{3}); % Equation 6

    disp('     Computing eigenvectors')
    % Compute the eigendecomposition
    eigCnt = 100; % We use 100 eigenvectors in the optimization
    [eigenvectors, eigenvalues] = eigs(Laplacian, eigCnt, 'SM');

    disp('     Initial optimization')
    % Compute initial soft segments
    initialSegmCnt = 40;
    sparsityParam = 0.8;
    iterCnt = 40;
    % feeding features to the function below triggers semantic intialization
    initSoftSegments = softSegmentsFromEigs(eigenvectors, eigenvalues, Laplacian, ...
                                            h, w, features, initialSegmCnt, iterCnt, sparsityParam, [], []);

    % Group segments w.r.t. their mean semantic feature vectors
    groupedSegments = groupSegments(initSoftSegments, features);

    disp('     Final optimization')
    % Do the final sparsification
    softSegments = sparsifySegments(groupedSegments, Laplacian, imageGradient(image, false, 6));

    disp('     Done.')
end


%DEMO_SURVIVAL_COXPH  Survival model using Cox proportional model
%
%  Description
%    Survival model using Cox proportional model with a piecewise
%    log-constant baseline hazard. The hazard rate is
%
%       h(t) = h_0(t)*exp(f),
%
%    where the baseline hazard is assumed to piecewise log-constant.
%
%    The inference is conducted via Laplace, where we find
%    Gaussian approximation for p(f| th, data), where th is the
%    maximum a posterior (MAP) estimate for the parameters.
%
%    The censoring indicator ye is
%
%      ye = 0 for uncensored event
%      ye = 1 for right censored event.
%
%    If survival times y for n observation are given as nx2 matrix with
%    entry times into follow-up in the first column and exit times from
%    follow-up in the second column, left truncated right censored
%    modelling is possible, for instance, in cases where age is wanted to
%    be set as a baseline hazard.
%
%    Example data set is leukemia survival data in Northwest England
%    presented in (Henderson, R., Shimakura, S., and Gorst, D. (2002).
%    Modeling spatial variation in leukemia survival data. Journal of the
%    American Statistical Association, 97:965–972). Data set was downloaded
%    from http://www.math.ntnu.no/%7Ehrue/r-inla.org/examples/leukemia/leuk.dat
%
%  See also  DEMO_SURVIVAL_WEIBULL

% Copyright (c) 2011 Jaakko Riihimäki

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

% First load data
S = which('demo_survival_weibull');
L = strrep(S,'demo_survival_weibull.m','demodata/leukemia.txt');
leukemiadata=load(L);

% leukemiadata consists of:
% 'time', 'cens', 'xcoord', 'ycoord', 'age', 'sex', 'wbc', 'tpi', 'district'

% survival times
y=leukemiadata(:,1);
% scale survival times
y=y/max(y);

ye=1-leukemiadata(:,2); % event indicator, ye = 0 for uncensored event
                  %                        ye = 1 for right censored event

% choose (for example) 'age', 'sex', 'wbc', and 'tpi' covariates
x0=leukemiadata(:,5:8);
x=x0;
% normalize continuous covariates
x(:,[1 3:4])=bsxfun(@rdivide,bsxfun(@minus,x0(:,[1 3:4]),mean(x0(:,[1 3:4]),1)),std(x0(:,[1 3:4]),1));

[n, nin]=size(x);

% number of time intervals
ntime=50;
% create finite partition of time axis
S=linspace(0,max(y)+0.001,ntime+1);

% Create the covariance functions
pl = prior_t('s2',1, 'nu', 4);
pm = prior_t('s2',1, 'nu', 4);

% covariance for hazard function
gpcfh = gpcf_sexp('lengthScale', 1, 'magnSigma2', 1.1, 'lengthScale_prior', pl, 'magnSigma2_prior', pm);
% covariance for proportional part
gpcf = gpcf_sexp('lengthScale', ones(1,size(x,2)), 'magnSigma2', 1.2, 'lengthScale_prior', pl, 'magnSigma2_prior', pm);

% Create the likelihood structure
lik = lik_coxph('S', S);

% NOTE! if multiple covariance functions per latent is used, define
% gp.comp_cf as follows:
% gp = gp_set(..., 'comp_cf' {[1 2] [5 6]};
% where [1 2] are for hazard function, and [5 6] for proportional part
gp = gp_set('lik', lik, 'cf', {gpcfh gpcf}, 'jitterSigma2', 1e-6, 'comp_cf', {1 2});

% Set the approximate inference method to Laplace
gp = gp_set(gp, 'latent_method', 'Laplace');

opt=optimset('TolFun',1e-2,'TolX',1e-2,'Display','iter');
gp=gp_optim(gp,x,y,'z',ye,'opt',opt);

% Make prediction
xt1=zeros(200,nin); xt1(:,2)=1;
xt2=zeros(200,nin); xt2(:,2)=-1;

xt1(:,1)=linspace(min(x(:,1)), max(x(:,1)), 200);
xt2(:,1)=linspace(min(x(:,1)), max(x(:,1)), 200);
xt01(:,1)=linspace(min(x0(:,1)), max(x0(:,1)), 200);
xt02(:,1)=linspace(min(x0(:,1)), max(x0(:,1)), 200);

[Ef1, Covf1] = gp_pred(gp, x, y, xt1, 'z', ye);
[Ef2, Covf2] = gp_pred(gp, x, y, xt2, 'z', ye);
Varf1 = diag(Covf1);
Varf2 = diag(Covf2);

figure, hold on, set(gcf, 'color', 'w'),
plot(gp.lik.xtime, Ef1(1:ntime),'k', 'linewidth', 3)
plot(gp.lik.xtime, Ef1(1:ntime)+1.96*sqrt(Varf1(1:ntime)),'--k', 'linewidth', 2)
plot(gp.lik.xtime, Ef1(1:ntime)-1.96*sqrt(Varf1(1:ntime)),'--k', 'linewidth', 2)
title('log-baseline hazard (follow-up time)')
xlabel('time')

% Compute posterior mean and 95% credible intervals of latent function as a
% function of age and sex
col1=ones(1,3)*0.7;
col2=ones(1,3)*0.3;
figure, hold on, set(gcf, 'color', 'w'),
plot(xt01(:,1), Ef1(ntime+1:end), 'color', col1, 'linewidth', 3)
plot(xt01(:,1), Ef1(ntime+1:end)+1.96*sqrt(Varf1(ntime+1:end)), '--', 'color', col1, 'linewidth', 2)
plot(xt01(:,1), Ef1(ntime+1:end)-1.96*sqrt(Varf1(ntime+1:end)), '--', 'color', col1, 'linewidth', 2)

plot(xt02(:,1), Ef2(ntime+1:end), 'color', col2, 'linewidth', 3)
plot(xt02(:,1), Ef2(ntime+1:end)+1.96*sqrt(Varf2(ntime+1:end)), '--', 'color', col2, 'linewidth', 2)
plot(xt02(:,1), Ef2(ntime+1:end)-1.96*sqrt(Varf2(ntime+1:end)), '--', 'color', col2, 'linewidth', 2)
xlabel('age')
title('effect of age for both sexes')

%- Age as baseline hazard

% Age in the beginning and in the end of follow-up
y=[x0(:,1) x0(:,1)+leukemiadata(:,1)/365];
y2=y;
% normalise ages
y2=y2-min(y2(:)); y2=y2./max(y(:));

x2=x;
x2(:,1)=[];

% covariance for proportional part
gpcf = gpcf_sexp('lengthScale', ones(1,size(x2,2)), 'magnSigma2', .5, 'lengthScale_prior', pl, 'magnSigma2_prior', pm);

% NOTE! if multiple covariance functions per latent is used, define
% gp.comp_cf as follows:
% gp = gp_set(..., 'comp_cf', {[1 2] [5 6]});
% where [1 2] are for hazard function, and [5 6] for proportional part
gp = gp_set('lik', lik, 'cf', {gpcfh gpcf}, 'jitterSigma2', 1e-6, 'comp_cf', {[1] [2]});

% Set the approximate inference method to Laplace
gp = gp_set(gp, 'latent_method', 'Laplace');

opt=optimset('TolFun',1e-2,'TolX',1e-2,'Display','iter');
gp=gp_optim(gp,x2,y2,'z',ye,'opt',opt);

[Ef1, Covf1] = gp_pred(gp, x2, y2, x2, 'z', ye);
Varf1 = diag(Covf1);
xtmpl=linspace(min(y(:)),max(y(:)),50);

figure, hold on, set(gcf, 'color', 'w'),
plot(xtmpl, Ef1(1:ntime),'k', 'linewidth', 3)
plot(xtmpl, Ef1(1:ntime)+1.96*sqrt(Varf1(1:ntime)),'--k', 'linewidth', 2)
plot(xtmpl, Ef1(1:ntime)-1.96*sqrt(Varf1(1:ntime)),'--k', 'linewidth', 2)
title('log-baseline hazard (age)')
xlabel('age')