function illustrate_eq_algorithm(dim,N,varargin)
%ILLUSTRATE_EQ_ALGORITHM Illustrate the EQ partition algorithm
%
%Syntax
% illustrate_eq_algorithm(dim,N,options);
%
%Description
% ILLUSTRATE_EQ_ALGORITHM(dim,N) illustrates the recursive zonal equal area
% sphere partitioning algorithm, which partitions S^dim (the unit sphere in
% dim+1 dimensional space) into N regions of equal area and small diameter.
%
% The illustration consists of four subplots:
% 1. Steps 1 and 2
% 2. Steps 3 to 5
% 3. Steps 6 and 7
% 4. Lower dimensional partitions (if dim == 2 or dim == 3)
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'offset','extra') uses experimental extra
% offsets for S^2 and S^3. If dim > 3, extra offsets are not used.
% For more detail on partition options, see HELP PARTITION_OPTIONS.
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,options) also recognizes a number of
% illustration options, which are specified as name, value pairs.
% Any number of pairs can be used, in any order.
%
% The following illustration options are used.
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'fontsize',size)
% Font size used in titles (numeric, default 16).
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'title','long')
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'title','short')
% Use long or short titles (default 'short').
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'proj','stereo')
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'proj','eqarea')
% Use stereographic or equal area projection (default 'stereo').
%
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'points','show')
% ILLUSTRATE_EQ_ALGORITHM(dim,N,'points','hide')
% Show or hide center points (default 'show').
%
% See examples below.
% For more detail on illustration options, see HELP ILLUSTRATION_OPTIONS.
%
%Notes
% The step numbers refer to the following steps of the the recursive zonal
% equal area sphere partitioning algorithm, which partition the sphere into
% zones.
%
% 1. Determine the colatitudes of the North and South polar caps.
% 2. Determine an ideal collar angle.
% 3. Use the angle between the North and South polar caps and the ideal collar
%    angle to determine an ideal number of collars.
% 4. Use a rounding procedure to determine the actual number of collars,
%    given the ideal number of collars.
% 5. Create a list containing the ideal number of regions in each collar.
% 6. Use a rounding procedure to create a list containing the actual number of
%    regions in each collar, given the list containing the ideal number of
%    regions.
% 7. Create a list containing the colatitude of the top of each zone,
%    given the list containing the actual number of regions in each collar,
%    and the colatitudes of the polar caps.
%
%Examples
% > illustrate_eq_algorithm(3,99)
% > illustrate_eq_algorithm(3,99,'offset','extra','proj','eqarea')
% > illustrate_eq_algorithm(3,99,'proj','eqarea','points','hide')
%
%See also
% PARTITION_OPTIONS, ILLUSTRATION_OPTIONS, SUBPLOT

% Copyright 2004-2005 Paul Leopardi for the University of New South Wales.
% $Revision 1.10 $ $Date 2005-06-01 $
% Documentation files renamed
% $Revision 1.00 $ $Date 2005-02-13 $
%
% For licensing, see COPYING.
% For references, see AUTHORS.
% For revision history, see CHANGELOG.

pdefault.extra_offset =  false;

popt = partition_options(pdefault, varargin{:});

gdefault.fontsize = 16;
gdefault.show_title =    true;
gdefault.long_title =    false;
gdefault.stereo =        false;
gdefault.show_points =   true;

gopt = illustration_options(gdefault, varargin{:});
opt_args = option_arguments(popt,gopt);

subplot(2,2,1);axis off
illustrate_steps_1_2(dim,N,opt_args);

subplot(2,2,2);axis off
illustrate_steps_3_5(dim,N,opt_args);

subplot(2,2,3);axis off
illustrate_steps_6_7(dim,N,opt_args);

subplot(2,2,4);axis off
cla

gopt.fontsize = 32;
switch dim
case 2
    opt_args = option_arguments(popt,gopt);
    project_s2_partition(N,opt_args{:});
case 3
    opt_args = option_arguments(popt,gopt);
    [s,m] = eq_caps(dim,N);
    max_collar = min(4,size(m,2)-2);
    for k = 1:max_collar
        subn = 9+2*k-mod(k-1,2);
        subplot(4,4,subn);axis off
        project_s2_partition(m(1+k),opt_args{:});
    end
end
%
% end function

function illustrate_steps_1_2(dim,N,varargin)
% Illustrate steps 1 and 2 of the EQ partition of S^dim into N regions;
%
% illustrate_steps_1_2(dim,N,options);

gdefault.fontsize = 14;
gdefault.show_title =    true;
gdefault.long_title =    false;

gopt = illustration_options(gdefault, varargin{:});
h = [0:1/90:1];
% Plot a circle to represent dth coordinate of S^d
Phi = h*2*pi;
plot(sin(Phi),cos(Phi),'k','LineWidth',1)
axis equal;axis off;hold on

c_polar = polar_colat(dim,N);

k = [-1:1/20:1];
j = ones(size(k));

% Plot the bounding parallels of the polar caps
plot(sin(c_polar)*k, cos(c_polar)*j,'r','LineWidth',2)
plot(sin(c_polar)*k,-cos(c_polar)*j,'r','LineWidth',2)

% Plot the North-South axis
plot(zeros(size(j)),k,'b','LineWidth',1)
% Plot the polar angle
plot(sin(c_polar)*h,cos(c_polar)*h,'b','LineWidth',2)

text(0.05,2/3,'\theta_c','Fontsize',gopt.fontsize);

% Plot the ideal collar angle
Delta_I = ideal_collar_angle(dim,N);
theta = c_polar + Delta_I;
plot(sin(theta)*h,cos(theta)*h,'b','LineWidth',2)

mid = c_polar + Delta_I/2;
text(sin(mid)*2/3,cos(mid)*2/3,'\Delta_I','Fontsize',gopt.fontsize);

% Plot an arc to indicate angles
theta = h*(c_polar + Delta_I);
plot(sin(theta)/5,cos(theta)/5,'b','LineWidth',1)

text(-0.9,-0.1,sprintf('V(\\theta_c) = V_R \n    = \\sigma(S^{%d})/%d',dim,N),...
    'Fontsize',gopt.fontsize);

caption_angle = min(mid + 2*Delta_I,pi-c_polar);
text(sin(caption_angle)/3,cos(caption_angle)/3,sprintf('\\Delta_I = V_R^{1/%d}',dim),...
    'Fontsize',gopt.fontsize);

if gopt.show_title
    title_str = sprintf('EQ(%d,%d) Steps 1 to 2\n',dim,N);
    title(title_str,'Fontsize',gopt.fontsize);
end

hold off
%
% end function

function illustrate_steps_3_5(dim,N,varargin)
% Illustrate steps 3 to 5 of the EQ partition of S^dim into N regions;
%
% illustrate_steps_3_5(dim,N,options);

gdefault.fontsize = 14;
gdefault.show_title =    true;
gdefault.long_title =    false;

gopt = illustration_options(gdefault, varargin{:});

h = [0:1/90:1];
Phi = h*2*pi;
plot(sin(Phi),cos(Phi),'k','LineWidth',1)
axis equal;axis off;hold on

c_polar = polar_colat(dim,N);
n_collars = num_collars(N,c_polar,ideal_collar_angle(dim,N));
r_regions = ideal_region_list(dim,N,c_polar,n_collars);
s_cap = cap_colats(dim,N,c_polar,r_regions);

k = [-1:1/20:1];
j = ones(size(k));
plot(sin(c_polar)*k, cos(c_polar)*j,'r','LineWidth',2);

plot(zeros(size(j)),k,'b','LineWidth',1)

for collar_n = 0:n_collars
    zone_n = 1+collar_n;
    theta = s_cap(zone_n);
    plot(sin(theta)*h,cos(theta)*h,'b','LineWidth',2);
    theta_str = sprintf('\\theta_{F,%d}',zone_n);
    text(sin(theta)*1.1,cos(theta)*1.1,theta_str,'Fontsize',gopt.fontsize);
    if collar_n ~= 0
        plot(sin(theta)*k, cos(theta)*j,'r','LineWidth',2);
        theta_p = s_cap(collar_n);
        arc = theta_p + (theta-theta_p)*h;
        plot(sin(arc)/5,cos(arc)/5,'b','LineWidth',1);
        mid = (theta_p + theta)/2;
        text(sin(mid)/2,cos(mid)/2,'\Delta_F','Fontsize',gopt.fontsize);
        y_str = sprintf('y_{%d} = %3.1f...',collar_n,r_regions(zone_n));
        text(-sin(mid)+1/20,cos(mid)+(mid-pi)/30,y_str,'Fontsize',gopt.fontsize);
    end
end
if gopt.show_title
    title_str = sprintf('EQ(%d,%d) Steps 3 to 5\n',dim,N);
    title(title_str,'Fontsize',gopt.fontsize);
end
hold off
%
% end function

function illustrate_steps_6_7(dim,N,varargin)
% Illustrate steps 6 to 7 of the EQ partition of S^dim into N regions;
%
% illustrate_steps_6_7(dim,N,options);

gdefault.fontsize = 14;
gdefault.show_title =    true;
gdefault.long_title =    false;

gopt = illustration_options(gdefault, varargin{:});

h = [0:1/90:1];
Phi = h*2*pi;
plot(sin(Phi),cos(Phi),'k','LineWidth',1)
axis equal;axis off;hold on

c_polar = polar_colat(dim,N);
n_collars = num_collars(N,c_polar,ideal_collar_angle(dim,N));
r_regions = ideal_region_list(dim,N,c_polar,n_collars);
n_regions = round_to_naturals(N,r_regions);
s_cap = cap_colats(dim,N,c_polar,n_regions);

k = [-1:1/20:1];
j = ones(size(k));
plot(sin(c_polar)*k, cos(c_polar)*j,'r','LineWidth',2);

plot(zeros(size(j)),k,'b','LineWidth',1)

for collar_n = 0:n_collars
    zone_n = 1+collar_n;
    theta = s_cap(zone_n);
    plot(sin(theta)*h,cos(theta)*h,'b','LineWidth',2);
    theta_str = sprintf('\\theta_{%d}',zone_n);
    text(sin(theta)*1.1,cos(theta)*1.1,theta_str,'Fontsize',gopt.fontsize);
    if collar_n ~= 0
        plot(sin(theta)*k, cos(theta)*j,'r','LineWidth',2);
        theta_p = s_cap(collar_n);
        arc = theta_p + (theta-theta_p)*h;
        plot(sin(arc)/5,cos(arc)/5,'b','LineWidth',1);
        mid = (theta_p + theta)/2;
        Delta_str = sprintf('\\Delta_{%i}',collar_n);
        text(sin(mid)/2,cos(mid)/2,Delta_str,'Fontsize',gopt.fontsize);
        m_str = sprintf('m_{%d} =%3.0f',collar_n,n_regions(zone_n));
        text(-sin(mid)+1/20,cos(mid)+(mid-pi)/30,m_str,'Fontsize',gopt.fontsize);
    end
end
if gopt.show_title
    title_str = sprintf('EQ(%d,%d) Steps 6 to 7\n',dim,N);
    title(title_str,'Fontsize',gopt.fontsize);
end
hold off
%
% end function

function arg = option_arguments(popt,gopt)

k = 1;
if isfield(popt,'extra_offset')
    arg{k} = 'offset';
    if popt.extra_offset
        arg{k+1} = 'extra';
    else
        arg{k+1} = 'normal';
    end
    k = k+2;
end

if isfield(gopt,'fontsize')
    arg{k} = 'fontsize';
    arg{k+1} = gopt.fontsize;
    k = k+2;
end

if isfield(gopt,'stereo')
    arg{k} = 'proj';
    if gopt.stereo
        arg{k+1} = 'stereo';
    else
        arg{k+1} = 'eqarea';
    end
    k = k+2;
end

if isfield(gopt,'show_title')
    arg{k} = 'title';
    if gopt.show_title
        if isfield(gopt,'long_title')
            if gopt.long_title
                arg{k+1} = 'long';
            else
                arg{k+1} = 'short';
            end
        else
            arg{k+1} = 'show';
        end
    else
        arg{k+1} = 'none';
    end
    k = k+2;
elseif isfield(gopt,'long_title')
    arg{k} = 'title';
    if gopt.long_title
        arg{k+1} = 'long';
    else
        arg{k+1} = 'short';
    end
    k = k+2;
end

if isfield(gopt,'show_points')
    arg{k} = 'points';
    if gopt.show_points
        arg{k+1} = 'show';
    else
        arg{k+1} = 'hide';
    end
    k = k+2;
end

if isfield(gopt,'show_surfaces')
    arg{k} = 'surf';
    if gopt.show_surfaces
        arg{k+1} = 'show';
    else
        arg{k+1} = 'hide';
    end
    k = k+2;
end


%% Kernel Average Misorientation (KAM)
%
%%
% The kernel average misorientation (KAM) is a measure of local grain
% misorientation that is usually derived from EBSD data. For formaly
% defining the KAM we denote by $o_{i,j}$ the orientations at pixel
% position $(i,j)$ and by $N(i,j)$ the set of all neighboring pixels. Then
% the kernel average misorientation $\mathrm{kam}_{i,j}$ at pixel position
% $(i,j)$ is defined as
%
% $$\mathrm{KAM}_{i,j} = \frac{1}{|N(i,j)|}\sum_{(k,l) \in N(i,j)} \omega(o_{i,j}, o_{k,l}) $$
%
% Here $\lvert N(i,j) \rvert$ denotes the number of all neighboring pixels
% taking into account and $\omega(o_{i,j}, o_{k,l})$ the disorientation
% angle between the orientation $o_{ij}$ in the center and the neighbouring
% orientation $(o_{k,l})$. The specific choice of the set $N(i,j)$ of
% neighboring pixels is crucial for the compution of the KAM. Most commonly
% the following additional constrains are made
%
% * consider neighbors up to order $n$, e.g. $n=1,2,3,\ldots$
% * consider only neighbors belonging to the same grain
% * consider only neighbors with a misorientation angle smaller than a
% threshold angle $\delta$
%
% In the case of sqaure and hexagonal grids the order of neighbors is
% illustrated below

plotSquareNeighbours; nextAxis; plotHexNeighbours

%% A Deformed Ferrite Specimen
%
% Let us demonstrate the computation of the KAM at the example of a
% deformed Ferrite specimen. Lets import the data first and reconstruct the
% grain structure

mtexdata ferrite

[grains,ebsd.grainId] = calcGrains(ebsd('indexed'));
% remove one-three pixel grains
ebsd(grains(grains.grainSize <= 3)) = [];
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'));

grains = smooth(grains,5);

plot(ebsd('indexed'),ebsd('indexed').orientations)
hold on
plot(grains.boundary,'lineWidth',1.5)
hold off

%%
% Although MTEX allows the computation of the KAM from arbitrarily sampled
% EBSD maps the algorithms are much faster an memory efficient if the maps
% are measured on regular hexagonal or rectangular grid - as it is standard
% in most applications. The command <EBSD.gridify.html |gridify|> makes
% MTEX aware of such an underlying regular measurement grid.

ebsd = ebsd.gridify;

%%
%
% The kernel average misorientation is computed by the command
% <EBSD.KAM.html |ebsd.KAM|>. As all MTEX commands it return the mean
% disorientation angle in radiant. Hence, dividing by the constant |degree|
% gives the result in degree.

kam = ebsd.KAM / degree;

% lets plot it
plot(ebsd,kam,'micronbar','off')
caxis([0,15])
mtexColorbar
mtexColorMap LaboTeX
hold on
plot(grains.boundary,'lineWidth',1.5)
hold off

%%
% When computed with default parameters in MTEX neighbors up to order 1 are
% considered and no threshold angle $\delta$ is applied. If grains have
% been reconstructed and the property |ebsd.grainId| has been set (as we
% did above) only misorientations within the same grain are considered. As
% a consequence the resulting KAM map is dominated by the orientation
% gradients at the subgrain boundaries.
%
% Specifying a reasonable small theshold angle $\delta=2.5^{\circ}$ the
% subgrain boundaries can be effectively removed from the KAM.

plot(ebsd,ebsd.KAM('threshold',2.5*degree) ./ degree,'micronbar','off')
caxis([0,2])
mtexColorbar
mtexColorMap LaboTeX
hold on
plot(grains.boundary,'lineWidth',1.5)
hold off

%%
% Unfortunately, the remaining KAM becomes very sensitve to measurement
% errors and is often very noisy. The noise can be  reduced by considering
% heigher order neighbors

plot(ebsd,ebsd.KAM('threshold',2.5*degree,'order',5) ./ degree,'micronbar','off')
caxis([0,2])
mtexColorbar
mtexColorMap LaboTeX
hold on
plot(grains.boundary,'lineWidth',1.5)
hold off

%%
% Although this reduced noise it also smoothes away local dislocation
% structures. A much more effective way to reduce the effect of measurement
% errors to the kernel average misorientation is to denoise the EBSD map
% first and compute than the KAM from the first order neighbors.

% chose a denoising filter
F = halfQuadraticFilter;
F.alpha = 0.5;

% denoise the orientation map
ebsdS = smooth(ebsd,F,'fill',grains);

% plot the first order KAM
plot(ebsdS,ebsdS.KAM('threshold',2.5*degree) ./ degree,'micronbar','off')
caxis([0,2])
mtexColorbar
mtexColorMap LaboTeX
hold on
plot(grains.boundary,'lineWidth',1.5)
hold off

%%
% We observe that the KAM is not longer related to subgrain boundaries and
% nicely revalves local dislocation structures of the deformed material.
%
%% Some helper functions
%
% The functions below where only used to generate the neighborhood pictures
% of the first paragraph

function plotSquareNeighbours

N = [4 3 2 3 4;...
  3 2 1 2 3;...
  2 1 0 1 2;...
  3 2 1 2 3;...
  4 3 2 3 4];

cs = crystalSymmetry;
ebsd = EBSDsquare(rotation.nan(5,5),N,0:4,{cs,cs,cs,cs,cs},[10 10]);
plot(ebsd,'EdgeColor','black','micronbar','off','figSize','small')
legend off

text(ebsd,N)

end

function plotHexNeighbours

N = [3 2 2 2 3;...
  2 1 1 2 3;...
  2 1 0 1 2;...
  2 1 1 2 3;...
  3 2 2 2 3;...
  3 3 3 3 4];

cs = crystalSymmetry;
ebsd = EBSDhex(rotation.nan(6,5),N,0:4,{cs,cs,cs,cs,cs},10,1,1);
plot(ebsd,'edgecolor','k','micronbar','off','figSize','small')
legend off
text(ebsd,N)
axis off

end


function euler_number2_test ( )

%*****************************************************************************80
%
%% POLPAK_TEST0265 tests EULER_NUMBER2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 October 2008
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'EULER_NUMBER2_TEST\n' );
  fprintf ( 1, '  EULER_NUMBER2 computes Euler numbers.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  N  exact   EULER_NUMBER2\n' );
  fprintf ( 1, '\n' );

  n_data = 0;

  while ( 1 )

    [ n_data, n, c1 ] = euler_number_values ( n_data );

    if ( n_data == 0 )
      break
    end

    c2 = euler_number2 ( n );

    fprintf ( 1, '  %2d  %10d  %12f\n', n, c1, c2 );

  end

  return
end


clear, clc;

% This is an example for running the function mcLeastC
%
%  Problem:
%
%  min  1/2 || A x - y||^2
%  s.t. sum_j ||x^j||_q <=z
%
%  The current program only implements q=2
%
%  x is grouped into k groups according to opts.ind
%  The indices of x_j in x is (ind(j)+1):ind(j+1)
%
% For detailed description of the function, please refer to the Manual.
%
%% ------------   History --------------------
% First version on August 10, 2009.
%
% September 5, 2009: adaptive line search is added
%
% For any problem, please contact Jun Liu (j.liu@asu.edu)

cd ..
cd ..

root=cd;
addpath(genpath([root '/SLEP']));
                     % add the functions in the folder SLEP to the path

% change to the original folder
cd Examples/L1Lq;

m=100;  n=100;       % The data matrix is of size m x n
k=10;                % the number of classes (tasks)
q=2;                 % the value of q in the L1/Lq regularization
z=50;             % the regularization parameter
randNum=1;           % a random number

% ---------------------- generate random data ----------------------
randn('state',(randNum-1)*3+1);
A=randn(m,n);        % the data matrix

randn('state',(randNum-1)*3+2);
xOrin=randn(n,k);

randn('state',(randNum-1)*3+3);
noise=randn(m,k);
y=A*xOrin +...
    noise*0.01;      % the response

%----------------------- Set optional items -----------------------
opts=[];

% Starting point
opts.init=2;        % starting from a zero point

% Termination
opts.tFlag=5;       % run .maxIter iterations
opts.maxIter=100;   % maximum number of iterations

% Normalization
opts.nFlag=0;       % without normalization

% Group Property
opts.q=q;           % set the value for q

%----------------------- Run the code mcLeastC -----------------------
fprintf('\n lFlag=0 \n');
opts.mFlag=0;       % treating it as compositive function
opts.lFlag=0;       % Nemirovski's line search
tic;
[x1, funVal1, ValueL1]= mcLeastC(A, y, z, opts);
toc;

opts.maxIter=200;

fprintf('\n lFlag=1 \n');
opts.mFlag=1;       % smooth reformulation
opts.lFlag=1;       % adaptive line search
opts.tFlag=2; opts.tol= funVal1(end);
tic;
[x2, funVal2, ValueL2]= mcLeastC(A, y, z, opts);
toc;

figure;
plot(funVal1,'-r');
hold on;
plot(funVal2,'--b');
legend('lFlag=0', 'lFlag=1');
xlabel('Iteration (i)');
ylabel('The objective function value');

% % --------------------- compute the pathwise solutions ----------------
% opts.fName='mcLeastC';    % set the function name to 'mcLeastC'
% Z=[0.9, 0.8, 0.5, 0.3];   % set the parameters
%
% % run the function pathSolutionLeast
% fprintf('\n Compute the pathwise solutions, please wait...');
% X=pathSolutionLeast(A, y, Z, opts);


function [idx, theta, rho] = PolarCoordinatesGrid(y, r, nDivs)
%   PolarCoordinatesGrid - Calculate index of grid cell and
%   polar coordinates for a given objective vector
%
%   [idx, theta, rho] = PolarCoordinatesGrid(y, r, nDivs)
%
%   Input:
%   y - individual's objectives
%   r - reference point
%   nDivs - number of divisions in each right angle
%
%   Output:
%   idx - index of grid cell where individual resides
%   theta - polar angles
%   rho - radius

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

% This function is written by Roman Denysiuk

%% calculate polar coordinates

% determine dimensionality
m = numel(r);

% calculate radius
rho = norm(y-r);

% calculate angles
theta = zeros(m-1,1);

for i = 0:m-2

    u = (y(m-i) - r(m-i))/rho;

    for j = 0:i-1
        u = u/cos(theta(j+1));
    end

    u = min( max(u, -1), 1); % ensure feasibility

    theta(i+1) = asin(u);

    theta(i+1) = min( max(theta(i+1), eps), pi/2-eps);
end

%% calculate grid index based on polar coordinates

% calculate grid coordinates (integer values)
G = ceil(2*nDivs*theta/pi);

% calculate index of pop member using grid coordinates
% formula: idx=G(1)*ndiv^0+(G(2)-1)*ndiv^1+(G(3)-1)*ndiv^2 ...

idx = G(1);
for i = 2:numel(G)
    idx = idx + (G(i)-1)*power(nDivs, i-1);
end

end


function [COEF] = rmder_inv(P, Vec, Mat)

% rmder_inv returns a vector containing the relative standard deviation of the regression coefficients. The
%                            constant of the regression is not included
%
%
%      Input:
%             P             Property vector
%             Vec           Descriptors vector
%             Mat           Descriptors matrix
%
%
%     Returns:
%
%            COEF           Vector containing the standard deviation for
%                            the regression coefficients without the constant
%
%
%
%
% Andrew G. Mercader, Pablo R. Duchowicz
% INIFTA, La Plata, Argentina
% Created: 30 Jan 2007

if (nargin < 3)
   error('rmder requires at least 3 input variables. Type ''help rmder''.');
end

% Exctracts from descriptor matrix the matrix corresponding to the given
% set of descriptors
% ----------------------------------------------------------------------------
    X = Mat(:,Vec);
% Check that independent (X) and dependent (P) data have compatible dimensions
% ----------------------------------------------------------------------------
     [n_x, k] = size(X);
[n_y,columns] = size(P);

if n_x ~= n_y,
    error('The number of rows in P must equal the number of rows in Mat.');
end

if columns ~= 1,
    error('P must be a vector, not a matrix');
end

n = n_x;

%  Solve for the regression coefficients using ordinary least-squares
%  ------------------------------------------------------------------
     X = [ ones(n,1) X ]   ;

XTXI = X' * X;
if rcond(XTXI) < 1e-25
    S_err = 0.00000000000000000000000000000000001;
    return;
end

 XTXI = inv(XTXI);
 Coefficients = XTXI * X' * P ;

%  Calculate the fitted regression values
%  --------------------------------------

    P_hat = X * Coefficients;

%  Calculate residuals and standard error
%  --------------------------------------

    residuals = P - P_hat;

           S_err = sqrt(residuals' * residuals / (n - k - 1) );

%  Calculate the standard deviation  for the regression coefficients
%  -----------------------------------------------------------------------------

    covariance = XTXI .* S_err^2;

    C = sqrt(diag(covariance, 0));
    Er = abs(C./Coefficients)*100;

COEF=[[Er]'];
COEF(1)=[];


function sparse_grid_monomial_test ( rule, dim_num, level_max, degree_max )

%*****************************************************************************80
%
%% SPARSE_GRID_MONOMIAL_TEST tests monomial exactness of the sparse grid rules.
%
%  Discussion:
%
%    This test is going to check EVERY monomial of total degree DEGREE_MAX
%    or less.  Even for a moderately high dimension of DIM_NUM = 10, you
%    do NOT want to use a large value of DEGREE_MAX, since there are
%
%      1         monomials of total degree 0,
%      DIM_NUM   monomials of total degree 1,
%      DIM_NUM^2 monomials of total degree 2,
%      DIM_NUM^3 monomials of total degree 3, and so on.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 July 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer RULE, the index of the rule.
%    1, "CC", Clenshaw Curtis Closed Fully Nested rule.
%    2, "F1", Fejer 1 Open Fully Nested rule.
%    3, "F2", Fejer 2 Open Fully Nested rule.
%    4, "GP", Gauss Patterson Open Fully Nested rule.
%    5, "GL", Gauss Legendre Open Weakly Nested rule.
%    6, "GH", Gauss Hermite Open Weakly Nested rule.
%    7, "LG", Gauss Laguerre Open Non Nested rule.
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer LEVEL_MAX, the level.
%
%    Input, integer DEGREE_MAX, the maximum monomial total
%    degree to check.
%
  level_min = max ( 0, level_max + 1 - dim_num );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPARSE_GRID_MONOMIAL_TEST\n' );
  fprintf ( 1, '  Check the exactness of a sparse grid quadrature rule,\n' );
  fprintf ( 1, '  applied to all monomials of orders 0 to DEGREE_MAX.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  For cases where the dimension is greater than 1,\n' );
  fprintf ( 1, '  many sparse grid of this level have accuracy through\n' );
  fprintf ( 1, '  monomials of total degree   %d\n', 2 * level_max + 1 );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial dimension DIM_NUM = %d\n', dim_num );
  fprintf ( 1, '  LEVEL_MIN =                 %d\n', level_min );
  fprintf ( 1, '  LEVEL_MAX =                 %d\n', level_max );
  fprintf ( 1, '  1D quadrature index RULE =  %d\n', rule );
  fprintf ( 1, '  Check up to DEGREE_MAX =    %d\n', degree_max );
%
%  Determine the number of points in the rule.
%
  point_num = levels_index_size ( dim_num, level_max, rule );

  fprintf ( 1, '  Unique points in the grid = %d\n', point_num );
%
%  Compute the weights and points.
%
  [ grid_weight, grid_point ] = sparse_grid ( dim_num, level_max, rule, ...
    point_num );
%
%  Compare exact and estimated values of the integrals of various monomials.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '      Error      Total   Monomial\n' );
  fprintf ( 1, '                 Degree  Exponents\n' );
  fprintf ( 1, '\n' );

  for degree = 0 : degree_max

    expon = [];
    more = 0;
    h = 0;
    t = 0;

    while ( 1 )

      [ expon, more, h, t ] = comp_next ( degree, dim_num, expon, more, h, t );

      quad_error = monomial_quadrature ( dim_num, expon, point_num, ...
        grid_weight, grid_point, rule );

      fprintf ( 1, '  %14e  %2d  ', quad_error, degree );
      for dim = 1 : dim_num
        fprintf ( 1, '%2d', expon(dim) );
      end
      fprintf ( 1, '\n' );

      if ( ~more )
        break
      end

    end

    if ( 1 < dim_num )
      fprintf ( 1, '\n' );
    end

  end

  return
end


% The OxyGEN proyect by Profoty.xyz
% Together against the Covid-19
% V4.0 rev.17/03/2020
%
% Website/blog: oxygen.protofy.xyz
% Contact: oxygen@protofy.xyz

%GEOMETRICAL PARAMETERS

%Length from the bearing to the hinge
l0 = 27.3;

%Length of the vertical wall that supports the hinge
h0 = 6.5;

%Lenght of the vertical support of the bearing
hb = 5.0;

%Bearing radius
br = 1.1;

%Array of different max and min positions of the bearing
h1a = [6.5, 8.5, 10.5, 12.5];
h2a = [20.5, 20.5, 20.5, 20.5];

%Number of cycles per cam turn (1 to 3).
nc = 1;

%Minimum radius of the camshaft
rmin = 5;

%BREATHING CYCLE PARAMETERS

%Duration of the inhale cycle / duration of the whole cycle
lambda1 = 0.500;
lambda2 = 0.060;

%Soft transition between inhale and exhale cycles
dpsi21 = 0.12;
dpsi12 = 0.15;

%Adjust parameters of the inhale curve
ga1 = pi;
gb1 = 1.2;
ff1 = 20;
sp1 = 1;

%Adjust parametes of the exhale curve
ga2 = 9;
gb2 = .5;
ff2 = 20;

%GENERATION OF THE CURVES AND THE CAMSHAFT

%Generation of the geometry

l = sqrt(l0^2+hb^2);

for i = 1:numel(h1a);

    ymin(i) = h1a(i);
    ymax(i) = h2a(i);

    alphamin(i) = acos((h0 - h1a(i)) / l);
    alphamax(i) = acos((h0 - h2a(i)) / l);

    xmin(i) = l*sin(alphamin(i));
    xmax(i) = l*sin(alphamax(i));

    d(i) = sqrt((xmin(i)-xmax(i))^2 + (ymin(i)-ymax(i))^2);

    alphatan(i) = (alphamin(i) + alphamax(i)) / 2;

    xtan(i) = l*sin(alphatan(i));
    ytan(i) = h0 - l*cos(alphatan(i));

    xsup(i) = xtan(i) + (d(i)/2)*cos(alphatan(i));
    xinf(i) = xtan(i) - (d(i)/2)*cos(alphatan(i));

    ysup(i) = ytan(i) + (d(i)/2)*sin(alphatan(i));
    yinf(i) = ytan(i) - (d(i)/2)*sin(alphatan(i));

    xcam(i) = xtan(i) + (d(i)/2 + rmin + br)*cos(alphatan(i));
    ycam(i) = ytan(i) + (d(i)/2 + rmin + br)*sin(alphatan(i));

end;

%Time increment
dt = 0.01;

%time coordinate during the whole cycle
theta = 0:dt:2*pi;

%Generation of the soft transition between inhale and exhale curves
psi1 = [];
psi2 = [];

for i = 1:numel(theta);

    if theta(i) < (lambda2-dpsi21/2)*2*pi;
        psi1(i) = 0;

    elseif theta(i) < (lambda2+dpsi21/2)*2*pi;
        psi1(i) = 0.5 + 0.5*cos((theta(i)-(lambda2+dpsi21/2)*2*pi)/(2*dpsi21));

    else theta(i) < (lambda1-dpsi12/2)*2*pi;
        psi1(i) = 1;

    end;

    psi2(i) = 1 - psi1(i);

end;

%Generation of the complete breathing cycle rho(theta)

rho = [];
rho1 = [];
rho2 = [];
rho2next = [];

rhomin = 1000;
rhomax = 0;

for i = 1:numel(theta);

    %Inhale curve
    rho1(i) = ff1*normpdf(sp1*theta(i), ga1, gb1);
    rho1next(i) = ff1*normpdf(sp1*theta(i)+sp1*2*pi, ga1, gb1);

    %Exhale curve
    rho2(i) = ff2*gampdf(theta(i), ga2, gb2);
    rho2next(i) = ff2*gampdf(theta(i)+2*pi, ga2, gb2);

    rho(i) = rho1(i);

    %Capturing min and max in order to generate the normalized curve
    if rho(i) > rhomax
        rhomax = rho(i);
    end;

    if rho(i) < rhomin
        rhomin = rho(i);
    end;

end;

%Generation of a normalised curve and camshaft

rhonorm = [];
rhocam = [];

for i = 1:numel(theta);

    rhonorm(i) = (rho(i)-rhomin)/(rhomax-rhomin);

    for n = 1:numel(d)

        rhocam(n,i) = rmin + rhonorm(i)*d(n);

    end;

end;

%Generation of the first derivate of the camshaft geometry to analize and
%validate the design

drho = [];
drhonorm = [];
drhocam = [];

a = rmin;
b = 1/dt;

for i = 1 : numel(rho)-1;

    drho(i) = b*(rho(i+1)-rho(i));
    drhonorm(i) = b*(rhonorm(i+1)-rhonorm(i));
    drhocam(i) = b*(rhocam(i+1)-rhocam(i)) + a;

end;

drho(numel(rho)) = b*(rho(1)-rho(numel(rho)));
drhonorm(numel(rhonorm)) = b*(rhonorm(1)-rhonorm(numel(rhonorm)));
drhocam(numel(rhocam)) = b*(rhocam(1)-rhocam(numel(rhocam))) + a;

%X and Y coordinates during two cycles (for 2-cycle camshaft plot)

theta2 = [theta/2, (2*pi+theta)/2];

rhocam2 = [rhocam, rhocam];
drhocam2 = [drho, drho];

%X and Y coordinates during three cycles (for 3-cycle camshaft plot)

theta3 = [theta/3, (2*pi+theta)/3, (4*pi+theta)/3];

rhocam3 = [rhocam, rhocam, rhocam];
drhocam3 = [drho, drho, drho];

%GENERATION OF THE PLOTS

%Trying to print it out in real size (FAIL)
%set(gcf,'PaperUnits','centimeters');
%set(gcf,'PaperSize',[42 29.7]);

fpos = figure('Name', 'Dimensions', 'Units', 'centimeters', 'NumberTitle', 'off');
set(gcf,'PaperUnits','centimeters', 'PaperSize', [42/2 27.9/2]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 28, 20]);
fpos = gcf;
hold on

xlim([-5 35]);
ylim([0 30]);

for i = 1:numel(xmin)

    plot([0, xmin(i)], [h0, ymin(i)], '-x')
    plot([0, xmax(i)], [h0, ymax(i)], '-x')

    plot([0, xtan(i)], [h0, ytan(i)], '--xb')

    plot([xsup(i), xinf(i)], [ysup(i), yinf(i)], '--xr')
    scatter(xcam(1), ycam(1))

end;

hold off

%Plot of the breathing cycle interpolation by curves

fcycle = figure('Name', 'Breath Cycle curves', 'Units', 'centimeters', 'NumberTitle', 'off');

hold on
plot(theta, psi1, '-k')
plot(theta, psi2, '-k')
plot(theta, rho1, '-g')
plot(theta, rho1next, '-g')
plot(theta, rho2, '-g')
plot(theta, rho2next, '-g')
%plot(theta, drho, '-r')
plot(theta, rho, '-b')
hold off

set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
fcam3 = gcf;

%Plot of the normalized breathing cycle and first derivate

fnorm = figure('Name', 'Normalized Breath Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');

hold on
%plot(theta, drhonorm, '-r')
plot(theta, rhonorm, '-b')
hold off

set(gcf,'PaperUnits','centimeters', 'PaperSize', [42/2 27.9/2]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
fcam3 = gcf;

%Plot of a 1-cycle camshaft

for n = 1:numel(d)

    fcam1 = figure('Name', '1-Cycle Camshaft', 'Units', 'centimeters', 'NumberTitle', 'off');
    %hold on

    %polarplot(theta, drhocam, '-r')
    polar(theta, rhocam(n,:), '-b')

    %rlim([0 25]);
    hold off

    set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
    set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
    fcam3 = gcf;

end

% %Plot of a 2-cycle camshaft
%
% fcam2 = figure('Name', '2-Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');
%
% %hold on;
% %polar(theta, drhocam2, '-r')
% polar(theta2, rhocam2, '-b')
% %hold off;
%
% set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
% set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
% fcam3 = gcf;
%
%
% %Plot of a 3-cycle camshaft
%
% fcam3 = figure('Name', '3-Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');
%
% %hold on;
% %polar(theta,drhocam3)
% polar(theta3, rhocam3)
% %hold off;
%
% set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
% set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
% fcam3 = gcf;

% The OxyGEN proyect by Profoty.xyz
% Together against the Covid-19
% V4.0 rev.17/03/2020
%
% Website/blog: oxygen.protofy.xyz
% Contact: oxygen@protofy.xyz


% Demonstrate posthoc model comparison for spm_mlm_bayes

clear all
close all

N=100;
d=10;
p=5;

x=randn(N,p);
W=randn(p,d);
W(4:5,:)=0;
e=2*randn(N,d);

y=x*W+e;
verbose=1;

% Input-specific shrinkage
mlm = spm_mlm_bayes (y,x,'input',verbose);

figure
imagesc(mlm.wmean);
colormap gray
colorbar
ylabel('Inputs');
xlabel('Outputs');
title('Bayes Regression Coefficients');

figure
imagesc(mlm.wml);
colorbar
ylabel('Inputs');
xlabel('Outputs');
colormap(gray);
title('ML Regression Coefficients');

disp(' ');
disp('Posthoc questions:');
disp(' ');
disp('Is regression coefficient 1,1 non zero ?');
con=zeros(p,d);
con(1,1)=1;
con_vec=con(:)';
disp('Log Evidence in favour of this hypothesis:');
logbf = spm_mlm_posthoc (mlm,con_vec)

disp('Is regression coefficient 4,6 non zero ?');
con=zeros(p,d);
con(4,6)=1;
con_vec=con(:)';
disp('Log Evidence in favour of this hypothesis:');
logbf = spm_mlm_posthoc (mlm,con_vec)

disp('Are regression coefficients 1,1 2,1 and 3,1 non zero ?');
w=zeros(p,d);
w(1,1)=1;w(2,1)=1;w(3,1)=1;
con_vec1 = spm_mlm_makecon (mlm,w);
disp('Log Evidence in favour of this hypothesis:');
logbf = spm_mlm_posthoc (mlm,con_vec1)

disp('If we define w1 = regression coefficients 1,1 2,1 and 3,1');
disp('and w2 = regression coefficients 1,2 2,2 and 3,2');
disp('Is w1 different to w2 ?');
w=zeros(p,d);
w(1,2)=1;w(2,2)=1;w(3,2)=1;
con_vec2 = spm_mlm_makecon (mlm,w);
con_vec_diff=con_vec2-con_vec1;
disp('Log Evidence in favour of this hypothesis:');
logbf = spm_mlm_posthoc (mlm,con_vec_diff)


function [X,data] = kamada_kawai_spring_layout(A,varargin)
% KAMADA_KAWAI_SPRING_LAYOUT Use springs to compute a graph layout
%
% X = kamada_kawai_spring_layout(A) computes a layout for an undirected
% graph, connected graph by simulating a system of springs.
% [X,data] = kamada_kawai_spring_layout(A) returns extra data, such as the
% spring matrix and matrix of distances between vertices, i.e.
%   data.spring_strength % returns the spring stremgth
%   data.distances % returns the distance between all points
%
% See
% http://www.boost.org/doc/libs/1_36_0/libs/graph/doc/kamada_kawai_spring_layout.html
% for information about the layout function and the parameters
%
% ... = kamada_kawai_spring_layout(A,...) takes a set of
% key-value pairs or an options structure.  See set_matlab_bgl_options
% for the standard options.
%   options.tol: stopping tolerance of layout change [double | {1e-6}]
%   options.maxiter: the maximum number of layout iterations [500]
%   options.spring_constant: energy of the system [double | {1}]
%   options.progressive: if you want to start from an existing layout,
%     provide the coordinates of the layout [{0} | position matrix X]
%   options.edge_length: default length of an edge [double | {1}]
%   options.edge_weight: a double array over the edges with an edge
%       weight for each edge, see EDGE_INDEX and EXAMPLES/REWEIGHTED_GRAPHS
%       for information on how to use this option correctly
%       [{'matrix'} | 'none' | length(nnz(A)) double vector]
%
% Example:
%   G = grid_graph(6,5);
%   X = kamada_kawai_spring_layout(G);
%   gplot(G,X);
%
% See also FRUCHTERMAN_REINGOLD_FORCE_DIRECTED_LAYOUT, GURSOY_ATUN_LAYOUT

% David F. Gleich
% Copyright, Stanford University, 2008

%% History
%  2008-09-25: Initial coding
%%

[trans check full2sparse] = get_matlab_bgl_options(varargin{:});
if full2sparse && ~issparse(A), A = sparse(A); end

n = num_vertices(A);
options = struct('tol',1e-6,'maxiter',500,'spring_constant',1,...
    'progressive',0,'edge_length',1,'edge_weight','matrix');
options = merge_options(options,varargin{:});

% edge_weights is an indicator that is 1 if we are using edge_weights
% passed on the command line or 0 if we are using the matrix, or -1 to use
% nothing
edge_weights = 0;
edge_weight_opt = 'matrix';

if strcmp(options.edge_weight, 'matrix'), % do nothing to use the matrix weights
elseif strcmp(options.edge_weight,'none'), edge_weights = -1; % don't use weights
else edge_weights = 1; edge_weight_opt = options.edge_weight;
end

if check
    % make sure the matrix is symmetric
    if ~edge_weights==1
        check_matlab_bgl(A,struct('sym',1,'values',edge_weights==0,'noneg',1));
    else
        if nnz(A) ~= length(edge_weight_opt)
            error('matlab_bgl:invalidParameter', ...
             'the vector of edge weights must have length nnz(A)');
        end
        if any(edge_weight_opt)<0, error('matlab_bgl:invalidParameter',...
                'the edge_weight array must be non-negative');
        end
        [i j] = find(A);
        Av = sparse(i,j,edge_weight_opt,size(A,1),size(A,2));
        check_matlab_bgl(Av,struct('sym',1,'noneg',1));
    end
end

progressive_opt = [];
if ~isscalar(options.progressive), progressive_opt = options.progressive; end

[X,spring,distance]=kamada_kawai_spring_layout_mex(...
    A, options.tol, options.maxiter, options.spring_constant, ...
    progressive_opt, options.edge_length, edge_weights, edge_weight_opt);

if nargout>1, data.spring_strength = spring; data.distances = distance; end


function he_plot ( a, b, index, filename )

%*****************************************************************************80
%
%% HE_PLOT plots HE(i,x).
%
%  Discussion:
%
%    He(i,x) represents the probabilist's Hermite polynomial.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 February 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the plotting range.
%
%    Input, integer INDEX(*), the orders of 1 or more Hermite functions
%    to be plotted together.
%
%    Input, string FILENAME, the name into which the graphics information is
%    to be stored.  Note that the PNG format will be used.
%
  m = 501;
  x = linspace ( a, b, m );
  x = x';
  index_num = length ( index );

  clf
  hold on
  for i = 1 : index_num
    n = index(i);
    y = he_polynomial_value ( m, n, x );
    plot ( x, y(:,n+1), 'LineWidth', 2 );
  end
  grid on
  xlabel ( '<--- X --->', 'Fontsize', 16 )
  ylabel ( '<--- He(i,x) --->', 'Fontsize', 16 )
  title ( 'Hermite polynomials He(n,x)', 'Fontsize', 24 )
  hold off
  print ( '-dpng', filename )

  return
end


function geometry_test2069 ( )

%*****************************************************************************80
%
%% TEST2069 tests TRIANGLE_CONTAINS_LINE_PAR_3D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2007
%
%  Author:
%
%    John Burkardt
%
  dim_num = 3;

  p0 = [ 3.0, 0.0, -7.0 ];
  pd = [ 2.0, 1.0, 5.0 ];
  t = [ ...
    8.0, 4.0, 2.0; ...
    9.0, 0.0, 5.0; ...
    2.0, 1.0, 2.0 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST2069\n' );
  fprintf ( 1, '  TRIANGLE_CONTAINS_LINE_PAR_3D determines whether\n' );
  fprintf ( 1, '    a triangle "contains" a parametric line in 3D.\n' );

  r8mat_transpose_print ( dim_num, 3, t, '  Triangle vertices:' );

  norm = sqrt ( sum ( pd(1:dim_num).^2 ) );
  pd(1:dim_num) = pd(1:dim_num) / norm;

  r8vec_print ( dim_num, p0, '  Parametric base point P0:' );
  r8vec_print ( dim_num, pd, '  Parametric direction PD:' );

  [ inside, pint ] = triangle_contains_line_par_3d ( t, p0, pd );

  if ( inside )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  The triangle contains the line.\n' );
    r8vec_print ( dim_num, pint, '  Intersection point:' );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, '  The triangle does not contain the line.\n' );
    r8vec_print ( dim_num, pint, '  The intersection point:' );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Expected answer:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    The triangle contains the line, and\n' );
  fprintf ( 1, '    the intersection point is at:\n' );
  fprintf ( 1, '      ( 7, 2, 3 ).\n' );

  return
end


function out = DT_IsSeasonal(y)
% DT_IsSeasonal     A simple test of seasonality.
%
% Fits a 'sin1' model to the time series using fit function from the Curve Fitting
% Toolbox. The output is binary: 1 if the goodness of fit, R^2, exceeds 0.3 and
% the amplitude of the fitted periodic component exceeds 0.5, and 0 otherwise.
%
%---INPUTS:
% y, the input time series
%
%---OUTPUT: Binary: 1 (= seasonal), 0 (= non-seasonal)

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function is free software: you can redistribute it and/or modify it under
% the terms of the GNU General Public License as published by the Free Software
% Foundation, either version 3 of the License, or (at your option) any later
% version.
%
% This program is distributed in the hope that it will be useful, but WITHOUT
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
% details.
%
% You should have received a copy of the GNU General Public License along with
% this program. If not, see <http://www.gnu.org/licenses/>.
% ------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
%% Preliminaries
%-------------------------------------------------------------------------------
% Check a curve-fitting toolbox license is available:
BF_CheckToolbox('curve_fitting_toolbox');

% Make sure the input time series, y, is a column vector
if size(y,2) > size(y,1)
    y = y';
end
N = length(y); % length of input time series
r = (1:N)'; % range over which to fit

%-------------------------------------------------------------------------------
%% Fit a sinusoidal model using the Curve-Fitting Toolbox
%-------------------------------------------------------------------------------
[cfun,gof] = fit(r,y,'sin1'); % fits the following form: a1*sin(b1*x+c1)

%-------------------------------------------------------------------------------
%% Two conditions for determining whether time series contains periodicities:
%-------------------------------------------------------------------------------
% Condition 1: fit is ok
th_fit = 0.3; % r2 > th_fit

% Condition 2: amplitude is not too small
th_ampl = 0.5; % a1 > th_ampl

if gof.rsquare > th_fit && abs(cfun.a1 > th_ampl)
    out = 1; % test thinks the time series has strong periodicities
else
    out = 0; % test thinks the time series doesn't have any strong periodicities
end

end


function coords = gsp_lle(G, dim, param)
%GSP_LLE Local Linear Embedding
%   Usage: coords = gsp_lle(G, dim);
%          coords = gsp_lle(G, dim, param);
%
%   Input parameters
%         G          : Graph
%         dim        : Dimensionality of the embedding
%         param      : Structure of optional parameters
%
%   Output parameters
%         coords     : Coordinates of the embedding
%
%   This function uses the weight matrix of a graph G, in order to compute
%   a *dim* -dimensional embedding (output coordinates). The algorithm used
%   is Locally Linear Embedding (LLE). Warning, this function might not
%   work if the graph is not connected.
%
%   *param* is a structure with optional parameters:
%
%   * *param.tol*    : Tolerance for the spectral gap (default 1e-6).
%   * *param.kernel* : The kernel used to create the graph weight matrix:
%     + 'exp'        : exponential kernel ($e^(frac{-d_{ij}}{sigma^2})$)
%     + '1/x'        : inverse of x kernel ($frac{1}{sigma+d_{ij}}$)
%     + '1/x^2'      : inverse of x^2 kernel ($frac{1}{(sigma+d_{ij})^2}$)
%     + 'resistance' : Resistance distance.
%   * *param.k*      : Max number of nearest neighbors. If not defined, the
%
%   number of neighbors varies from node to node since the algorithm
%   considers all the columns $j$ of the weight matrix that have non
%   zero values on the line $i$ as the neighbors of $i$.
%
%   References: saul2000introduction
%
%   See also: gsp_update_coordinates gsp_isomap gsp_laplacian_eigenmaps
%
%   Demo: gsp_demo_graph_embedding

% Authors : Dion O. E. Tzamarias
% Date    : 20/11/2015

%% TODO Fix bug param.k
%%

if nargin<3
    param = struct;
end

if ~isfield(param,'tol'), param.tol = 1e-6; end
if ~isfield(param,'kernel'), param.kernel = 'exp'; end

% Handling default parameters

W = zeros(G.N,G.N);

% if ~isfield(param,'k')
    [D] = gsp_weight2distance(G);
    [rows, cols ] = find(D);
    idx = cell(cols(end),1);
    for jj=1:cols(end)
        idx{jj} = rows(cols==jj).';
    end
% else
%     [D,idx] = gsp_weight2distance(G, param.kernel, param.k);
% end
D = D.^2; % D contains the squared distances
for ii=1:length(D)

    %   C = 0.5*(repmat(sum(D(idx{ii},idx{ii}),2),1,length(idx{ii}))/length(idx{ii})...
    %       + repmat(sum(D(idx{ii},idx{ii}),2).',length(idx{ii}),1)/length(idx{ii}) ...
    %       - D(idx{ii},idx{ii}) - repmat(sum(sum(D(idx{ii},idx{ii}),1)),...
    %       length(idx{ii}),length(idx{ii}))/length(idx{ii}).^2);
    C = 0.5*(bsxfun(@plus,sum(D(idx{ii},idx{ii}),2),sum(D(...
        idx{ii},idx{ii}),1))/length(idx{ii})-bsxfun(@plus,...
        D(idx{ii},idx{ii}),sum(sum(D(idx{ii},idx{ii}),1))...
        /length(idx{ii}).^2));

    if abs(det(C))< param.tol  %   C is singular
        C = C + (param.tol*trace(C)) / length(idx{ii})...
            * eye(size(C));
    end
%     if abs(det(C))< param.tol*1e-3
%         warning('C is singular')
%     end

    W(ii,idx{ii}) = C\ones(length(idx{ii}),1);
    W(ii,:) = W(ii,:)./sum(W(ii,:));
end

M = (eye(G.N,G.N) - W)' * (eye(G.N,G.N) - W);
M = sparse(M);

% Compute first dim eigenvectors of M
options.disp = 0;
options.isreal = 1;
options.issym = 1;
% only need bottom (no_dims + 1) eigenvectors
tol = param.tol;
[coords, e] = eigs(M, dim + 1, tol, options);
e = diag(e);

if nnz(e<param.tol) > 1
    disp('Multiple zero eigenvalues')
end

[~ , ind] = sort(e, 'ascend');
coords = coords(:,ind);
coords = coords(:,2:end);
end

%   The input parameter type refers to the type of the problem:
%   * 'weight_matrix' : Solve problem using the weight matrix of the graph G
%     Use the pairwise distance equation in order to reconstruct data from
%     neighbours.
%   * 'coords'       : Slove the problem using the coordinates. This is the
%     typical LLE aproach.

% switch lower(type)
%     case 'coords'
%         for ii=1:G.N
%
%             k_near_indx = knnsearch(G.coords,G.coords(ii,:),'k',n_neighbor+1);
%             k_nearest = G.coords(k_near_indx(2:end),:);
%
%             C = (repmat(G.coords(ii,:),n_neighbor,1) - k_nearest)* ...
%                 (repmat(G.coords(ii,:),n_neighbor,1) - k_nearest)' ;
%
%             if abs(det(C))<tol  % C is not singular
%                 C = C + ((tol*trace(C))^2) / n_neighbor * eye(size(C));
%             end
%             if abs(det(C))<tol
%                 warning('C is not singular')
%             end
%
%             W(ii,k_near_indx(2:end)) = C\ones(n_neighbor,1);
%             W(ii,:) = W(ii,:)./sum(W(ii,:));
%         end
%
%     case 'weight_matrix'


function [a,fps,tps] = aucs(crit,z)
%AUCS Compute area under curve for survival model
%
%  Description
%    A = AUCS(CRIT,Z) Compute are under curve for survival model
%    using criteria vector CRIT (where larger value means larger
%    risk of incidence) and censoring indicator column vector Z
%    (0=event, 1=censored).
%
%    [A,FPS,TPS] = AUCS(CRIT,Z) Return also a vector of false
%    positive rates FPS and a vector of true positive rates TPS.
%
%  Reference
%    L. E. Chambless, C. P. Cummiskey, and G. Cui (2011). Several
%    methods to assess improvement in risk prediction models:
%    Extension to survival analysis. Statistics in Medicine
%    30(1):22-38.

% Copyright (C) 2012 Ernesto Ulloa, Aki Vehtari

% 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.

ip=inputParser;
ip.addRequired('crit',@(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
ip.addRequired('z', @(x) isreal(x) && all(isfinite(x(:))))
ip.parse(crit,z)

ye=z;
tps=0;
fps=0;
qs=sort(crit,'descend');

for i2=1:numel(crit)
  tps(i2+1)=mean(crit>=qs(i2) & 1-ye)./mean(1-ye);
  fps(i2+1)=mean(crit>=qs(i2) & ye)./(mean(ye));
end

if (mean(1-ye)==0)||(mean(ye)==0)
  warning('z vector has no different values, function will return 0');
  a=0;
else
  a=sum([diff(fps).*mean([tps(1:end-1);tps(2:end)],1)]);
end

end


function value = p31_exact ( dim_num )

%*****************************************************************************80
%
%% P31_EXACT returns the exact integral for problem 31.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Kenneth Hanson,
%    Quasi-Monte Carlo: halftoning in high dimensions?
%    in Computatinal Imaging,
%    Edited by CA Bouman and RL Stevenson,
%    Proceedings SPIE,
%    Volume 5016, 2003, pages 161-172.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Output, real VALUE, the exact value of the integral.
%

%
%  Get the limits of integration.
%
  [ a, b ] = p31_lim ( dim_num );
%
%  Get the coefficient vector C.
%
  c = [];
  c = p31_r8vec ( 'G', 'C', dim_num, c );
%
%  Get the location of Z.
%
  z = [];
  z = p31_r8vec ( 'G', 'Z', dim_num, z );
%
%  The value of the DIM_NUM dimensional integral is separable
%  into the product of integrals over each dimension.
%
%  Each of these 1 dimensional integrals, in turn, is
%  easily computed, depending on where Z(I) lies with
%  respect to the limits of integration A(I) and B(I).
%
  value = 1.0;

  for i = 1 : dim_num
%
%  Z < A < B
%
%  | X - Z | = X - Z from A to B.
%
    if ( z(i) < a(i) )

      value = value * ...
      ( exp ( - c(i) * ( a(i) - z(i) ) ) ...
      - exp ( - c(i) * ( b(i) - z(i) ) ) ) / c(i);
%
%  A < Z < B
%
%  | X - Z | = Z - X from B to Z,
%            = X - Z from      Z to A.
%
    elseif ( z(i) < b(i) )

      value = value * ( 2.0 ...
          - exp ( - c(i) * ( z(i) - a(i) ) ) ...
          - exp ( - c(i) * ( b(i) - z(i) ) ) ) / c(i);
%
%  A < B < Z
%
%  | X - Z | = Z - X from A to B.
%
    else

      value = value * ...
      ( exp ( - c(i) * ( z(i) - b(i) ) ) ...
      - exp ( - c(i) * ( z(i) - a(i) ) ) ) / c(i);

    end

  end

  return
end


function cvx_optpnt = complex_lorentz( sx, dim )

%COMPLEX_LORENTZ   Complex second-order cone.
%   COMPLEX_LORENTZ(N), where N is a positive integer, creates a column
%   variable of length N and a scalar variable, and constrains them
%   to lie in a second-order cone. That is, given the declaration
%       variable x(n) complex
%       variable y
%   the constraint
%       {x,y} == complex_lorentz(n)
%   is equivalent to
%       norm(x,2) <= y
%   The inequality form is more natural, and preferred in most cases. But
%   in fact, the COMPLEX_LORENTZ set form is used by CVX itself to convert
%   complex NORM()-based constraints to solvable form.
%
%   COMPLEX_LORENTZ(SX,DIM), where SX is a valid size vector and DIM is a
%   positive integer, creates an array variable of size SX and an array
%   variable of size SY (see below) and applies the second-order cone
%   constraint along dimension DIM. That is, given the declarations
%       sy = sx; sy(min(dim,length(sx)+1))=1;
%       variable x(sx) complex
%       variable y(sy)
%   the constraint
%       {x,y} == complex_lorentz(sx,dim)
%   is equivalent to
%       norms(x,2,dim) <= y
%   Again, the inequality form is preferred, but CVX uses the set form
%   internally. DIM is optional; if it is omitted, the first non-singleton
%   dimension is used.
%
%   LORENTZ(SX,DIM,CPLX) creates real second-order cones if CPLX is FALSE,
%   and complex second-order cones if CPLX is TRUE. The latter case is
%   equivalent to COMPLEX_LORENTZ(SX,DIM).
%
%   Disciplined convex programming information:
%       LORENTZ is a cvx set specification. See the user guide for
%       details on how to use sets.

narginchk(1,2);
if nargin == 1,
    cvx_optpnt = lorentz( sx, [], true );
else
    cvx_optpnt = lorentz( sx, dim, true );
end

% Copyright 2005-2016 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function value = p13_f ( dim_num, point_num, x )

%*****************************************************************************80
%
%% P13_F evaluates the integrand for problem 13.
%
%  Dimension:
%
%    DIM_NUM arbitrary.
%
%  Region:
%
%    0 <= X(1:DIM_NUM) <= 1
%
%  Integrand:
%
%    product ( 1 <= i <= dim_num ) t(n(i))(2*x(i)-1)
%
%    where T(N)(X) is the Chebyshev polynomial of order N,
%    and N(I) = mod ( i, 4 ) + 1.
%
%  Exact Integral:
%
%    0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 June 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Harald Niederreiter,
%    Implementation and Tests of Low-Discrepancy Sequences,
%    ACM Transactions on Modeling and Computer Simulation,
%    Volume 2, Number 3, July 1992, pages 195-213.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the argument.
%
%    Input, integer POINT_NUM, the number of points.
%
%    Input, real X(DIM_NUM,POINT_NUM), the evaluation points.
%
%    Output, real VALUE(POINT_NUM), the integrand values.
%
  value(1:point_num) = 1.0;

  for point = 1 : point_num

    for dim = 1 : dim_num

      t = 2.0 * x(dim,point) - 1.0;
      k = mod ( dim, 4 );

      if ( k == 1 )
        factor = t;
      elseif ( k == 2 )
        factor = 2.0 * t - 1.0;
      elseif ( k == 3 )
        factor = ( 4.0 * t - 3.0 ) * t;
      elseif ( k == 4 )
        factor = ( 8.0 * t - 8.0 * t + 1.0 );
      end

      value(point) = value(point) * factor;

    end

  end

  p13_i4 ( 'I', '#', point_num );

  return
end


function jed = ymd_to_jed_gregorian ( y, m, d )

%*****************************************************************************80
%
%% YMD_TO_JED_GREGORIAN converts a Gregorian YMD date to a JED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Richards,
%    Algorithm E,
%    Mapping Time, The Calendar and Its History,
%    Oxford, 1999, pages 323-324.
%
%  Parameters:
%
%    Input, integer Y, M, D, the YMD date.
%
%    Output, real JED, the corresponding JED.
%

%
%  Check the date.
%
  [ y, m, d, ierror ] = ymd_check_gregorian ( y, m, d );

  if ( ierror ~= 0 )
    jed = -1.0;
    return
  end
%
%  Account for the missing year 0 by moving negative years up one.
%
  y2 = y_common_to_astronomical ( y );
%
%  Convert the calendar date to a computational date.
%
  y_prime = y2 + 4716 - floor ( ( 14 - m ) / 12 );
  m_prime = mod ( m + 9, 12 );
  d_prime = d - 1;
%
%  Convert the computational date to a JED.
%
  j1 = floor ( ( 1461 * y_prime ) / 4 );

  j2 = floor ( ( 153 * m_prime + 2 ) / 5 );

  g = floor ( ( y_prime + 184 ) / 100 );

  g = floor ( 3 * g / 4 ) - 38;

  jed = j1 + j2 + d_prime - 1401 - g - 0.5;

  return
end


function xdot = dto_rhs (t, x, u)

% first-order equations of motion

% required by dto_trap.m

% input

%  t = current time

%  x = current state vector

%  x(1) = r, x(2) = u, x(3) = v

%  u = current control vector

% output

%  xdot = rhs equations of motion

%  xdot(1) = r dot, xdot(2) = u dot, xdot(3) = v dot

% Orbital Mechanics with MATLAB

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

global acc beta

% current control variable

theta = u(1);

% current thrust acceleration

accm = acc / (1.0 - beta * t);

% evaluate equations of motion at current conditions

xdot(1) = x(2);

xdot(2) = (x(3) * x(3) - 1.0 / x(1)) / x(1) + accm * sin(theta);

xdot(3) = -x(2) * x(3) / x(1) + accm * cos(theta);


function LLF = cauchy_log(parameters,data)
%---------------------------------------------------
% PURPOSE:
%  Log Likelihood function of the Cauchy-Lorentz Distribution,
%  to estimate the location and scale parameters of a data set
%---------------------------------------------------
% USAGE:
% LLF = cauchy_log(x, data)
%
% INPUTS:
% parameters: a vector of parameters of the form [m; s]
% data:       the data set
%
% OUTPUTS:
% LLF:      The log-likelihood function
%---------------------------------------------------
% Author:
% Alexandros Gabrielsen, a.gabrielsen@city.ac.uk
% Date: 06/2010
%---------------------------------------------------
[a,b]=size(parameters);
if b>a
   parameters=parameters';
end
n=length(data);
LLF  = -n*log(pi) +n*log(parameters(2)) - sum(log(parameters(2)^2 + (data-parameters(1)).^2));
end


function y = mat2lpc(x,f)
%MAT2LPC Compresses a matrix using 1-D lossles predictive coding.
%   Y = MAT2LPC(X, F) encodes matrix X using 1-D lossless predictive
%   coding. A linear prediction of X is made based on the coefficients
%   in F. If F is omitted, F = 1 (for previous pixel coding) is assumed.
%   The prediction error is then computed and output as encoded matrix
%   Y.
%
%   See also LPC2MAT.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

narginchk(1,2);                     % Check input arguments
if nargin < 2                       % Set default filter if omitted
    f = 1;
end

x = double(x);                      % Ensure double for computations
[m, n] = size(x);                   % Get dimensions of input matrix
p = zeros(m,n);                     % Init linear prediction to 0
xs = x;     zc = zeros(m,1);        % Prepare for input shift and pad

for j = 1:length(f)                 % For each filter coefficient ...
    xs = [zc xs(:,1:end - 1)];      % Shift and zero pad x
    p = p + f(j) * xs;              % Form partial prediction sums
end

y = x - round(p);                   % Compute prediction error


function test_tutorial_connectivity20130308

% MEM 7gb
% WALLTIME 00:10:00
% DEPENDENCY

% Simulated data with directed connections
% We will first simulate some data with a known connectivity structure built in. This way we know what to expect in terms of connectivity. To simulate data we use ft_connectivitysimulation. We will use an order 2 multivariate autoregressive model. The necessary ingredients are a set of NxN coefficient matrices, one matrix for each time lag. These coefficients need to be stored in the cfg.param field. Next to the coefficients we have to specify the NxN covariance matrix of the innovation noise. This matrix needs to be stored in the cfg.noisecov field. The model we are going to use to simulate the data is as follows:
%
% x(t) = 0.8*x(t-1) - 0.5*x(t-2)
% y(t) = 0.9*y(t-1) + 0.5*z(t-1) - 0.8*y(t-2)
% z(t) = 0.5*z(t-1) + 0.4*x(t-1) - 0.2*z(t-2)

cfg             = [];
cfg.ntrials     = 500;
cfg.triallength = 1;
cfg.fsample     = 200;
cfg.nsignal     = 3;
cfg.method      = 'ar';

cfg.params(:,:,1) = [ 0.8    0    0 ;
                        0  0.9  0.5 ;
                      0.4    0  0.5];

cfg.params(:,:,2) = [-0.5    0    0 ;
                        0 -0.8    0 ;
                        0    0 -0.2];

cfg.noisecov      = [ 0.3    0    0 ;
                        0    1    0 ;
                        0    0  0.2];

data              = ft_connectivitysimulation(cfg);

% The simulated data consists of 3 channels in 500 trials. You can easily visualize the data for example in the first trial using
%
figure
plot(data.time{1}, data.trial{1})
legend(data.label)
xlabel('time (s)')

% or browse through the complete data using
%
cfg = [];
cfg.viewmode = 'vertical';  % you can also specify 'butterfly'
ft_databrowser(cfg, data);

%
%
% Computation of the multivariate autoregressive model
% To be able to compute spectrally resolved Granger causality, or other frequency-domain directional measures of connectivity, we have to fit an autoregressive model to the data. This is done using the ft_mvaranalysis function.
%
% For the actual computation of the autoregressive coefficients FieldTrip makes use of an implementation from third party toolboxes. At present ft_mvaranalysis supports the biosig and bsmart toolboxes for these computations.
%
% In this tutorial we will use the bsmart toolbox. The relevant functions have been included in the FieldTrip release in the fieldtrip/external/bsmart directory.
%
cfg         = [];
cfg.order   = 5;
cfg.toolbox = 'bsmart';
mdata       = ft_mvaranalysis(cfg, data);

% mdata =
%          dimord: 'chan_chan_lag'
%           label: {3x1 cell}
%          coeffs: [3x3x5 double]
%        noisecov: [3x3 double]
%             dof: 500
%     fsampleorig: 200
%             cfg: [1x1 struct]
%
% The resulting variable mdata contains a description of the data in terms of a multivariate autoregressive model. For each time-lag up to the model order (which is 5 in this case), a 33 matrix of coefficients is outputted. The noisecov-field contains covariance matrix of the model's residuals.
%
% Exercise 1
% Compare the parameters specified for the simulation with the estimated coefficients and discuss.
%
% Computation of the spectral transfer function
% From the autoregressive coefficients it is now possible to compute the spectral transfer matrix, for which we use ft_freqanalysis.
%
cfg        = [];
cfg.method = 'mvar';
mfreq      = ft_freqanalysis(cfg, mdata);

% mfreq =
%         label: {3x1 cell}
%          freq: [1x101 double]
%        dimord: 'chan_chan_freq'
%      transfer: [3x3x101 double]
%      noisecov: [3x3 double]
%     crsspctrm: [3x3x101 double]
%           dof: 500
%           cfg: [1x1 struct]
%
% The resulting mfreq data structure contains the pairwise transfer function between the 3 channels for 101 frequencies.
%
% It is also possible to compute the spectral transfer function using non-parametric spectral factorization of the cross-spectral density matrix. For this, we need a Fourier decomposition of the data. This is done in the following section.
%
%
% Non-parametric computation of the cross-spectral density matrix
% Some connectivity metrics can be computed from a non-parametric spectral estimate (i.e. after the application of the FFT-algorithm and conjugate multiplication to get cross-spectral densities), such as coherence, phase-locking value and phase slope index. The following part computes the fourier-representation of the data using ft_freqanalysis. It is not necessary to compute the cross-spectral density at this stage, because the function used in the next step, ft_connectivityanalysis, contains functionality to compute the cross-spectral density from the fourier coefficients.
%
cfg           = [];
cfg.method    = 'mtmfft';
cfg.taper     = 'dpss';
cfg.output    = 'fourier';
cfg.tapsmofrq = 2;
freq          = ft_freqanalysis(cfg, data);

% freq =
%             label: {3x1 cell}
%            dimord: 'rpttap_chan_freq'
%              freq: [1x101 double]
%     fourierspctrm: [1500x3x101 double]
%         cumsumcnt: [500x1 double]
%         cumtapcnt: [500x1 double]
%               cfg: [1x1 struct]
% The resulting freq structure contains the spectral estimate for 3 tapers in each of the 500 trials (hence 1500 estimates), for each of the 3 channels and for 101 frequencies.
%
%
% Computation and inspection of the connectivity measures
% The actual computation of the connectivity metric is done by ft_connectivityanalysis. This function is transparent to the type of input data, i.e. provided the input data allows the requested metric to be computed, the metric will be calculated. Here, we provide an example for the computation and visualization of the coherence coefficient.
%
cfg           = [];
cfg.method    = 'coh';
coh           = ft_connectivityanalysis(cfg, freq);
cohm          = ft_connectivityanalysis(cfg, mfreq);
% Subsequently, the data can be visualized using ft_connectivityplot.
%
cfg           = [];
cfg.parameter = 'cohspctrm';
cfg.zlim      = [0 1];
ft_connectivityplot(cfg, coh, cohm);

%
% The coherence measure is a symmetric measure, which means that it does not provide information regarding the direction of information flow between any pair of signals. In order to analyze directionality in interactions, measures based on the concept of granger causality can be computed. These measures are based on an estimate of the spectral transfer matrix, which can be computed in a straightforward way from the multivariate autoregressive model fitted to the data.
%
cfg           = [];
cfg.method    = 'granger';
granger       = ft_connectivityanalysis(cfg, mfreq);

cfg           = [];
cfg.parameter = 'grangerspctrm';
cfg.zlim      = [0 1];
ft_connectivityplot(cfg, granger);

% Instead of plotting it with ft_connectivityplot, you can use the following low-level MATLAB plotting code which gives a better understanding of the numerical representation of the results.
%
figure
for row=1:3
for col=1:3
  subplot(3,3,(row-1)*3+col);
  plot(granger.freq, squeeze(granger.grangerspctrm(row,col,:)))
  ylim([0 1])
end
end

%
% Exercise 2
% Discuss the differences between the granger causality spectra, and the coherence spectra.
% Exercise 3
% Compute the following connectivity measures from the mfreq data, and visualize and discuss the results: partial directed coherence (pdc), directed transfer function (dtf), phase slope index (psi)
%
% Simulated data with common pick-up and different noise levels
%  this is under progress
%
% When working with electrophysiological data (EEG/MEG/LFP) the signals that are picked up by the individual channels invariably consist of instantaneous mixtures of the underlying source signals. This mixing can severely affect the outcome of connectivity analysis, and thus affects the interpretation. We will demonstrate this by simulating data in 2 channels, where each of the channels consists of a weighted combination of temporally white noise unique to each of the channels, and a common input of a band-limited signal (filtered between 15 and 25 Hz). We will compute connectivity between these channels, and show that the common input can give rise to spurious estimates of connectivity.
%
% % create some instantaneously mixed data
%
% define some variables locally
nTrials  = 100;
nSamples = 1000;
fsample  = 1000;

% mixing matrix
mixing   = [0.8 0.2 0;
              0 0.2 0.8];

data       = [];
data.trial = cell(1,nTrials);
data.time  = cell(1,nTrials);
for k = 1:nTrials
  dat = randn(3, nSamples);
  dat(2,:) = ft_preproc_bandpassfilter(dat(2,:), 1000, [15 25]);
  dat = 0.2.*(dat-repmat(mean(dat,2),[1 nSamples]))./repmat(std(dat,[],2),[1 nSamples]);
  data.trial{k} = mixing * dat;
  data.time{k}  = (0:nSamples-1)./fsample;
end
data.label = {'chan1' 'chan2'}';

figure;plot(dat'+repmat([0 1 2],[nSamples 1]));
title('original ''sources''');

figure;plot((mixing*dat)'+repmat([0 1],[nSamples 1]));
axis([0 1000 -1 2]);
set(findobj(gcf,'color',[0 0.5 0]), 'color', [1 0 0]);
title('mixed ''sources''');

% do spectral analysis
cfg = [];
cfg.method    = 'mtmfft';
cfg.output    = 'fourier';
cfg.foilim    = [0 200];
cfg.tapsmofrq = 5;
freq          = ft_freqanalysis(cfg, data);
fd            = ft_freqdescriptives(cfg, freq);

figure;plot(fd.freq, fd.powspctrm);
set(findobj(gcf,'color',[0 0.5 0]), 'color', [1 0 0]);
title('powerpectrum');

%
% compute connectivity
cfg = [];
cfg.method = 'granger';
g = ft_connectivityanalysis(cfg, freq);
cfg.method = 'coh';
c = ft_connectivityanalysis(cfg, freq);
% visualize the results
cfg = [];
cfg.parameter = 'grangerspctrm';
ft_connectivityplot(cfg, g);
cfg.parameter = 'cohspctrm';
ft_connectivityplot(cfg, c);

% Exercise 4
% Simulate new data using the following mixing matrix:
% [0.9 0.1 0;0 0.2 0.8]
% and recompute the connectivity measures. Discuss what you see.
%
% Exercise 5
% Play a bit with the parameters in the mixing matrix and see what is the effect on the estimated connectivity.
% Exercise 6
% Simulate new data where the 2 mixed signals are created from 4 underlying sources, and where two of these sources are common input to both signals, and where these two sources are temporally shifted copies of one another.
% Hint: the mixing matrix could look like this:
%
% [a b c 0; 0 d e f];
% and the trials could be created like this:
%
% for k = 1:nTrials
%   dat = randn(4, nSamples+10);
%   dat(2,:) = ft_preproc_bandpassfilter(dat(2,:), 1000, [15 25]);
%   dat(3,1:(nSamples)) = dat(2,11:(nSamples+10));
%   dat = dat(:,1:1000);
%   dat = 0.2.*(dat-repmat(mean(dat,2),[1 nSamples]))./repmat(std(dat,[],2),[1 nSamples]);
%   data.trial{k} = mixing * dat;
%   data.time{k}  = (0:nSamples-1)./fsample;
% end
% Compute connectivity between the signals and discuss what you observe. In particular, also compute measures of directed interaction.
%
%
% Connectivity between MEG virtual channel and EMG
% The previous two examples were using simulated data, either with a clear directed connectivity structure, or with a trivial pick-up of a common source in two channels. We will now continue with connectivity analysis on real MEG data. The dataset is the same as the one used in the Analysis of corticomuscular coherence tutorial.
%
% In short, the dataset consists of combined MEG and EMG recordings while the subject lifted his right hand. The coherence tutorial introduction contains a more elaborate description of the experiment and the dataset and a detailed analysis can be found in the corresponding paper 1). Due to the long distance between the EMG and the MEG, there is no volume conduction and hence no common pick-up. Hence this dataset lends itself well for connectivity analysis. But rather than doing an analysis between the EMG and one of the MEG channels (as in the original study), we will extract the cortical activity using a beamformer virtual channel.
%
%
% Compute the spatial filter for the region of interest
% We start with determining the motor cortex as region of interest. At the end of the coherence tutorial it is demonstrated how to make a 3-D reconstruction of the cortico-muscolar coherence (CMC) using the DICS algorithm. That source reconstruction serves as starting point for this analysis.
%
% You can download the result from the DICS reconstruction from the FieldTrip ftp server (source.mat)
%
% We will first determine the position on which the cortico-muscular coherence is the largest.
%

cd(dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/connectivity'));
load source

[maxval, maxindx] = max(source.avg.coh);
maxpos = source.pos(maxindx,:);

% maxpos =
%     4 -3 12
% The cortical position is expressed in individual subject head-coordinates and in centimeter. Relative to the center of the head (in between the ears) the position is 4 cm towards the nose, -3 towards the left side (i.e., 3 cm towards the right!) and 12 cm towards the vertex.
%
% The ft_sourceanalysis methods are usually applied to the whole brain using a regular 3-D grid or using a triangulated cortical sheet. You can also just specify the location of a single or multiple points of interest with cfg.sourcemodel.pos and the LCMV beamformer will simply be performed at the location of interest.
%
% The LCMV beamformer spatial filter for the location of interest will pass the activity at that location with unit-gain, while optimally suppressing all other noise and other source contributions to the MEG data. The LCMV implementation in FieldTrip requires the data covariance matrix to be computed with ft_timelockanalysis.
%
% Rather than doing all the preprocessing again, you can download the preprocessed data from the FieldTrip ftp server (data.mat)
%
load data
%
%% compute the beamformer filter
cfg                   = [];
cfg.covariance        = 'yes';
cfg.channel           = 'MEG';
cfg.vartrllength      = 2;
cfg.covariancewindow  = 'all';
timelock              = ft_timelockanalysis(cfg, data);

cfg             = [];
cfg.method      = 'lcmv';
cfg.hdmfile     = 'SubjectCMC.hdm';
cfg.sourcemodel.pos = maxpos;
cfg.keepfilter  = 'yes';
source          = ft_sourceanalysis(cfg, timelock);
% The source reconstruction contains the estimated power and the source-level time-series of the averaged ERF, but here we are not interested in those. The cfg.keepfilter option results in the spatial filter being kept in the output source structure. That spatial can be used to reconstruct the single-trial time series as a virtual channel by multiplying it with the original MEG data.
%
%
% Extract the virtual channel time-series
%% construct the 3-D virtual channel at the location of interest
beamformer = source.avg.filter{1};

chansel = ft_channelselection('MEG', data.label); % find the names
chansel = match_str(data.label, chansel);         % find the indices

sourcedata = [];
sourcedata.label = {'x', 'y', 'z'};
sourcedata.time = data.time;
for i=1:length(data.trial)
  sourcedata.trial{i} = beamformer * data.trial{i}(chansel,:);
end
% The LCMV spatial filter is computed here without applying any time-domain filters. Consequently, it will have to suppress all noise in the data in all frequency bands. The spatial filter derived from the broadband data allows us to compute a broadband source level time-series.
% If you would know that the subsequent analysis would be limited to a specific frequency range in the data (e.g. everything above 30 Hz), you could first apply a filter using ft_preprocessing (e.g. cfg.hpfilter=yes and cfg.hpfreq=30) prior to computing the covariance and the spatial filter.
%
% The sourcedata structure resembles the raw-data output of ft_preprocessing and consequently can be used in any follow-up function. You can for example visualize the single-trial virtual channel time-series using ft_databrowser:
%
cfg = [];
cfg.viewmode = 'vertical';  % you can also specify 'butterfly'
ft_databrowser(cfg, sourcedata);

%
% Notice that the reconstruction contains three channels, for the x-, the y- and the z-component of the equivalent current dipole source at the location of interest.
%
%
% Project along the strongest dipole direction
% The interpretation of connectivity is facilitated if we can compute it between two plain channels rather than between one channel versus a triplet of channels. Therefore we will project the time-series along the dipole direction that explains most variance. This projection is equivalent to determining the largest (temporal) eigenvector and can be computationally performed using the singular value decomposition (svd).
%
%% construct a single virtual channel in the maximum power orientation
timeseries = cat(2, sourcedata.trial{:});

[u, s, v] = svd(timeseries, 'econ');

% whos u s v
%   Name           Size              Bytes  Class     Attributes
%
%   s              3x3                  72  double
%   u              3x3                  72  double
%   v         196800x3             4723200  double
% Matrix u contains the spatial decomposition, matrix v the temporal and on the diagonal of matrix s you can find the eigenvalues. See "help svd" for more details.
%
% We now recompute the virtual channel time-series, but now only for the dipole direction that has the most power.
%
% this is equal to the first column of matrix V, apart from the scaling with s(1,1)
timeseriesmaxproj = u(:,1)' * timeseries;
virtualchanneldata = [];
virtualchanneldata.label = {'cortex'};
virtualchanneldata.time = data.time;
for i=1:length(data.trial)
  virtualchanneldata.trial{i} = u(:,1)' * beamformer * data.trial{i}(chansel,:);
end
% Rather than using a sourcemodel in the beamformer that consists of all three (x, y, z) directions, you can also have the beamformer compute the filter for only the optimal source orientation. This is implemented using the cfg.lcmv.fixedori='yes' option.
% Recompute the spatial filter for the optimal source orientation and using that spatial filter (a 1151 vector) recompute the time-series.
%
% Investigate and describe the difference between the two time-series. What is the difference between the two dipole orientations?
%
% Note that one orientation is represented in the SVD matrix "u" and the other is in the source.avg.ori field.
%
%
% Combine the virtual channel with the EMG
% The raw data structure containing one (virtual) channel can be combined with the two EMG channels from the original preprocessed data.
%
%% select the two EMG channels
cfg = [];
cfg.channel = 'EMG';
emgdata = ft_selectdata(cfg, data);

%% combine the virtual channel with the two EMG channels
cfg = [];
combineddata = ft_appenddata(cfg, virtualchanneldata, emgdata);

% save combineddata combineddata
%
% Compute the connectivity
% The resulting combined data structure has three channels: the activity from the cortex, the left EMG and the right EMG. We can now continue with regular channel-level connectivity analysis.
%
%% compute the spectral decomposition
cfg            = [];
cfg.output     = 'fourier';
cfg.method     = 'mtmfft';
cfg.foilim     = [5 100];
cfg.tapsmofrq  = 5;
cfg.keeptrials = 'yes';
cfg.channel    = {'cortex' 'EMGlft' 'EMGrgt'};
freq    = ft_freqanalysis(cfg, combineddata);

cfg = [];
cfg.method = 'coh';
coherence = ft_connectivityanalysis(cfg, freq);
% This computes the spectral decomposition and the coherence spectrum between all channel pairs, which can be plotted with
%
cfg = [];
cfg.zlim = [0 0.2];
figure
ft_connectivityplot(cfg, coherence);
title('coherence')

%
% To look in more detail into the numerical representation of the coherence results, you can use
%
figure
plot(coherence.freq, squeeze(coherence.cohspctrm(1,2,:)))
title(sprintf('connectivity between %s and %s', coherence.label{1}, coherence.label{2}));
xlabel('freq (Hz)')
ylabel('coherence')

%
% The spectrum reveals coherence peaks at 10 and 20 Hz (remember that the initial DICS localizer was done at beta). Furthermore, there is a broader plateau of coherence in the gamma range from 40-50 Hz.
%
% The spectral decomposition was performed with mutitapering and 5 Hz spectral smoothing (i.e. 5Hz in both directions). Recompute the spectral decomposition and the coherence with a hanning taper. Recompute it with mutitapering and 10 Hz smoothing. Plot the three coherence spectra and look at the differences.
% Rather than looking at undirected coherence, the virtual channel level data can now also easily be submitted to directed connectivity measures. Compute the spectrally resolved granger connectivity and try to assess whether the directionality is from cortex to EMG or vice versa.
%
% Summary and further reading
% This tutorial demonstrates how to compute connectivity measures between two time series. If you want to learn how to make a distributed representation of connectivity throughout the whole brain, you may want to continue with the corticomuscular coherence tutorial.
%
% This tutorial was last tested by Robert with revision 6026 of FieldTrip (~20120611) on a 64-bit Mac OS X machine using MATLAB 2011b.


function G=doog2(sig,r,th,N);
% G=doog2(sig,r,th,N);
% Make difference of offset gaussians kernel
% theta is in degrees
% (see Malik & Perona, J. Opt. Soc. Amer., 1990)
%
% Example:
% >> imagesc(doog2(1,12,0,64,1))
% >> colormap(gray)
%
% Serge Belongie

no_pts=N;  % no. of points in x,y grid

[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2);

phi=pi*th/180;
sigy=sig;
sigx=r*sig;
R=[cos(phi) -sin(phi); sin(phi) cos(phi)];
C=R*diag([sigx,sigy])*R';

X=[x(:) y(:)];

Gb=gaussian(X,[0 0]',C);
Gb=reshape(Gb,N,N);

m=R*[0 sig]';
Ga=gaussian(X,m,C);
Ga=reshape(Ga,N,N);
Gc=rot90(Ga,2);

a=-1;
b=2;
c=-1;

G = a*Ga + b*Gb + c*Gc;


function sinogram = myRadon(image,thetas)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% radon transformation -> schlegel & bille 9.1.1
% written by Mark Bangert
% m.bangert@dkfz.de 2011

numOfAngularProjections  = length(thetas);
numOfParallelProjections = size(image,1);

sinogram = zeros(numOfParallelProjections,numOfAngularProjections);

% loop over the number of angles
for i = 1:length(thetas)

   % rotate image
   tmpImage      = imrotate(image,-thetas(i),'bilinear','crop');

   % fill sinogram
   sinogram(:,i) = sum(tmpImage,2);

   % visualization on the fly
   imagesc(sinogram);
   drawnow

end


function kern = gaussianKernParamInit(kern, isArd)

% GAUSSIANKERNPARAMINIT Gaussian kernel parameter initialisation.
% The gaussian kernel used here follows the shape of a gaussian
%	distribution
%
%	k(x_i, x_j) =  sigma2*exp(- 0.5*(x_i - x_j)'P(x_i - x_j))
%
%	In the above equation, P is the precision matrix and sigma2 is a variance factor. P is a diagonal matrix.
%
%  FORMAT
% DESC  initialises the gaussian
%	kernel structure with some default parameters.
% RETURN kern : the kernel structure with the default parameters placed in.
% ARG kern : the kernel structure which requires initialisation.
%
%
% SEEALSO : kernCreate, kernParamInit
%
% COPYRIGHT : Mauricio A. Alvarez and Neil D. Lawrence, 2008
%
% MODIFICATIONS : Mauricio A. Alvarez, 2009, 2010

% KERN

if kern.inputDimension == 0
   kern.inputDimension = 1;
end

if isfield(kern, 'options') && isfield(kern.options, 'isArd')
    kern.isArd = kern.options.isArd;
else
    switch nargin
        case 1
            kern.isArd = false;
        case 2
            kern.isArd = isArd;
    end
end
kern.sigma2Latent = 1;
if kern.isArd
    kern.precisionU   = ones(kern.inputDimension,1);
    kern.nParams = kern.inputDimension + 1;
else
    kern.precisionU   = 1;
    kern.nParams = 2;
end
% Constrains parameters positive for optimisation.
% The variances of P need to be positive and we constrain the sensitivity
% to be positive as well
kern.transforms.index =1:kern.nParams;
kern.transforms.type = optimiDefaultConstraint('positive');
kern.isStationary = true;


function [ pc_deg, pc ] = plymul2 ( add, mul, pa_deg, pa, pb_deg, pb )

%*****************************************************************************80
%
%% PLYMUL2 multiplies two polynomials in the field of order 2.
%
%  Discussion:
%
%    Polynomials stored as arrays have the coefficient of degree N in POLY(N+1).
%
%    A polynomial which is identically 0 is given degree -1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 March 2003
%
%  Author:
%
%    Original FORTRAN77 version by Paul Bratley, Bennett Fox, Harald Niederreiter.
%    MATLAB version by John Burkardt
%
%  Parameters:
%
%    Input, integer ADD(2,2), MUL(2,2), the addition and multiplication
%    tables, mod 2.
%
%    Input, integer PA_DEG, the degree of polynomial A.
%
%    Input, integer PA(PA_DEG+1), the coefficients of polynomial A.
%
%    Input, integer PB_DEG, the degree of polynomial B.
%
%    Input, integer PB(PB_DEG+1), the coefficients of polynomial B.
%
%    Output, integer PC_DEG, the degree of polynomial C.
%
%    Output, integer PC(PC_DEG+1), the product polynomial, C = A * B mod 2.
%
  if ( pa_deg == -1 | pb_deg == -1 )
    pc_deg = -1;
  else
    pc_deg = pa_deg + pb_deg;
  end

  for i = 0 : pc_deg
    term = 0;
    for j = max ( 0, i-pa_deg ) : min ( pb_deg, i )
      term = add ( term+1, mul ( pa(i-j+1)+1, pb(j+1)+1 ) + 1 );
    end
    pt(i+1) = term;
  end

  for i = 0 : pc_deg
    pc(i+1) = pt(i+1);
  end

  return
end


% demo script for regression with HKL
clear all

% fixing the seed of the random generators
seed=1;
randn('state',seed);
rand('state',seed);

% toy example characteristics
p = 1024;           % total number of variables (used to generate a Wishart distribution)
psub = 32;          % kept number of variables = dimension of the problem
n = 256;            % number of observations
s = 4;              % number of relevant variables
noise_std = .2;		% standard deviation of noise
proptrain = .5;     % proportion of data kept for training (the rest is used for testing)

% generate random covariance matrix from a Wishart distribution
Sigma_sqrt = randn(p,p);
Sigma = Sigma_sqrt' * Sigma_sqrt;

% normalize to unit trace and sample
diagonal = diag(Sigma);
Sigma = diag( 1./diagonal.^.5) * Sigma * diag( 1./diagonal.^.5);
Sigma_sqrt =   Sigma_sqrt * diag( 1./diagonal.^.5);
X = randn(n,p) * Sigma_sqrt;

X = X(:,1:psub);
p=psub;

% generate nonlinear function of X as the sum of all cross-products
J =  1:s;    % select the first s variables
Y = zeros(n,1);
for i=1:s
	for j=1:i-1
		Y = Y + X(:,J(i)) .* X(:,J(j));
	end
end
% normalize to unit standard deviation
Y = Y / std(Y);

% add some noise with known standard deviation
Y =  Y + randn(n,1) * noise_std;

% split data in two groups
ntrain = round(n*proptrain);
ntest = n - ntrain;
rp = randperm(n);
trainset = rp(1:ntrain);
testset  = rp(ntrain+1:end);

% select some regularization parameterst lambdas (from large to small)
lambdas = 10.^[2:-.5:-8];

% HKL with hermite polynomial decomposition
[outputs,model,accuracies,accuracies_kfold,bestlambda_same] = hkl_kfold(10,'same',X(trainset,:),Y(trainset),lambdas,'square','hermite',[ .5 3 .1 4 ],...
	'Xtest',X(testset,:),'Ytest',Y(testset),'maxactive',300,'memory_cache',2e9,'display',0);

estimated_best_error_same = accuracies.testing_error(bestlambda_same)
best_error_same = min(accuracies.testing_error)

[outputs,model,accuracies,accuracies_kfold,bestlambda_scaled] = hkl_kfold(10,'scaled',X(trainset,:),Y(trainset),lambdas,'square','hermite',[ .5 3 .1 4 ],...
	'Xtest',X(testset,:),'Ytest',Y(testset),'maxactive',300,'memory_cache',2e9,'display',0);

estimated_best_error_scaled = accuracies.testing_error(bestlambda_scaled)
estimated_best_error_overfit = min(accuracies.testing_error)


function K = covPeriodic(hyp, x, z, i)

% Stationary covariance function for a smooth periodic function, with period p
% in 1d (see covPERiso and covPERard for multivariate data):
%
% k(x,z) = sf^2 * exp( -2*sin^2( pi*||x-z||/p )/ell^2 )
%
% where the hyperparameters are:
%
% hyp = [ log(ell)
%         log(p)
%         log(sf) ]
%
% Copyright (c) by Carl Edward Rasmussen and Hannes Nickisch, 2011-01-05.
%
% See also COVFUNCTIONS.M.

if nargin<2, K = '3'; return; end                  % report number of parameters
if nargin<3, z = []; end                                   % make sure, z exists
xeqz = isempty(z); dg = strcmp(z,'diag');                       % determine mode

[n,D] = size(x);
if D>1, error('Covariance is defined for 1d data only.'), end
ell = exp(hyp(1));
p   = exp(hyp(2));
sf2 = exp(2*hyp(3));

% precompute distances
if dg                                                               % vector kxx
  K = zeros(size(x,1),1);
else
  if xeqz                                                 % symmetric matrix Kxx
    K = sqrt(sq_dist(x'));
  else                                                   % cross covariances Kxz
    K = sqrt(sq_dist(x',z'));
  end
end

K = pi*K/p;
if nargin<4                                                        % covariances
    K = sin(K)/ell; K = K.*K; K =   sf2*exp(-2*K);
else                                                               % derivatives
  if i==1
    K = sin(K)/ell; K = K.*K; K = 4*sf2*exp(-2*K).*K;
  elseif i==2
    R = sin(K)/ell; K = 4*sf2/ell*exp(-2*R.*R).*R.*cos(K).*K;
  elseif i==3
    K = sin(K)/ell; K = K.*K; K = 2*sf2*exp(-2*K);
  else
    error('Unknown hyperparameter')
  end
end


function [MHz] = radps2MHz(radps)
% Convert frequency from radians per second to megahertz.
% Chad A. Greene 2012
MHz = radps/(2*pi)/1000000;


function l = invgammaPriorLogProb(prior, x)

% INVGAMMAPRIORLOGPROB Log probability of inverse gamma prior.

% PRIOR

% PRIOR

% Compute log prior
D = length(x);
l = D*prior.a*log(prior.b)-D*gammaln(prior.a)-(prior.a+1)*sum(log(x))-prior.b*sum(1./x);


function [af, sf] = farras

% Farras nearly symmetric filters for orthogonal
% 2-channel perfect reconstruction filter bank
%
% USAGE:
%    [af, sf] = farras
% OUTPUT:
%    af - analysis filters
%    sf - synthesis filters
% REFERENCE:
%    A. F. Abdelnour and I. W. Selesnick.
%    "Nearly symmetric orthogonal wavelet bases",
%    Proc. IEEE Int. Conf. Acoust., Speech,
%    Signal Processing (ICASSP), May 2001.
% See afb, dwt.
%
% WAVELET SOFTWARE AT POLYTECHNIC UNIVERSITY, BROOKLYN, NY
% http://taco.poly.edu/WaveletSoftware/

af = [
                  0  -0.01122679215254
                  0   0.01122679215254
  -0.08838834764832   0.08838834764832
   0.08838834764832   0.08838834764832
   0.69587998903400  -0.69587998903400
   0.69587998903400   0.69587998903400
   0.08838834764832  -0.08838834764832
  -0.08838834764832  -0.08838834764832
   0.01122679215254                  0
   0.01122679215254                  0
];

sf = af(end:-1:1, :);


function [ h ] = plot_q_mountain_car(Q)
%PLOT_Q_MOUNTAIN_CAR Summary of this function goes here
%   Detailed explanation goes here

% (N x 2)
s     = BuildStateList();
[v,I] = max(Q,[],2);

vs = -v;

xs      = linspace(-1.5,0.6,100);
ys      = linspace(-0.07,0.07,100);
[xi,yi] = meshgrid(xs,ys);

% Q (N x 2)

h = figure; hold on;
subplot(2,2,1);
zi = griddata(s(:,1),s(:,2),vs,xi,yi);
surf(xi,yi,zi); shading interp;
view(2);
title('Mountain car -max_u Q(x,u)');
xlabel('Position');
ylabel('Velocity');
colorbar;
ca = caxis;
xlim([-1.5,0.6]);
ylim([-0.07,0.07]);
axis square;
box on;

subplot(2,2,2);
plot_policy_moutain_car(Q);
xlim([-1.5,0.6]);
ylim([-0.07,0.07]);

subplot(2,2,3);
zi = griddata(s(:,1),s(:,2),-Q(:,1),xi,yi);
surf(xi,yi,zi); shading interp;
view(2);
title('-Q(x,-1)');
xlabel('Position');
ylabel('Velocity');
colorbar;
caxis(ca);
xlim([-1.5,0.6]);
ylim([-0.07,0.07]);
axis square;
box on;

subplot(2,2,4);
zi = griddata(s(:,1),s(:,2),-Q(:,2),xi,yi);
surf(xi,yi,zi); shading interp;
view(2);
title('-Q(x,1)');
xlabel('Position');
ylabel('Velocity');
colorbar;
caxis(ca);
xlim([-1.5,0.6]);
ylim([-0.07,0.07]);
axis square;
box on;

end


function D = compute_pairwise_distance(X, Y)
    % efficient implementation taken from homework assignment 7
    if( ~isa(X,'double') || ~isa(Y,'double'))
        error( 'Inputs must be of type double'); end;
    m = size(X,1); n = size(Y,1);
    Yt = Y';
    XX = sum(X.*X,2);
    YY = sum(Yt.*Yt,1);
    D = XX(:,ones(1,n)) + YY(ones(1,m),:) - 2*X*Yt;
end


function gammaAB = diffCoherence(k, r_A, r_B, a_nm, b_nm, G_mtx)
%DIFFCOHERENCE Computes diffuse field coherence of two directional patterns
%
%   Does that. For more details see
%
%       Politis, A., 2016.
%       Diffuse-field coherence of sensors with arbitrary directional responses. arXiv preprint arXiv:1608.07713.
%
%   Inputs:
%       k:  vector of wavenumbers to compute coherence at
%       r_A:    [x y z] vector of location of first sensor/beamformer
%       r_B:    [x y z] vector of location of second sensor/beamformer
%       a_nm:   SHD beamweights of the first directional pattern
%       b_nm:   SHD beamweights of the second directional pattern
%       G_mtx:  (optional) pre-computed matrix of Gaunt coefficients used
%           in the derivation. If not passed then they are computed here,
%           but that can be very slow for high orders.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DIFFCOHERENCE.M - 7/06/2015
% Archontis Politis, archontis.politis@aalto.fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% get the vector connecting the two patterns
r_AB = r_B-r_A;
[phi_r, elev_r, d] = cart2sph(r_AB(1),r_AB(2),r_AB(3));
theta_r = pi/2-elev_r;

orderA = sqrt(length(a_nm)) -1;
orderB = sqrt(length(b_nm)) -1;
orderC = orderA+orderB;
minOrder = min(orderA, orderB);

% convert second pattern to its conjugate for coherence between complex
% patterns (doesn't do anything if the patterns are real)
b_nm = conjCoeffs(b_nm);

% denominator of the coherence function
denAB = sqrt((a_nm'*a_nm) * (b_nm'*b_nm));

if d==0
    % numerator of the coherence function
    numAB = dot(a_nm(1:(minOrder+1)^2), b_nm(1:(minOrder+1)^2));
    numAB = numAB*ones(size(k));

else
    % get coefficients of the product function
    if nargin<6
        c_nm = sphMultiplication(a_nm, b_nm);
    else
        c_nm = sphMultiplication(a_nm, b_nm, G_mtx);
    end

    % numerator of the coherence function
    y_nm_r = getSH(orderC, [phi_r theta_r], 'complex')';
    kd = k*d;
    imag_n = 1i.^(0:orderC).';
    bessel_n = zeros(orderC+1,length(kd));
    for no=0:orderC, bessel_n(no+1,:) = sph_besselj(no, kd).'; end
    imag_bessel_n = (imag_n*ones(1,length(kd))).*bessel_n;
    imag_bessel_nm = replicatePerOrder(imag_bessel_n);
    planewave_nm = 4*pi*(y_nm_r*ones(1,length(kd))).*imag_bessel_nm;
    numAB = zeros(size(k));
    for kk=1:length(kd)
        numAB(kk) = planewave_nm(:,kk)' * c_nm;
    end
end

% coherence
gammaAB = numAB/denAB;

end


function [ fe, next, ierr ] = chfev ( x1, x2, f1, f2, d1, d2, ne, xe )

%*****************************************************************************80
%
%% CHFEV evaluates a cubic polynomial given in Hermite form.
%
%  Discussion:
%
%    This routine evaluates a cubic polynomial given in Hermite form at an
%    array of points.  While designed for use by SPLINE_PCHIP_VAL, it may
%    be useful directly as an evaluator for a piecewise cubic
%    Hermite function in applications, such as graphing, where
%    the interval is known in advance.
%
%    The cubic polynomial is determined by function values
%    F1, F2 and derivatives D1, D2 on the interval [X1,X2].
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 August 2005
%
%  Author:
%
%    Original FORTRAN77 version by Fred Fritsch.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Fred Fritsch, Ralph Carlson,
%    Monotone Piecewise Cubic Interpolation,
%    SIAM Journal on Numerical Analysis,
%    Volume 17, Number 2, April 1980, pages 238-246.
%
%    David Kahaner, Cleve Moler, Steven Nash,
%    Numerical Methods and Software,
%    Prentice Hall, 1988.
%
%  Parameters:
%
%    Input, real X1, X2, the endpoints of the interval of
%    definition of the cubic.  X1 and X2 must be distinct.
%
%    Input, real F1, F2, the values of the function at X1 and
%    X2, respectively.
%
%    Input, real D1, D2, the derivative values at X1 and
%    X2, respectively.
%
%    Input, integer NE, the number of evaluation points.
%
%    Input, real XE(NE), the points at which the function is to
%    be evaluated.  If any of the XE are outside the interval
%    [X1,X2], a warning error is returned in NEXT.
%
%    Output, real FE(NE), the value of the cubic function
%    at the points XE.
%
%    Output, integer NEXT(2), indicates the number of extrapolation points:
%    NEXT(1) = number of evaluation points to the left of interval.
%    NEXT(2) = number of evaluation points to the right of interval.
%
%    Output, integer IERR, error flag.
%    0, no errors.
%    -1, NE < 1.
%    -2, X1 == X2.
%
  if ( ne < 1 )
    ierr = -1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CHFEV - Fatal error!\n' );
    fprintf ( 1, '  Number of evaluation points is less than 1.\n' );
    fprintf ( 1, '  NE = %d\n', ne );
    error ( 'CHFEV - Fatal error!' )
  end

  h = x2 - x1;

  if ( h == 0.0 )
    ierr = -2;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CHFEV - Fatal error!\n' );
    fprintf ( 1, '  The interval [X1,X2] is of zero length.\n' );
    error ( 'CHFEV - Fatal error!' )
  end
%
%  Initialize.
%
  ierr = 0;
  next(1) = 0;
  next(2) = 0;
  xmi = min ( 0.0, h );
  xma = max ( 0.0, h );
%
%  Compute cubic coefficients expanded about X1.
%
  delta = ( f2 - f1 ) / h;
  del1 = ( d1 - delta ) / h;
  del2 = ( d2 - delta ) / h;
  c2 = -( del1 + del1 + del2 );
  c3 = ( del1 + del2 ) / h;
%
%  Evaluation loop.
%
  for i = 1 : ne

    x = xe(i) - x1;
    fe(i) = f1 + x * ( d1 + x * ( c2 + x * c3 ) );
%
%  Count the extrapolation points.
%
    if ( x < xmi )
      next(1) = next(1) + 1
    end

    if ( xma < x )
      next(2) = next(2) + 1
    end

  end

  return
end


function [W, b] = initializeOneLayerParams(layerSize, inputSize)
%% Initialize Parameters Randomly Based on Layer Sizes
r  = sqrt(6) / sqrt(layerSize+inputSize+1);
W = rand(layerSize, inputSize) * 2 * r - r;
b = zeros(layerSize, 1);
end


function pass = test_div( )
% Test divergence

tol = 1e2*chebfunpref().cheb2Prefs.chebfun2eps;

% Check divergence of an empty diskfunv is an empty diskfun.
u = diskfunv;
f = div(u);
pass(1) = isempty(f) & isa(f,'diskfun');

% Check definition:
F = diskfunv(@(x,y) cos(x), @(x,y) sin(y));
divF = diff(F(1), 1,1) + diff(F(2), 2, 1);
pass(2) = ( norm(divF - divergence(F) ) < tol );

% Check divergence of the zero field is zero
f = diskfun(@(x,y) 0*x);
u = diskfunv(f,f);
pass(3) = norm(div(u)) < tol;

% Check divergence of gradient is laplacian:
f = diskfun(@(x,y) cos(x.*y));
pass(4) = ( norm(laplacian( f ) - divergence( gradient( f ) ) ) < tol );

% Check that the div and divergence give the same result.
divergenceu = divergence(u);
divu = div(u);
pass(5) = isequal(divu,divergenceu);

end