function out=add_circular_mask(in,th,norm)
if nargin < 3
norm=0;
end

	thickness=4;
	[N,M]=size(in);
	[ix,iy]=meshgrid([-N/2+1/2:N/2-1/2],[-N/2+1/2:N/2-1/2]);
	rad=ix.^2+iy.^2;
	mask=max(0,thickness-abs(sqrt(rad)-(th*N/2)));
	outermask=(rad < (th*N/2)^2);
	if norm==0
	out=in.*outermask+min(0,min(in(:)))*(1-outermask);
	mask=mask*(max(64,0*max(out(:)))/max(mask(:)));
	else
	out=in.*outermask+min(in(:))*(1-outermask);
	mask=mask*((max(out(:)))/max(mask(:)));
	end
	tope=max(out(:));
	%out=min(tope,out+mask);
	out=(mask/tope).*mask+(1-mask/tope).*out;

if 0
	cjet=colormap(gray);
	cjet=1-cjet;
	inr=in(:);
	if norm==1
	inr=(inr-min(inr))*(55/(max(inr)-min(inr)));
	end
	tempo=cjet(max(1,min(64,round(inr))),:);
	out=reshape(tempo,N,M,3);
	mtempo(:,:,1)=outermask;
	mtempo(:,:,2)=outermask;
	mtempo(:,:,3)=outermask;
	out=out.*mtempo+ (1-mtempo);
end

end


function doublePendulumAnimate(sol,P)

%This function is used to run an animation of the double pendulum:

duration = sol.x(end) - sol.x(1);

tic;  %Start a timer
timeNow = 0;

h = gcf;

len = P.l1+P.l2;
axisVec = [-len,len,-len,len];

s1 = sqrt(P.m1);
s2 = sqrt(P.m2);
sMin = min(s1,s2);
s1 = s1/sMin;
s2 = s2/sMin;

while timeNow < duration

    zNow = deval(sol,timeNow);
    [p1,p2,g1,g2] = doublePendulumPosition(zNow,P);

    figure(h);
    plotFrame(timeNow,p1,p2,g1,g2,s1,s2);
    axis(axisVec); axis square; axis off;
    drawnow;

    pause(0.001);
    timeNow = toc;
end

end

function plotFrame(time,p1,p2,g1,g2,s1,s2)

linkOneX = [0;p1(1)];
linkOneY = [0;p1(2)];

linkTwoX = [p1(1);p2(1)];
linkTwoY = [p1(2);p2(2)];

clf;
hold on;

plot(0,0,'ks','MarkerSize',20,'LineWidth',3);

plot(linkOneX,linkOneY,'r-','LineWidth',6);
plot(linkTwoX,linkTwoY,'b-','LineWidth',6);

plot(0,0,'k.','MarkerSize',25);
plot(p1(1),p1(2),'k.','MarkerSize',25);
plot(p2(1),p2(2),'k.','MarkerSize',25);

plot(g1(1),g1(2),'ko','MarkerSize',round(15*s1),'LineWidth', 3);
plot(g2(1),g2(2),'ko','MarkerSize',round(15*s2),'LineWidth', 3);
plot(g1(1),g1(2),'kx','MarkerSize',round(15*s1),'LineWidth', 3);
plot(g2(1),g2(2),'kx','MarkerSize',round(15*s2),'LineWidth', 3);

title(sprintf('Time: %4.3f',time));

end


function [cs,h]=m_contour(long,lat,data,varargin)
%  M_CONTOUR Draws contour lines on a map
%    M_CONTOUR(LONG,LAT,DATA,...) draw contours on a map. Behavior
%    is the same as for CONTOUR except that LONG and LAT vectors or
%    matrices must be specified.
%
%    [CS,H]=M_CONTOUR(...) returns a contour matrix C and a vector
%    H of handles to LINE or PATCH objects for use by CLABEL.
%
%    See also CONTOUR

% Rich Pawlowicz (rich@ocgy.ubc.ca) 17/Jan/1998
%
% This software is provided "as is" without warranty of any kind. But
% it's mine, so you can't sell it.

% 9/Dec/98 - made sure bad things don't happen if all your lat/long
%            points are out of the plot region.
% 6/Nov/00 - eliminate returned stuff if ';' neglected (thx to D Byrne)

global MAP_PROJECTION

% Have to have initialized a map first

if isempty(MAP_PROJECTION)
  disp('No Map Projection initialized - call M_PROJ first!');
  return;
end

if min(size(long))==1 && min(size(lat))==1
 [long,lat]=meshgrid(long,lat);
end

[X,Y]=m_ll2xy(long,lat,'clip','on');

i=isnan(X);      % For these we set the *data* to NaN...
data(i)=NaN;

                 % And then recompute positions without clipping. THis
                 % is necessary otherwise contouring fails (X/Y with NaN
                 % is a no-no.
if any(i(:)), [X,Y]=m_ll2xy(long,lat,'clip','off'); end

if any(~i(:))
 [cs,h]=contour(X,Y,data,varargin{:});
 set(h,'tag','m_contour');
else
  cs=[];h=[];
end

if nargout==0
 clear cs h
end


function [tg] = tgso2(tmap,ntex,radius,theta,varargin)
% function [tg] = tgso2(tmap,ntex,radius,theta,...)
%
% Compute the texture gradient at a single orientation and scale.
%
% INPUT
%	tmap		Texton map, values in [1,ntex].
%	ntex		Number of textons.
%	radius		Radius of disc for tg.
%	theta		Orientation orthogonal to tg.
%	'smooth'	Smoothing method, one of
%			{'gaussian','savgol','none'}, default 'none'.
%	'sigma'		Sigma for smoothing, default to radius.
%	'tsim'		Texton similarity matrix.  If not
%			provided, then use chi-squared.
%
% OUTPUT
%	tg		The tg image.
%
% David R. Martin <dmartin@eecs.berkeley.edu>
% March 2003

% process options
smooth = 'none';
sigma = radius;
usechi2 = true;
for i = 1:2:numel(varargin),
  opt = varargin{i};
  if ~ischar(opt), error('option names not a string'); end
  if i==numel(varargin), error(sprintf('option ''%s'' has no value',opt)); end
  val = varargin{i+1};
  switch opt,
   case 'smooth',
    switch val,
     case {'none','gaussian','savgol'}, smooth=val;
     otherwise, error(sprintf('invalid option smooth=''%s''',val));
    end
   case 'sigma', sigma=val;
   case 'tsim', tsim=val; usechi2=false;
   otherwise, error(sprintf('invalid option ''%s''',opt));
  end
end

radius = max(1,radius);
theta = mod(theta,pi);

% check texton labels
if any(tmap~=round(tmap)),
  error('texton labels not integral');
end
if min(tmap(:)) < 1 | max(tmap(:))>ntex,
  error(sprintf('texton labels out of range [1,%d]',ntex));
end

% radius of discrete disc
wr = floor(radius);

% count number of pixels in a disc
[u,v] = meshgrid(-wr:wr,-wr:wr);
gamma = atan2(v,u);
mask = (u.^2 + v.^2 <= radius^2);
mask(wr+1,wr+1) = 0; % mask out center pixel to remove bias
count = sum(mask(:));

% determine which half of the disc pixels fall in
% (0=masked 1=left 2=right)
side = 1 + (mod(gamma-theta,2*pi) < pi);
side = side .* mask;
if sum(sum(side==1)) ~= sum(sum(side==2)), error('bug:inbalance'); end

[h,w] = size(tmap);
tg = zeros(h,w);
fwrite(2,'[');
for x = 1:w,
  fwrite(2,'.');
  for y = 1:h,
    hist = zeros(ntex,2);
    for u = -wr:wr,
      xi = x + u;
      if xi<1 | xi>w, continue; end
      for v = -wr:wr,
        yi = y + v;
        if yi<1 | yi>h, continue; end
        s = side(v+wr+1,u+wr+1);
        if s==0, continue; end % masked out
        t = tmap(yi,xi);
        hist(t,s) = hist(t,s) + 1;
      end
    end
    hist = hist .* (2/count); % normalize
    if usechi2,
      chi = (hist(:,1)-hist(:,2)).^2 ./ (hist(:,1)+hist(:,2)+eps);
      tg(y,x) = 0.5*sum(chi);
    else
      lrdiff = abs(hist(:,1)-hist(:,2));
      tg(y,x) = lrdiff' * tsim * lrdiff;
    end
  end
end
fprintf(2,']\n');

switch smooth,
 case 'gaussian',
  f = oeFilter([sigma .5],3,theta+pi/2);
  tg = applyFilter(f,tg);
 case 'savgol',
  a = fitparab(tg,sigma,sigma/4,theta);
  tg = max(0,a);
end


classdef prtPreProcElm < prtPreProc
    %prtPreProcElm - Extreme Learning Machine
    %   A 1 Hidden Layer Neural Network with Random Weights
    %
    % Example:
    %    dsTrain = prtDataGenXor;
    %    dsTest = prtDataGenXor;
    %    algo = prtPreProcElm('nNeurons',1000) + prtClassLr;
    %    algo = algo.train(dsTrain);
    %    yOut = algo.run(dsTest);
    %    close all;
    %    prtScoreRoc(yOut);

    properties (SetAccess=private)
        name = 'Extreme Learning Machine'
        nameAbbreviation = 'ELM'
    end

    properties (SetAccess = protected)

    end

    properties
        nNeurons = 100;
        activationFunction = @(x)1./(1 + exp(-x));

        weights = [];
        bias = []
    end

    methods

               % Allow for string, value pairs
        function self = prtPreProcElm(varargin)
            self = prtUtilAssignStringValuePairs(self,varargin{:});
        end
    end

    methods (Access=protected, Hidden = true)

        function self = trainAction(self,dataSet)
            self.weights = rand(dataSet.nFeatures, self.nNeurons)*2 - 1;
            self.bias = rand(1,self.nNeurons);
        end

        function dataSet = runAction(self,dataSet)
           dataSet.X = self.activationFunction(bsxfun(@plus, dataSet.X*self.weights, self.bias));
        end
    end
end


function c=comp_uwpfbt(f,wtNodes,rangeLoc,nodesUps,scaling,interscaling)
%COMP_UWPFBT Compute Undecimated Wavelet Packet Filterbank Tree
%   Usage:  c=comp_uwpfbt(f,wtNodes,nodesUps);
%
%   Input parameters:
%         f        : Input data as L*W array.
%         wtNodes  : Filterbank tree nodes (elementary filterbanks) in
%                    BF order. Cell array of structures of length *nodeNo*.
%         nodesUps : Filters upsampling factor of each node. Array of
%                    length *nodeNo*.
%
%   Output parameters:
%         c        : Coefficients stored in L*M*W array.
%

% Pre-allocated output
[L, W] = size(f);
M = sum(cellfun(@(wtEl) numel(wtEl.h),wtNodes));
c = zeros(L,M,W,assert_classname(f,wtNodes{1}.h{1}.h));

% Convenience input reshape
ca = reshape(f,size(f,1),1,size(f,2));
cOutRunIdx = 1;
cInRunIdxs = [1];

interscalingfac = 1;
if strcmp('intscale',interscaling)
    interscalingfac = 1/2;
elseif strcmp('intsqrt',interscaling)
    interscalingfac = 1/sqrt(2);
end

% For each node in tree in the BF order...
for jj=1:numel(wtNodes)
   % Node filters subs. factors
   a = wtNodes{jj}.a;

   % Optionally scale the filters
   h = comp_filterbankscale(wtNodes{jj}.h(:),a(:),scaling);

   % Node filters to a matrix
   % hMat = cell2mat(cellfun(@(hEl) conj(flipud(hEl.h(:))),h','UniformOutput',0));
   hMat = cell2mat(cellfun(@(hEl) hEl.h(:),h','UniformOutput',0));

   % Node filters initial skips
   % hOffet = cellfun(@(hEl) 1-numel(hEl.h)-hEl.offset,wtNodes{jj}.h);
   hOffet = cellfun(@(hEl) hEl.offset, wtNodes{jj}.h);
   % Number of filters of the current node
   filtNo = size(hMat,2);
   % Zero index position of the upsampled filters.
   offset = nodesUps(jj).*(hOffet);

   % Run filterbank
   c(:,cOutRunIdx:cOutRunIdx + filtNo-1,:)=...
      comp_atrousfilterbank_td(squeeze(ca(:,1,:)),hMat,nodesUps(jj),offset);

   % Bookkeeping
   outRange = cOutRunIdx:cOutRunIdx+filtNo-1;
   outRange(rangeLoc{jj}) = [];
   cInRunIdxs = [cInRunIdxs(2:end),outRange];

   cOutRunIdx = cOutRunIdx + filtNo;

   % Prepare input for the next iteration
   if ~isempty(cInRunIdxs)
      c(:,cInRunIdxs(1),:) = c(:,cInRunIdxs(1),:)*interscalingfac;
      ca = c(:,cInRunIdxs(1),:);
   end
end


function [node,face,elem]=meshabox(p0,p1,opt,nodesize)
%
% [node,face,elem]=meshabox(p0,p1,opt,maxvol)
%
% create the surface and tetrahedral mesh of a box geometry
%
% author: Qianqian Fang, <fangq at nmr.mgh.harvard.edu>
%
% input:
%   p0:  coordinates (x,y,z) for one end of the box diagnoal
%   p1:  coordinates (x,y,z) for the other end of the box diagnoal
%   opt: maximum volume of the tetrahedral elements
%   nodesize: 1 or a 8x1 array, size of the element near each vertex
%
% output:
%   node: node coordinates, 3 columns for x, y and z respectively
%   face: integer array with dimensions of NB x 3, each row represents
%         a surface mesh face element
%   elem: integer array with dimensions of NE x 4, each row represents
%         a tetrahedron
%
% example:
%   [node,face,elem]=meshabox([2 3 2],[6 12 15],0.1,1);
%   plotmesh(node,elem,'x>4');
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

if(nargin<4)
   nodesize=1;
end
[node,elem,face]=surf2mesh([],[],p0,p1,1,opt,[],[],nodesize);
elem=elem(:,1:4);
face=face(:,1:3);


function [f] = spm_cost_SHC_fx(x,v,P)
% equations of motion for foraging problem using SHCs
% problem
% FORMAT [f] = spm_cost_SHC_fx(x,v,P)
%
% x   - hidden states (x.x, x.v x.q and x.a)
% v   - exogenous inputs
% P   - parameters
%
% The parameters associate increases in some physiological states x.q with
% positions in physical space, encoded by radial basis functions x.a
%__________________________________________________________________________
% Copyright (C) 2010 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_cost_SHC_fx.m 3757 2010-03-08 11:41:53Z guillaume $

% location and radius of attractors A
%--------------------------------------------------------------------------
global A; X   = A.x;

% gradient of Hamiltonian (G) is determined by the attractor state x.a
%--------------------------------------------------------------------------
[m,i] = max(x.a);
G     = x.x - X(:,i);

% motion of physical states
%--------------------------------------------------------------------------
f   = x;
f.x = x.v;
f.v = -G*8 - x.v*4;

% motion of physiological states (using basis functions of position)
%--------------------------------------------------------------------------
for i = 1:size(X,2)
    b(i,1) = norm(x.x - X(:,i)) < A.d;
end

f.q = P'*b - x.q/2;
f.a = P*(x.q < A.u) - b*4 - sum(x.a);

% flow
%--------------------------------------------------------------------------
dt  = 1/8;
f.x = f.x*dt;
f.v = f.v*dt;
f.q = f.q*dt;
f.a = f.a*dt;


function F = airy(K, F, scale, pref)
%AIRY   Airy function of a CHEBFUN.
%   AIRY(F) returns the Airy function Ai(F) of a CHEBFUN F.
%
%   AIRY(K, F) returns various Airy functions specified by K:
%     0 - (default) is the same as airy(Z)
%     1 - returns the derivative, Ai'(Z)
%     2 - returns the Airy function of the second kind, Bi(Z)
%     3 - returns the derivative, Bi'(Z)
%
%   AIRY(K, F, SCALE) returns a scaled AIRY(K, F) specified by SCALE:
%     0 - (default) is that same as AIRY(K, Z)
%     1 - returns airy(K, F) scaled by EXP(2/3*F.^(3/2)) for K = 0, 1,
%         and scaled by EXP(-ABS(2/3.*REAL(F.^(3/2)))) for K = 2, 3.
%
% See also BESSELJ.

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

% Parse the inputs as described in help text:
if ( nargin == 1 )
    F = K;
    K = 0;
    pref = chebfunpref();
end
if ( nargin < 3 )
    scale = 0;
    pref = chebfunpref();
end
if ( nargin == 3 )
    if ( isa(scale, 'chebfunpref') )
        pref = scale;
        scale = 0;
    else
        pref = chebfunpref;
    end
end

for k = 1:numel(F)
    F(k) = columnAiry(K, F(k), scale, pref);
end

end

function g = columnAiry(K, f, scale, pref)

% The standard Airy function:
g = compose(f, @(x) airy(K, x), [], pref);

if ( scale == 0 )
    % Standard case (no scaling).

elseif ( (scale == 1) && ((K == 0) || (K == 1)) )
    % Scaled with k = 1, 2:
    scl = exp(2/3*f.^(3/2));
    g = scl.*g;

elseif ( (scale == 1) && ((K == 2) || (K == 3)) )
    % Scaled with k = 2, 3:
    scl = exp(-abs(2/3*real(f.^(3/2))));
    g = scl.*g;

else
    % Invalid parameter sequence:
    error('CHEBFUN:CHEBFUN:airy:params', 'Invalid paramter selection.');

end

end


function S1 = my_conv2(S1, sig, varargin)
% takes an extra argument which specifies which dimension to filter on
% extra argument can be a vector with all dimensions that need to be
% smoothed, in which case sig can also be a vector of different smoothing
% constants

if sig>.25
    idims = 2;
    if ~isempty(varargin)
        idims = varargin{1};
    end
    if numel(idims)>1 && numel(sig)>1
        sigall = sig;
    else
        sigall = repmat(sig, numel(idims), 1);
    end

    for i = 1:length(idims)
        sig = sigall(i);

        idim = idims(i);
        Nd = ndims(S1);

        S1 = permute(S1, [idim 1:idim-1 idim+1:Nd]);

        S1 = my_conv(S1, sig);
%         dsnew = size(S1);
%
%         S1 = reshape(S1, size(S1,1), []);
%         dsnew2 = size(S1);
%
%         tmax = ceil(4*sig);
%         dt = -tmax:1:tmax;
%         gaus = exp( - dt.^2/(2*sig^2));
%         gaus = gaus'/sum(gaus);
%
%         cNorm = filter(gaus, 1, cat(1, ones(dsnew2(1), 1), zeros(tmax,1)));
%         cNorm = cNorm(1+tmax:end, :);
%
%         S1 = filter(gaus, 1, cat(1, S1, zeros([tmax, dsnew2(2)])));
%         S1(1:tmax, :) = [];
%         S1 = reshape(S1, dsnew);
%
%         S1 = bsxfun(@rdivide, S1, cNorm);

        S1 = permute(S1, [2:idim 1 idim+1:Nd]);
    end
end


function L = laplacian(f)
%LAPLACIAN   Laplacian of a SEPARABLEAPPROX.
%   L = LAPLACIAN(F) returns a SEPARABLEAPPROX representing the Laplacian of F.
%
% See also SEPARABLEAPPROX/LAP.

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

% laplacian(f) = f_xx + f_yy:
L = diff(f, 2, 2) + diff(f, 2, 1);

end


function x = one_null_right ( m, n )

%*****************************************************************************80
%
%% ONE_NULL_RIGHT returns a right null vector of the ONE matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the order of the matrix.
%
%    Output, real X(N,1), the null vector.
%
  if ( n == 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'ONE_NULL_RIGHT - Fatal error!\n' );
    fprintf ( 1, '  Matrix is nonsingular for N = 1.\n' );
    error ( 'ONE_NULL_RIGHT - Fatal error!' );
  end

  x = zeros ( n, 1 );

  x(1) =     1.0;
  x(n) =    -1.0;

  return
end


function [ap, prec, rec] = ml_ap(confidence, gt, draw)
% function [ap, prec, rec] = ml_ap(confidence, gt, draw)
% Average precision, adapted from VOCevaluation
% gt: a vector of 1 and -1. 1 is for positive, -1 is for negative.
% confidence: confidence for belonging to the positive class
% By: Minh Hoai Nguyen (minhhoai@robots.ox.ac.uk)
% Last modified: 23-Nov-2012

    if length(confidence) ~= length(gt)
        error('mismatch');
    end;
    confidence = confidence(:);
    gt = gt(:);
    [~,si]=sort(confidence, 'descend');
    tp=gt(si)>0;
    fp=gt(si)<0;

    fp=cumsum(fp);
    tp=cumsum(tp);
    rec=tp/sum(gt>0);
    prec=tp./(fp+tp);
    ap=VOCap(rec,prec);

    if draw
        % plot precision/recall
        plot(rec,prec,'-');
        grid;
        xlabel 'recall'
        ylabel 'precision'
    end

function ap = VOCap(rec,prec)
    mrec=[0 ; rec ; 1];
    mpre=[0 ; prec ; 0];
    for i=numel(mpre)-1:-1:1
        mpre(i)=max(mpre(i),mpre(i+1));
    end
    i=find(mrec(2:end)~=mrec(1:end-1))+1;
    ap=sum((mrec(i)-mrec(i-1)).*mpre(i));


% Implementation of the multiple extended object tracking algorithm based on the article
%
% "Linear-Time Joint Probabilistic Data Association for Multiple Extended Object Tracking (to appear)"
% S. Yang, K. Thormann, and M. Baum
% 2018 IEEE Sensor Array and Multichannel Signal Processing Workshop (SAM 2018), Sheffield, United Kingdom, 2018.
%
%
%
% Further information:
% http://www.fusion.informatik.uni-goettingen.de
% https://github.com/Fusion-Goettingen
%
% Source code written by Shishan Yang
% =============================

clc
close all
clear
dbstop error

scenario = 1; % turn and closely-spaced
% scenario = 2; % cross
clambda = 40; % clutter rate

% motion and measurement parameters used for multiplicative noise model
Cv = diag([10 10]);
Crw = diag([10 10 10 10]);
Cpw(:,:,1) = diag([0.02 1 1]);
Cpw(:,:,2) = diag([0.02 1 1]);
Ar = [1 0 1 0; 0 1 0 1; 0 0 1 0; 0 0 0 1];
Ap = eye(3);
H = [eye(2);zeros(2,2)]';

figure
hold on
box on
axis equal

[gt, meas,mlambda, xbound, ybound,cp,nr_timesteps] = getMeasGt(scenario,clambda,Cv);

% first guess
r = [-20 -250 10 10;-20 250 10 -10];
p = [0 30 30;0 15 15 ];

N = size(r,1);

Cr(:,:,1) = diag([900 900 10 10]);
Cp(:,:,1) = diag([.2 400 400]);

Cr(:,:,2) = diag([900 900 10 10]);
Cp(:,:,2) = diag([.02 100 100]);

%% plot first guess
for n = 1:N
    plot_extent([r(n,1:2) p(n,:)],'--','r',1);
end

for t = 1:nr_timesteps

    [r,p,Cr,Cp] = MEOT_JPDA(meas{t},r,p,Cr,Cp,cp,H,Cv,mlambda,clambda);

    %% Visulize
    if mod(t,3)==1

        pMeas = plot(meas{t}(1,:),meas{t}(2,:),'k.');
        for n = 1:N
            plotGT = plot_extent(gt(n,1:5,t),'-','k',1);
            plotEst = plot_extent([r(n,1:2),p(n,:)],'-','g',1);
        end
        pause(0.001)
    end

    %% prediction
    for n = 1:N
        r(n,:) = Ar*r(n,:)';
        p(n,:) = Ap*p(n,:)';
        Cr(:,:,n) = Ar*Cr(:,:,n)*Ar'+Crw;
        Cp(:,:,n) = Ap*Cp(:,:,n)*Ap'+Cpw(:,:,n);
    end
end
    legend([plotGT plotEst],{'Ground Truth','Estimates'})


classdef PREA < ALGORITHM
% <multi/many> <real/integer/label/binary/permutation>
% Promising-region based EMO algorithm

%------------------------------- Reference --------------------------------
% J. Yuan, H. Liu, F. Gu, Q. Zhang, and Z. He, Investigating the properties
% of indicators and an evolutionary many-objective algorithm based on a
% promising region, IEEE Transactions on Evolutionary Computation, 2021,
% 25(1): 75-86.
%------------------------------- 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 Jiawei Yuan

    methods
        function main(Algorithm,Problem)
            %% Generate the random population
            Population = Problem.Initialization();
            Zmin       = min(Population.objs,[],1);

            %% shift the objective space to R+
            PopObj = Population.objs;
            PopObj = PopObj - repmat(Zmin,Problem.N,1) + 1e-6;

            %% calculate the ratio based indicator matrix
            IMatrix = ones(Problem.N,Problem.N);
            for i=1:1:Problem.N
                Fi             = PopObj(i,:);
                % calculate ratio based indicator value of each individual
                Ir             = PopObj./repmat(Fi,Problem.N,1) - 1;
                InvertIr       = repmat(Fi,Problem.N,1)./PopObj - 1;
                MaxIr          = max(Ir,[],2);
                MinIr          = max(InvertIr,[],2);
                DomInds        = find(MaxIr<=0);
                MaxIr(DomInds) = -MinIr(DomInds);
                IMatrix(i,:)   = MaxIr';
                IMatrix(i,i)   = Inf;
            end

            %% Optimization
            while Algorithm.NotTerminated(Population)
                MatingPool = MatingStrategy(IMatrix);
                Offspring  = OperatorGAhalf(Problem,Population(MatingPool));
                Zmin       = min([Zmin;Offspring.objs],[],1);
                [Population,IMatrix] = PREA_Update([Population,Offspring],Problem.N,Zmin);
            end
        end
    end
end


function [y] = spm_fx_lz(x,u,P)
% flow for Lorenz attractor
% FORMAT [y] = spm_fx_lz(x,u,P)
% x - state
% u - input
% P - parameters
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_fx_lz.m 1961 2008-07-26 09:38:46Z karl $

% flow for Lorenz attractor
%--------------------------------------------------------------------------
try
    P(3) = P(3)*(1 + u);
end
J    = [-P(1) P(1) 0; (P(3) - x(3)) -1 -x(1); x(2) x(1) P(2)];
y    = J*x;


function [ttm] = tt_Fd_mtx2(tt_a, bound1, bound2, eps)
%TT-representation of the diffusion matrix
%   [TTM] = TT_FD_MTX2(TT_A, BOUND1, BOUND2, EPS) Computes TT
%   representation of a simplest discretization of the diffusion operator
%   with operator given in the QTT-format (TT_A).
%
%
% TT-Toolbox 2.2, 2009-2012
%
%This is TT Toolbox, written by Ivan Oseledets et al.
%Institute of Numerical Mathematics, Moscow, Russia
%webpage: http://spring.inm.ras.ru/osel
%
%For all questions, bugs and suggestions please mail
%ivan.oseledets@gmail.com
%---------------------------

d = size(tt_a, 1);
n = zeros(1,d);
for q=1:d
    n(q)=size(tt_a{q}, 1);
end;

if (max(size(bound1))==1) bound1 = bound1*ones(1,d); end;
if (max(size(bound2))==1) bound2 = bound2*ones(1,d); end;

ranks_a = tt_ranks(tt_a);

for q=1:d
    cur_tt = cell(d,1);

    cur_tt{1}=zeros(n(1),n(1),ranks_a(1));
    for k=1:ranks_a(1)
            lp1 = diag(-1*ones(n(1)-1,1), [-1])+diag(2*ones(n(1), 1), [0])+diag(-1*ones(n(1)-1,1), [1]);
            Mp1 = diag((1/6)*ones(n(1)-1,1), [-1])+diag((4/6)*ones(n(1), 1), [0])+diag((1/6)*ones(n(1)-1,1), [1]);
            if (bound1(1)==1) lp1(1,1)=1; end;
            if (bound2(1)==1) lp1(n(1),n(1))=1; end;
            h = 1/(n(1)+1);
            if ((bound1(1)==1)||(bound2(1)==1)) h = 1/n(1); end;
            if ((bound1(1)==1)&&(bound2(1)==1)) h = 1/(n(1)-1); end;
            Mlp1 = diag(tt_a{1}(2:n(1),k), [-1])+diag(tt_a{1}(2:n(1),k), [1]);
            Mlp1 = Mlp1 + diag(tt_a{1}(1:n(1),k)+[tt_a{1}(2:n(1),k)' tt_a{1}(n(1),k)]', [0])*0.5;
        if (q==1)
            cur_tt{1}(:,:,k) = Mlp1.*(lp1/h^2);
        else
            cur_tt{1}(:,:,k) = Mlp1.*Mp1;
%             cur_tt{1}(:,:,k) = diag(tt_a{1}(1:n(1),k)+[tt_a{1}(2:n(1),k)' tt_a{1}(n(1),k)]', [0])*0.5;
        end;
    end;

    for p=2:d-1
        cur_tt{p}=zeros(n(p),n(p),ranks_a(p-1),ranks_a(p));
        for k1=1:ranks_a(p-1)
            for k2=1:ranks_a(p)
                    lp1 = diag(-1*ones(n(p)-1,1), [-1])+diag(2*ones(n(p), 1), [0])+diag(-1*ones(n(p)-1,1), [1]);
                    Mp1 = diag((1/6)*ones(n(1)-1,1), [-1])+diag((4/6)*ones(n(1), 1), [0])+diag((1/6)*ones(n(1)-1,1), [1]);
                    if (bound1(p)==1) lp1(1,1)=1; end;
                    if (bound2(p)==1) lp1(n(p),n(p))=1; end;
                    h = 1/(n(p)+1);
                    if ((bound1(p)==1)||(bound2(p)==1)) h = 1/n(p); end;
                    if ((bound1(p)==1)&&(bound2(p)==1)) h = 1/(n(p)-1); end;
                    Mlp1 = diag(tt_a{p}(2:n(p),k1,k2), [-1])+diag(tt_a{p}(2:n(p),k1,k2), [1]);
                    Mlp1 = Mlp1 + diag(tt_a{p}(1:n(p),k1,k2)+[tt_a{p}(2:n(p),k1,k2)' tt_a{p}(n(p),k1,k2)]', [0])*0.5;
                if (p==q)
                    cur_tt{p}(:,:,k1,k2) = Mlp1.*(lp1/h^2);
                else
                    cur_tt{p}(:,:,k1,k2) = Mlp1.*Mp1;
%                     cur_tt{p}(:,:,k1,k2) = diag(tt_a{p}(1:n(p),k1,k2)+[tt_a{p}(2:n(p),k1,k2)' tt_a{p}(n(p),k1,k2)]', [0])*0.5;
                end;
            end;
        end;
    end;

    cur_tt{d}=zeros(n(d),n(d),ranks_a(d-1));
    for k=1:ranks_a(d-1)
            lp1 = diag(-1*ones(n(d)-1,1), [-1])+diag(2*ones(n(d), 1), [0])+diag(-1*ones(n(d)-1,1), [1]);
            Mp1 = diag((1/6)*ones(n(1)-1,1), [-1])+diag((4/6)*ones(n(1), 1), [0])+diag((1/6)*ones(n(1)-1,1), [1]);
            if (bound1(d)==1) lp1(1,1)=1; end;
            if (bound2(d)==1) lp1(n(d),n(d))=1; end;
            h = 1/(n(d)+1);
            if ((bound1(d)==1)||(bound2(d)==1)) h = 1/n(d); end;
            if ((bound1(d)==1)&&(bound2(d)==1)) h = 1/(n(d)-1); end;
            Mlp1 = diag(tt_a{d}(2:n(d),k), [-1])+diag(tt_a{d}(2:n(d),k), [1]);
            Mlp1 = Mlp1 + diag(tt_a{d}(1:n(d),k)+[tt_a{d}(2:n(d),k)' tt_a{d}(n(d),k)]', [0])*0.5;
        if (q==d)
            cur_tt{d}(:,:,k) = Mlp1.*(lp1/h^2);
        else
            cur_tt{d}(:,:,k) = Mlp1.*Mp1;
%             cur_tt{d}(:,:,k) = diag(tt_a{d}(1:n(d),k)+[tt_a{d}(2:n(d),k)' tt_a{d}(n(d),k)]', [0])*0.5;
        end;
    end;

    if (q==1)
        ttm = cur_tt;
    else
        ttm = ttm_add(ttm, cur_tt);
        ttm = tt_mat_compr(ttm, eps);
    end;
end;

end


function [ x, tan, status ] = p00_limit ( problem, option, nvar, x1, tan1, ...
  x2, tan2, lim )

%*****************************************************************************80
%
%% P00_LIMIT seeks a limit point.
%
%  Discussion:
%
%    For a given index 1 <= LIM <= NVAR, a limit point X is a point which
%    satisfies F(X) = 0 and TAN(X)(LIM) = 0, that is, X is a point on the
%    solution curve, and the LIM-th component of the tangent vector at X
%    is zero.
%
%    This function may be called if a limit point has been bracketed,
%    that is, if X1 and X2 are points on the curve with the property that
%    there is a change in sign in the LIM-th component of the tangent
%    vector between X1 and X2.
%
%    The function carries out an iteration seeking a point X between
%    X1 and X2 for which the LIM-th tangent component is zero.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 October 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer PROBLEM, the problem index.
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Input, real X1(NVAR), TAN1(NVAR), a point on the curve,
%    and its tangent vector.
%
%    Input, real X2(NVAR), TAN2(NVAR), a second point on the curve,
%    and its tangent vector.
%
%    Input, integer LIM, the index of the entry of TAN which
%    we are seeking to zero.
%
%    Output, real X(NVAR), TAN(NVAR), the computed limit point
%    and its tangent vector.
%
%    Output, integer STATUS.
%    nonnegative, the limit point was computed in STATUS steps.
%    negative, the limit point could not be computed.
%
  VERBOSE = 0;
%
%  Use a fixed parameter index, but do NOT use LIM.
%
  x = x2 - x1;
  x(lim) = 0.0;
  par_index = r8vec_amax_index ( nvar, x );
%
%  Start the zero finding process.
%
  a = 0.0;
  b = 1.0;
  tol = sqrt ( eps );
  arg = 0.0;
  status_zero = 0;
  value = 0.0;

  status = 0;

  while ( 1 )

    [ arg, status_zero ] = zero_rc ( a, b, tol, value, status_zero );

    if ( status_zero < 0 )
      status = -1;
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P00_LIMIT - Fatal error!\n' );
      fprintf ( 1, '  ZERO_RC returned an error flag.\n' );
      break
    end

    if ( arg == 0.0 )

      x = x1;
      tan = tan1;

    elseif ( arg == 1.0 )

      x = x2;
      tan = tan2;

    else

      x = ( 1.0 - arg ) * x1 ...
          +       arg   * x2;

      [ x, status_newton ] = p00_newton ( problem, option, nvar, x, par_index );

      if ( status_newton < 0 )
        status = -2;
        fprintf ( 1, '\n' );
        fprintf ( 1, 'P00_LIMIT - Fatal error!\n' );
        fprintf ( 1, '  ZERO_RC returned an error flag.\n' );
        break
      end

      tan = p00_tan ( problem, option, nvar, x );

    end

    value = tan(lim);

    if ( VERBOSE )
      fprintf ( 1, '  %8d  %14e  %14e\n', status_zero, arg, value );
    end

    status = status + 1;

    if ( status_zero == 0 )
      break
    end

  end

  return
end


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function [price, se, low, high] ...
    = LongstaffSchwartz_M2(S, M, Ns, g, df, f, B, Nr, NSim, level)
% Longstaff Schwartz method for pricing american options

v = g(:,end);   % start for backward induction

% backward induction and regression from t_{Nr-1} up to t_1
for i = Nr-1:-1:1
        index = find(g(:,i+1) > 0); % all ITM paths
        s = S(index,i+1);           % values of S at given time points
        m = M(index,i+1);           % values of M at given time points
        v = v * df(i+1);            % option value at t_i

        Acell = B(s,m);             % evaluate basis function in cell array B
        A = cell2mat(Acell{:,:});   % convert to matrix

        c = A*f(:,i);                   % continuation value
        exercise = g(index,i+1) >= c;    % early exercise
        v(index(exercise)) = g(index(exercise),i+1);
end

price = mean(v * df(1));    % final option value

% standard error and confidence interval
sv = sqrt(1/(NSim-1)*sum((v - price * ones(NSim,1)).^2));
se = sv/sqrt(NSim);
low =  price - norminv(level) * sv/sqrt(NSim);
high = price + norminv(level) * sv/sqrt(NSim);

end


function result = sumOfNeighbors(input,edges,edgeOffsets,numNeighbors)

numNodes = length(input);
result = zeros(size(input));
for n = 1:numNodes
   for e = [edgeOffsets(n):edgeOffsets(n)+numNeighbors(n)-1]
      result(n) = result(n) + input(edges(e));
   end
end

% ras 03/2007:
% let's make this agree with sumOfNeighbors.mex: it outputs a
% transverse:
result = result';

return


%  myConstantParamFilter - filtering procedure for state-space models with
%  constant parameters
%
%  ::
%
%
%    [LogLik,Incr,retcode,Filters]=myConstantParamFilter(syst,y,U,z,options)
%
%  Args:
%
%     - **syst** [struct]: structure provided by dsge.filter
%
%     - **y** [matrix]: matrix of data provided by dsge.filter
%
%     - **U** [matrix]: matrix of trends provided by dsge.filter
%
%     - **z** [matrix]: matrix of deterministic terms provided by dsge.filter
%
%     - **options** [struct]: options provided by dsge.filter
%
%  Returns:
%     :
%
%     - **LogLik** [numeric]: value of the log likelihood
%
%     - **Incr** [vector]: contributions to the likelihood in each period
%
%     - **retcode** [numeric]: flag equal to 0 if there is no problem
%
%     - **Filters** [struct]: structure containing all the filtering
%       information
%
%  Note:
%
%     - If the function is passed through a rise/dsge object, then it should
%       be called as ff=filter(m,'kf_user_algo',@myConstantParamFilter).
%
%     See also: myKnownRegimesFilter
%


function [x, y, z] = rfPlot(params, RF, parent, peak)
% rfPlot - script to visualize cropped RF
%
% [x, y, z] = rfPlot(params, RF, [parent=axes in new figure]);
%
% Will produce a plot illustrating the estimated location of a
% 2D Gaussian receptive field, with a grid.
%
% RF is a
% the 'parent' argument directs where to display the plot. Default
% is to create a new figure with its own axes.
%
% 2006/02 SOD: wrote it.
% 2006/09 RAS: added optional 'parent' argument, so you can
% direct the plot to a subplot axes.
% 2008/06 RAS: updated calculation of RF grid to use the X, Y sample points
% in params.analysis.X (and .Y). This replaces a previous method using the
% sample rate; I've found that when you recompute the stimulus (e.g.
% rmRecomputeParams), X/Y sample points for which no stimulus was presented
% are omitted from the analysis. We use this sampling grid to be
% consistent, and prevent bugs in code like rmPlotGUI.
% 2008/07 SOD: reverted back to original. See comments below at the
% relevant code. Must validate rmRecomputeParams.
if ~exist('parent','var') || isempty(parent), figure; parent = gca;      end;
if ~exist('peak','var'), peak = [];      end;

[x,y] = prfSamplingGrid(params);
z    = NaN(size(x));
z(params.stim(1).instimwindow) = RF;
z    = reshape(z,size(x));

% plot
axes(parent);
cla;
hold on;
surf(x,y,z,'LineStyle','none');

%draw lines at every degree
mylines = 0; %[-floor(params.analysis.fieldSize):floor(params.analysis.fieldSize)];
for ll = 1:numel(mylines),
    for n=1:2,
        if n==1,
            ii = find(x==mylines(ll) & isfinite(z));
            [xs, is] = sort(y(ii));
        else
            ii = find(y==mylines(ll) & isfinite(z));
            [xs, is] = sort(x(ii));
        end;
        if ~isempty(is),
            ii = ii(is);
            h  = line(x(ii),y(ii),z(ii));
            if mylines(ll)==0,
                set(h,'LineWidth',1,'Color',[0 0 0]);
            else
                set(h,'LineWidth',0.5,'Color',[0 0 0]);
            end;
        end;
    end;
end;

minz = min(z(:));
maxz = peak;
if isempty(maxz), maxz = max(z(:)); end;
if isnan(maxz), maxz = 0.1; minz = -0.1; end;
if minz==maxz,
    minz = minz - 0.1;
    maxz = maxz + 0.1;
end;

% scale axis
axis([min(x(:)) max(x(:)) min(y(:)) max(y(:)) minz maxz]);
axis image;

% scale colorbar to be centered on zero
caxis([-1 1].*max(abs(minz),abs(maxz)));

% axis labels
xlabel('x (deg)');
ylabel('y (deg)');
zlabel('BOLD amplitude (%/deg^2/sec)');
title('pRF profile');
hold off;

return


function [h,Hf,Hh] = fromFrameHmg(f,hf)

% FROMFRAMEHMG  Fom-frame transformation for homogeneous coordinates
%   P = FROMFRAMEHMG(F,PF) transforms homogeneous point PF from frame F to
%   the global frame.
%
%   [p,Pf,Ppf] = ... returns the Jacobians wrt F and PF.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

F = homogeneous(f)    ;
[t,q] = splitFrame(f) ;

h = F*hf;

if nargout > 1

    [a,b,c,d] = split(q);
    [hx,hy,hz,ht] = split(hf);

    Ht = [...
        [ ht,  0,  0]
        [  0, ht,  0]
        [  0,  0, ht]
        [  0,  0,  0]];
    Hq = [...
        [  2*a*hx-2*d*hy+2*c*hz,  2*b*hx+2*c*hy+2*d*hz, -2*c*hx+2*b*hy+2*a*hz, -2*d*hx-2*a*hy+2*b*hz]
        [  2*d*hx+2*a*hy-2*b*hz,  2*c*hx-2*b*hy-2*a*hz,  2*b*hx+2*c*hy+2*d*hz,  2*a*hx-2*d*hy+2*c*hz]
        [ -2*c*hx+2*b*hy+2*a*hz,  2*d*hx+2*a*hy-2*b*hz, -2*a*hx+2*d*hy-2*c*hz,  2*b*hx+2*c*hy+2*d*hz]
        [                     0,                     0,                     0,                     0]];

    Hf = [Ht Hq];
    Hh = F;

end

return

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB 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.
%
%   SLAMTB 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 SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


clear all

%define the global variables
global TrainSetX;
global TrainSetY;
global TrainXY;
global TestSetX;
global TestSetY;

global eta;
global gama;
global afa;
global npos;

global kneighbor_test;
global kneighbor_testp;
global kneighbor_mix;

%set the parameters
afa = 0.4;
gama = 15;
eta = 0.12;

kneighbor_testp = textread('KneighborFile.txt');
kneighbor_testp = kneighbor_testp(:,1:(size(kneighbor_testp,2)-1));
kneighbor_testp = kneighbor_testp + 1;
A = textread('data/Train1.data');
TrainSetX = spconvert(A);
A = textread('data/Test1.data');
TestSetX = spconvert(A);
clear A;
TrainSetY = textread('data/Train1.label');
TestSetY = textread('data/Test1.label');
indexi = find(TestSetY == 1);
npos = sum(TestSetY(indexi));

TrainXY = scale_cols(TrainSetX,TrainSetY);
DataX = [TrainSetX TestSetX];
pos = 0;
% read the model trained from Logistic Regression
wbest = textread('orimodel.model');
ptemp = 1./(1 + exp(-wbest'*TrainSetX));
Uconf_mix = [ptemp',1-ptemp'];
TrainA = getResult(ptemp,TrainSetY);
ptemp = 1./(1 + exp(-wbest'*TestSetX));
TestA = getResult(ptemp,TestSetY);
Uconf_mix = [Uconf_mix;[ptemp',1-ptemp']];
clear ptemp;
fprintf('The original training and testing accuracy:  %g:    %g  ...... %g\n',pos,TrainA*100,TestA*100);result = [];
[W,result] = PRP_CG(wbest,npos,gama,afa,0.1);
ptemp = 1./(1 + exp(-W'*TestSetX));
TestA = getResult(ptemp,TestSetY);
fprintf('The final testing accuracy: %g\n',TestA*100);
result(1,length(result)+1) = TestA;
xlswrite('result.xls',result');


function [y, x] = tapas_dcm_euler_gen(DCM, Ep)
% [y, x] = tapas_dcm_euler_gen(DCM, Ep)
%
% Generates synthetic fMRI data under a given signal to noise ratio (SNR)
% with the fixed hemodynamic convolution kernel
%
%   Input:
%   	DCM         - model structure
%       Ep          - data-generating parameters
%
%   Output:
%       y           - generated BOLD signal
%       x           - generated neuronal signal
%

% ----------------------------------------------------------------------
%
% Authors: Stefan Fraessle (stefanf@biomed.ee.ethz.ch), Ekaterina I. Lomakina
%
% Copyright (C) 2016-2018 Translational Neuromodeling Unit
%                         Institute for Biomedical Engineering
%                         University of Zurich & ETH Zurich
%
% This file is part of the TAPAS rDCM Toolbox, which is released under the
% terms of the GNU General Public License (GPL), version 3.0 or later. You
% can redistribute and/or modify the code under the terms of the GPL. For
% further see COPYING or <http://www.gnu.org/licenses/>.
%
% Please note that this toolbox is in an early stage of development. Changes
% are likely to occur in future releases.
%
% ----------------------------------------------------------------------

% number of regions
nr = size(Ep.A,1);
A = Ep.A';

% Transpose each nrxnr matrix
mArrayB = permute(Ep.B, [2 1 3]);

% create an empty D-matrix
if (sum(Ep.D(:))==0)
    Ep.D = zeros(nr,nr,nr);
end

% Transpose each nrxnr matrix
mArrayD = permute(Ep.D, [2 1 3]);
if (isempty(mArrayD))
    mArrayD = zeros(nr,nr,nr);
end

% driving inputs
C = DCM.U.u*(Ep.C'/16);
U = full(DCM.U.u);

% hemodynamic constants
H = [0.64 0.32 2.00 0.32 0.32];

% constants for hemodynamic model
oxygenExtractionFraction = 0.32*ones(nr, 1);
alphainv                 = 1/H(4);
tau                      = H(3)*exp(Ep.transit);
gamma                    = H(2);
kappa                    = H(1)*exp(Ep.decay);
epsilon                  = 1.0*exp(Ep.epsilon)*ones(nr, 1);

% parameter list
paramList = [DCM.U.dt size(U,1) nr size(U,2) 0 1 1];

% neuronal signal and time courses for hemodynamic parameters
[x,~,~,v,q] = dcm_euler_integration(A,C,U,mArrayB,mArrayD,...
                   oxygenExtractionFraction,alphainv,tau,gamma,kappa,paramList);

% constants for BOLD signal equation
relaxationRateSlope      = 25;
frequencyOffset          = 40.3;
oxygenExtractionFraction = 0.4*ones(1,nr);
echoTime                 = 0.04;
restingVenousVolume      = 4;

% coefficients of BOLD signal equation
coefficientK1  = 4.3*frequencyOffset*echoTime*oxygenExtractionFraction;
coefficientK2  = epsilon'.*(relaxationRateSlope*oxygenExtractionFraction*echoTime);
coefficientK3  = 1 - epsilon';

% get the Euler indices
Indices = DCM.M.idx;

% BOLD signal time course
y = restingVenousVolume*( bsxfun(@times,coefficientK1,(1 - (q(Indices,:)))) +...
            bsxfun(@times,coefficientK2,(1 - (q(Indices,:)./v(Indices,:)))) +...
            bsxfun(@times,coefficientK3,(1-v(Indices,:))));

end


function [Fx, Fy] = contactForces(q,dq,ddq,p)
% [Fx, Fy] = contactForces(q,dq,ddq,p)
%
% This function computes the contact forces for the five-link biped
%
% INPUTS:
%   q = [5,n] = configuration
%   dq = [5,n] = rates
%   ddq = [5,n] = accelerations
%   p = parameter struct
%
% OUTPUTS:
%   Fx = [1,n] = horizontal contact force acting on robot
%   Fy = [1,n] = vertical contact force acting on robot
%

[Fx,Fy] = autoGen_contactForce(...
    q(1,:),q(2,:),q(3,:),q(4,:),q(5,:),...
    dq(1,:),dq(2,:),dq(3,:),dq(4,:),dq(5,:),...
    ddq(1,:),ddq(2,:),ddq(3,:),ddq(4,:),ddq(5,:),...
    p.m1, p.m2, p.m3, p.m4, p.m5, p.l1, p.l2, p.l3, p.l4, p.c1, p.c2, p.c3, p.c4, p.c5, p.g);

end


function test_cnn_gradients_are_numerically_correct
batch_x = rand(28,28,5);
batch_y = rand(10,5);
cnn.layers = {
    struct('type', 'i') %input layer
    struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer
    struct('type', 's', 'scale', 2) %sub sampling layer
    struct('type', 'c', 'outputmaps', 2, 'kernelsize', 5) %convolution layer
    struct('type', 's', 'scale', 2) %subsampling layer
};
cnn = cnnsetup(cnn, batch_x, batch_y);

cnn = cnnff(cnn, batch_x);
cnn = cnnbp(cnn, batch_y);
cnnnumgradcheck(cnn, batch_x, batch_y);


function [P] = spm_dcm_fmri_graph_gen(x,v,P)
% Generates adjacency graph for spectral DCM for fMRI
% FORMAT [g] = spm_dcm_fmri_graph_gen(x,v,P)
%
% This routine computes the adjacency matrix (A) for spm_fx_fmri
%
% see also: spm_fx_fmri
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_dcm_fmri_graph_gen.m 5821 2013-12-31 14:26:41Z karl $

% compute bias for log connectivity using functional space
%==========================================================================

% spectral deomposition
%--------------------------------------------------------------------------
P.A   = full(P.A);

if isfield(P,'modes')

    % outer product
    %======================================================================
    n     = length(P.A);                          % number of nodes
    m     = length(v);                            % number of modes
    s     = [-exp(-v); (zeros(n - m,1) - 1)];
    P.A   = P.modes*diag(s)*P.modes';
    P.A   = full(P.A + diag(log(-2*diag(P.A)) - diag(P.A)));
    P     = rmfield(P,'modes');

    return

end

if isnumeric(v)

    % static modes (explicit negativity constraints on self excitation)
    %======================================================================
    % P.A   = v'*v;

    % dynamical modes (implicit negative definite constraints)
    %======================================================================
    P.A   = logm(v'*v + eye(size(v,2),size(v,2))*exp(-16))/16;
    P.A   = P.A + diag(log(-2*diag(P.A)) - diag(P.A));

    return

end

% Distance-based bias on (empirical) prior mean of log connectivity
%--------------------------------------------------------------------------
[n m]          = size(v.x);
if size(P.A,3) == 1 && numel(v.a) == 1

    % one-state model of (MoG) connectivity
    %======================================================================
    for i = 1:m
        for j = (i + 1):m

            % Euclidean distance
            %--------------------------------------------------------------
            P.A(i,j) =  ...
                exp(v.a - sum((v.x(:,i) - v.x(:,j)).^2)/2)/4 - ... % excitatory
                exp(v.a - sum((v.x(:,i) - v.x(:,j)).^2)/8)/8;      % inhibitory
            P.A(j,i) = P.A(i,j);

        end
    end

elseif size(P.A,3) == 1 && numel(v.a) == 2

    % one-state model of centre-surround connectivity
    %======================================================================
    for i = 1:m
        for j = (i + 1):m

            % Euclidean distance
            %--------------------------------------------------------------
            D        = exp(-sum((v.x(:,i) - v.x(:,j)).^2)/2);
            P.A(i,j) = exp(v.a(1))*D/16 + v.a(2);
            P.A(j,i) = P.A(i,j);

        end
    end

elseif size(P.A,3) == 2

    % assume two-state model of log connectivity
    %======================================================================
    for i = 1:m
        for j = (i + 1):m

            % Euclidean distance
            %--------------------------------------------------------------
            P.A(i,j,1) = v.a - sum((v.x(:,i) - v.x(:,j)).^2)/2;
            P.A(j,i,1) = P.A(i,j,1);

            % hierarchical distance
            %--------------------------------------------------------------
            P.A(i,j,2) = (sqrt(sum(v.x(:,i).^2)) - sqrt(sum(v.x(:,j)).^2))/2;
            P.A(j,i,2) = -P.A(i,j,2);

        end
    end

end


function [f]= spm_fx_dem_pursuit(x,v,P)
% returns the flow for visual pursuit demo
% FORMAT [f]= spm_fx_dem_pursuit(x,v,P)
%
% x    - hidden states:
%   x.o(1) - oculomotor angle
%   x.o(2) - oculomotor angle
%   x.x(1) - target location (visual) - extrinsic coordinates (Cartesian)
%   x.x(2) - target location (visual) - extrinsic coordinates (Cartesian)
%   x.a(:) - attractor (SHC) states
%
% v    - hidden causes
% P    - parameters
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_fx_dem_pursuit.m 4322 2011-05-04 15:28:08Z karl $

% intisaise flow (to ensure fields are aligned)
%--------------------------------------------------------------------------
f    = x;

% motion of attractor states
%==========================================================================
f.a  = spm_lotka_volterra(x.a,v);

% motion of target states
%==========================================================================

% target location is determined by the attractor state softmax(x.a)
%--------------------------------------------------------------------------
t    = P*spm_softmax(x.a,1/2);
f.x  = (t - x.x)/2;

% motion of oculomotor angles (attracted to target)
%==========================================================================
t    = atan(x.x);
f.o  = (t - x.o);


function [ point, seed ] = p08_sample ( m, n, seed )

%*****************************************************************************80
%
%% P08_SAMPLE samples points from the region in problem 08.
%
%  Discussion:
%
%    A rejection method is used.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input/output, integer SEED, a seed for the random number generator.
%
%    Output, real POINT(M,N), the coordinates
%    of the points.
%
  batch = 1000;

  [ lo, hi ] = p08_box ( m );

  have = 0;
%
%  We are going to generate batches of sample points.
%
  sample_num = min ( batch, n );

  reject = 0;

  while ( 1 )
%
%  Generate a batch of points in the bounding box.
%
    sample(1:m,1:sample_num) = rand ( m, sample_num );
%
%  Remap the points to the box.
%
    sample(1,1:sample_num) = lo(1) + sample(1,1:sample_num) * ( hi(1) - lo(1) );
    sample(2,1:sample_num) = lo(2) + sample(2,1:sample_num) * ( hi(2) - lo(2) );

    inside(1:sample_num) = p08_inside ( m, sample_num, sample );
%
%  Accept those points which are inside the region.
%
    for j = 1 : sample_num

      if ( inside(j) )

        have = have + 1;
        point(1:m,have) = sample(1:m,j);

        if ( have == n )
          return
        end

      else

        reject = reject + 1;

      end

    end

    if ( 10 * n < reject )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'P08_SAMPLE - Fatal error!\n' );
      fprintf ( 1, '  Too many points rejected!\n' );
      fprintf ( 1, '\n' );
      fprintf ( 1, '  Total number of accepted points = %d\n', have );
      fprintf ( 1, '\n' );
      fprintf ( 1, '  Number generated on this sweep =  %d\n', sample_num );
      fprintf ( 1, '  Number accepted =                 %d\n', ...
        sample_num - reject );
      fprintf ( 1, '  Number rejected =                 %d\n', reject );
      fprintf ( 1, '\n' );
      fprintf ( 1, '  Something appears to be wrong!\n' );
      error ( 'P08_SAMPLE - Fatal error!' );
    end

  end

  return
end


function box = intersectBoxes(box1, box2)
%INTERSECTBOXES Intersection of two bounding boxes.
%
%   RES = intersectBoxes(BOX1, BOX2)
%
%   Example
%   box1 = [5 20 5 30];
%   box2 = [0 15 0 15];
%   intersectBoxes(box1, box2)
%   ans =
%       5 15 5 15
%
%   See also
%   boxes2d, drawBox, mergeBoxes
%

% ------
% Author: David Legland
% E-mail: david.legland@grignon.inra.fr
% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b)
% Copyright 2010-2022 INRA - Cepia Software Platform

% unify sizes of data
if size(box1,1) == 1
    box1 = repmat(box1, size(box2,1), 1);
elseif size(box2, 1) == 1
    box2 = repmat(box2, size(box1,1), 1);
elseif size(box1,1) ~= size(box2,1)
    error('Bad size for inputs');
end

% compute extreme coords
mini = min(box1(:,[2 4]), box2(:,[2 4]));
maxi = max(box1(:,[1 3]), box2(:,[1 3]));

% concatenate result into a new box structure
box = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2)];


%This program localizes single molecules and determines their positions
%by fitting a gaussian to their intensity profile.  A position dependent
%background subtraction is used.

function einzelreader(handles, h)
    global xpix ypix wbox psf_w02;

    version = '6/23/08'; %record version (date) of gui being used

    rbox=str2double(get(handles.rbox_edit,'String'));
    wbox=2*rbox+1;
    [xpix,ypix] = meshgrid(-rbox:rbox,-rbox:rbox);

    q       = str2double(get(handles.cam_pix_edit,'String'));
    wvlnth  = str2double(get(handles.wvlnth,'String'))/1000; %convert wavelength from nm to um
    NA      = str2double(get(handles.NA,'String'));
    psf_scale = str2double(get(handles.psf_scale_edit,'String'));

    psf_w0 = psf_scale*0.55*wvlnth/NA/1.17; % 1/e2 radius of PSF in um, use 1/e2 = FWHM/1.17 from Pawley
                                      % with scale factor (20% for "real objective" due to
                                      % measured PSF from Hess and Webb
                                      % 2002)
    psf_std=psf_w0/2; %standard deviation of psf
    psf_w02=(psf_w0/q)*(psf_w0/q); %square of 1/e^2 radius in pixels

    yfit_psf=exp(-2*((xpix).*(xpix)+(ypix).*(ypix))/psf_w02);
    npix=sum(sum(yfit_psf));     % area of molecule in square pixels

    total_molecules=0;
    xcm_all=zeros(1,1);
    ycm_all=zeros(1,1);
    framenum_all=zeros(1,1);
    n_fail_a0=0;
    n_fail_outbox=0;

    imagefile = get(handles.im_file_edit, 'String');
    outpath = get(handles.out_dir_edit, 'String');
    if outpath(length(outpath))~='/'
        outpath = [outpath,'/'];
    end
    preview = get(handles.show_preview,'Value');

    fs0 = str2double(get(handles.fs,'String')); %Setup for preview frame skipping
    fs1 = fs0;

    if get(handles.rolling_ball_cb,'Value') %if using rolling ball subtraction
        %Obtain info on image type, etc
        file_info = get_file_info2(imagefile, handles);

        n_end   = file_info.stop;
        n_start = file_info.start;

        if get(handles.custom_roi,'Value')
            x_offset   = str2double(get(handles.x_off_edit,'String'));
            y_offset   = str2double(get(handles.y_off_edit,'String'));
            x_size     = str2double(get(handles.x_size_edit,'String'));
            y_size     = str2double(get(handles.y_size_edit,'String'));
        else
            x_offset = 1;
            y_offset = 1;
            x_size   = file_info.width;
            y_size   = file_info.height;
        end

        rball=str2double(get(handles.rb_radius_edit,'String')); %radius of rolling ball
        se = strel('ball',rball,rball,0); %structural element, i.e. rolling ball

        FWHM=str2double(get(handles.FWHM_edit,'String'));; %FWHM of gaussian smoothing in pixels
        rk=(FWHM)/sqrt(2*log(2)); %1/e^2 smoothing radius in pixels
        kw=20; %kernal width of smoothing function
        [X,Y]=meshgrid(-kw/2:kw/2,-kw/2:kw/2);
        kd=sqrt(X.*X+Y.*Y);
        gs=exp(-2*kd.*kd/(rk*rk));
        gs=gs/sum(sum(gs)); %smoothing function normalized to have area = 1

    else %else use integrated widefield sum
        %Load wf sum & mean background mat file
        meanbkg_mat_file = getappdata(0,'last_mbkg_save'); %strcat(dir,'analysis\',date,'/',base_name,'sum_wf_meanbkg.mat');
        load(meanbkg_mat_file,'meanbkg_all','image_sum','x_size','y_size','x_offset','y_offset','field0','n_field','file_info');%,'zero_level'); %mat file from sum_wf_meanbkg.m

        n_end   = file_info.stop;
        n_start = file_info.start;
        %give warning if starting/ending frames are not compatible with wf sum & mean background mat file
        if(n_start<field0)
            warndlg(sprintf('Warning: Starting frame is less than corresponding frame used in Compute WF & Mean Background, need to change starting frame or re-run Compute WF & Mean Background'));
            return
        end
        if(n_end>n_field)
            warndlg(sprintf('Warning: Ending frame is greater than corresponding frame used in Compute WF & Mean Background, need to change ending frame or re-run Compute WF & Mean Background'));
            return
        end

        bkg_pc = str2double(get(handles.bkg_percent,'String'))/100;
        zero_level = str2double(get(handles.zero_lvl,'String'));

        %normalize so that ave pixel value = 1
        image_sum_mean=mean(mean(image_sum(y_offset:y_offset+y_size-1,x_offset:x_offset+x_size-1)));
        image_sum_norm = (image_sum(y_offset:y_offset+y_size-1,x_offset:x_offset+x_size-1))/image_sum_mean;
    end

    %Load variables from the GUI edit boxes
    %--------------------------------------
    if get(handles.pixel_photon,'Value')
        pix_to_pho = str2double(get(handles.pix_to_pho,'String'));
    else
        pix_to_pho = 1;
    end

    iprod_thresh    = str2double(get(handles.iprod_thresh_edit,'String'))*pix_to_pho; %initial threshold for a "bright object"
    threshold       = str2double(get(handles.threshold_edit,'String'))*pix_to_pho; %this value to be included
    upper_threshold = str2double(get(handles.upperthresh_edit,'String'))*pix_to_pho; %this value to not be excluded

    n_bright_pixel_threshold   = str2double(get(handles.min_above_edit,'String')); %min # of pixels above
    box_overlap_factor         = str2double(get(handles.box_overlap_edit,'String')); %if center to center closer, don't include either
    max_pixels_above_threshold = str2double(get(handles.max_above_edit,'String')); %max # of pixels above

    %Initialize temporary runtime file for passing variables
    %-------------
    for x=1:99
        temp_runtime = [outpath,'temp_runtime_',num2str(x,'%2.2d'),'.mat'];
        if ~exist(temp_runtime,'file')
            break
        end
    end
    setappdata(0,'temp_runtime',temp_runtime);
    %-------------

    %Initialize waitbar and pause component
    w = waitbarxmod(0,'Executing "einzelreader.m" ...','CreateCancelBtn','delete(gcf)');
    set(w,'Name','Progress Bar');
    uicontrol('Style','pushbutton','Parent',w,'String','Pause','Position',[210,10,60,23], ...
              'UserData',1,'Callback',@pause_gui);
    drawnow;   %Draw the extra button immediately
    pause(.1); %Pause to ensure window completes drawing
    %keepontop('Progress Bar');

    wb_norm = n_end-n_start;
    if wb_norm == 0 %Avoid divide by zero errors
        wb_norm = 1;
    end

    if h~=0                             %If preview window is active, store the handle of the progress bar
        setappdata(h,'PrBar_Handle',w); %in the appdata of the figure
    end

    for fileloop=n_start:n_end
        if strcmp(file_info.type,'singlepage')
            index = num2str(fileloop,file_info.prec);
%             infile = [file_info.path,'/',file_info.part_name,index,file_info.ext];
            infile = [file_info.path,'/',file_info.part_name,index,file_info.ext];
            i1=double(imread(infile));
        elseif strcmp(file_info.type,'multipage')
            i1=double(imread(imagefile,fileloop));
        end

        compl = (fileloop-n_start)/wb_norm;
        drawnow;
        waitbarxmod(compl,w,'Executing "einzelreader.m" ...'); %Rename the waitbar

        if get(handles.rolling_ball_cb,'Value') %if using rolling ball subtraction
            i1_gs = uint16(conv2(i1,gs,'same')); %smoothed original
            rb_im = imopen(i1_gs,se);
            bkg   = zeros(y_size,x_size);
            bkg   = double(rb_im(y_offset:y_offset+y_size-1,x_offset:x_offset+x_size-1));
        else
            bkg    = zeros(y_size,x_size);
            bkg    = image_sum_norm*bkg_pc*meanbkg_all(fileloop)+zero_level;
        end

        iprod = zeros(y_size,x_size);
        iprod = i1(y_offset:y_offset+y_size-1,x_offset:x_offset+x_size-1)-bkg;
        iprod=iprod.*(iprod>0); % set any negative pixel values to zero

        high_pixel_mask = zeros(y_size,x_size);
        high_pixel_xy   = zeros(10000,3);  % x,y,active
        n_high_pixels   = 0;
        pix_val=iprod_thresh;

        while(pix_val >= iprod_thresh) %continue until reach minimum threshold
            pix_val=0;
            for i=rbox+1:y_size-rbox-1
                for j=rbox+1:x_size-rbox-1
                    if high_pixel_mask(i,j)==0 && iprod(i,j)>pix_val
                        pix_val=iprod(i,j); %find brightest pixel
                        high_pixel_y=i;
                        high_pixel_x=j;
                    end
                end
            end
            if(pix_val < iprod_thresh)
                break
            end
            x0box=high_pixel_x-rbox;
            y0box=high_pixel_y-rbox;
            x1box=high_pixel_x+rbox;
            y1box=high_pixel_y+rbox;

            high_pixel_mask(y0box:y1box,x0box:x1box)=1;
            n_high_pixels=n_high_pixels+1;
            high_pixel_xy(n_high_pixels,1)=high_pixel_x;
            high_pixel_xy(n_high_pixels,2)=high_pixel_y;
            high_pixel_xy(n_high_pixels,3)=1; % active
        end

        drawnow;              %**These added to keep waitbar responsive...
                              % Without these 'drawnow's, the queue gets large and
                              % ignores button presses during execution...
                              %(this function is fast when there is no
                              % actual drawing to do)

        waitbarxmod(compl,w); % <-check waitbar (fast,see waitbarxmod.m)

        for i=1:n_high_pixels
          for j=1:i
            if (i~=j & high_pixel_xy(i,3)==1 & high_pixel_xy(j,3)==1)
              dx=high_pixel_xy(i,1)-high_pixel_xy(j,1);
              dy=high_pixel_xy(i,2)-high_pixel_xy(j,2);
              dmin_nearest_box=sqrt(dx*dx+dy*dy);

              if (dmin_nearest_box<box_overlap_factor*rbox) % these boxes overlap
                if j>i
                  high_pixel_xy(j,3)=-3;       % make one of the boxes inactive
                else
                  high_pixel_xy(i,3)=-3;       % make one of the boxes inactive
                end
              end
            end
          end
        end

        drawnow;
        waitbarxmod(compl,w); %check waitbar

        n_boxes=0;
        boxes_xy=zeros(10000,3);

        for i=1:n_high_pixels
           if high_pixel_xy(i,3)==1
               n_boxes=n_boxes+1;
               boxes_xy(n_boxes,1)=high_pixel_xy(i,1);
               boxes_xy(n_boxes,2)=high_pixel_xy(i,2);
               boxes_xy(n_boxes,3)=1;
           end
        end

        drawnow;
        waitbarxmod(compl,w); %check waitbar

        failed=zeros(n_boxes,1);
        for i=1:n_boxes
           x0_box=boxes_xy(i,1)-rbox;
           y0_box=boxes_xy(i,2)-rbox;
           x1_box=boxes_xy(i,1)+rbox;
           y1_box=boxes_xy(i,2)+rbox;

           grab=iprod(y0_box:y1_box,x0_box:x1_box);
           minbkg=min(min(grab));
           grab=grab-minbkg;

           xm_sum=0;
           ym_sum=0;
           m_sum=0;
           for x=x0_box:x1_box
             for y=y0_box:y1_box
                xind=floor(x);
                yind=floor(y);
                intens=iprod(yind,xind);
                xm_sum=xm_sum+xind*intens;
                ym_sum=ym_sum+yind*intens;
                m_sum=m_sum+intens;
             end
           end

           x_cm(i)=xm_sum/m_sum;
           y_cm(i)=ym_sum/m_sum;

           %re-center box around center of mass
           if round(x_cm(i)) > 1+rbox && round(x_cm(i)) < x_size-rbox
               boxes_xy(i,1)=round(x_cm(i));
           end
           if round(y_cm(i)) > 1+rbox && round(y_cm(i)) < y_size-rbox
               boxes_xy(i,2)=round(y_cm(i));
           end

           x0_box=boxes_xy(i,1)-rbox;
           y0_box=boxes_xy(i,2)-rbox;
           x1_box=boxes_xy(i,1)+rbox;
           y1_box=boxes_xy(i,2)+rbox;

           grab=zeros(wbox,wbox);
           grab=iprod(y0_box:y1_box,x0_box:x1_box);
           minbkg=min(min(grab));
           grab=grab-minbkg;
           grab_sum(i)=sum(sum(grab));
           image_bright_in_box(:,:,i)=grab;

           xc_box=(x0_box+x1_box)*0.5;
           yc_box=(y0_box+y1_box)*0.5;

           xguess=x_cm(i)-xc_box;
           yguess=y_cm(i)-yc_box;

           for n=1:wbox
                for p=1:wbox
                    k=(n-1)*wbox+p;
                    xymerge(k)=0;
                    zmerge(k)=grab(n,p);
                end
           end

           beta=[xguess,yguess,50];
           [betafit,resid,J,COVB,mse] = nlinfit(xymerge,zmerge,@gaussian_merge,beta);
           ci = nlparci(betafit,resid,'covar',COVB); %calculate error estimates on parameters
           ci_err=(ci(:,2)-ci(:,1))/2;
           xf_err(i)=ci_err(1);
           yf_err(i)=ci_err(2);
           a0_err(i)=ci_err(3);

           zfitmerge=gaussian_merge(betafit,xymerge);

           for n=1:wbox
                for p=1:wbox
                    k=(n-1)*wbox+p;
                    zfit(n,p)=zfitmerge(k);
                end
           end

           yf_box(i)=betafit(2)+yc_box;
           xf_box(i)=betafit(1)+xc_box;
           a0_box(i)=betafit(3);

           if(a0_box(i) < 0)
                n_fail_a0=n_fail_a0+1;
                failed(i)=1;
           end
           if xf_box(i) > x1_box || xf_box(i) < x0_box || yf_box(i) > y1_box || yf_box(i) < y0_box
                n_fail_outbox=n_fail_outbox+1;
                failed(i)=1;
           end

           drawnow   %Flush event queue to keep cancel/pause button responsive on every pass.
                     %This is the slowest function by far and drawnow barely changes its exec time

           waitbarxmod(compl,w); %check waitbar
        end

        n_pixels_above_threshold=zeros(n_boxes,1);
        n_pixels_above_upper_threshold=zeros(n_boxes,1);

        for i=1:n_boxes
          if (boxes_xy(i,3)==1)
            n_pixels_above_threshold(i)=0;
            for j=1:2*rbox+1
              for k=1:2*rbox+1
                intens=image_bright_in_box(j,k,i);
                if intens>=threshold
                  n_pixels_above_threshold(i)=n_pixels_above_threshold(i)+1;
                end
                if intens>=upper_threshold
                  n_pixels_above_upper_threshold(i)=n_pixels_above_upper_threshold(i)+1;
                end
              end
            end
          end
        end

        drawnow;
        waitbarxmod(compl,w); %check waitbar

        n_molecules_found=0;

        for i=1:n_boxes
            if boxes_xy(i,3)==1
                if (n_pixels_above_threshold(i)>=n_bright_pixel_threshold && n_pixels_above_upper_threshold(i)<=max_pixels_above_threshold)
                    n_molecules_found=n_molecules_found+1;
                else
                    if (n_pixels_above_threshold(i)<n_bright_pixel_threshold)
                      boxes_xy(i,3)=-2; %draw red box
                    end
                    if (n_pixels_above_threshold(i)>max_pixels_above_threshold)
                      boxes_xy(i,3)=-1; %draw yellow box
                    end
                end
            end
        end

        drawnow;
        waitbarxmod(compl,w); %check waitbar

        if preview  %If preview active, update images on screen
            set(0,'CurrentFigure',h);
            if ~exist('plot2','var')
                position2 = [.01,.37,.25,.25];
                plot2 = axes('Position', position2);
                setappdata(plot2,'pos',position2);
            else
                set(h,'CurrentAxes',plot2);
            end
            i1display = i1(y_offset:y_offset+y_size-1,x_offset:x_offset+x_size-1);
            imagesc(i1display,'HitTest','off');
            axis image;
            colormap gray;
            title(['Last Frame Processed: ', num2str(fileloop)])
            set(plot2, 'ButtonDownFcn',{@focus_swap,guidata(gcbo)});
            clear i1display;

            if ~exist('plot1','var')
                position1 = [.01,.05,.25,.25];
                plot1 = axes('Position', position1,'Color','k','YTickLabel','','XTickLabel','');
                axis image;
                set(plot1,'Position',position1);
                setappdata(plot1,'pos', position1);
            end

            if get(handles.rolling_ball_cb,'Value')
                if ~exist('plot3','var')
                    position3 = [.01,.70,.25,.25];
                    plot3 = axes('Position', position3);
                    setappdata(plot3,'pos',position3);
                else
                    set(h,'CurrentAxes',plot3);
             end
                imagesc(rb_im,'HitTest','off')
                colormap gray, axis image;
                title(['Rolling Ball Profile: ',num2str(fileloop)])
                set(plot3,'ButtonDownFcn',{@focus_swap,guidata(gcbo)});
            end

            if ~exist('plot4','var')
                if x_size < y_size
                    positionf = [.18,.065,.87,.87];
                else
                    positionf = [.32,.3,.6,.65];
                end
                plot4 = axes('Position', positionf);
                setappdata(0,'focused',plot4);
            else
                set(h,'CurrentAxes',plot4);
            end

            if get(handles.mnl_scale_check,'Value')
                clim = str2double(get(handles.mnl_scale_edit,'String'));
                imagesc(iprod,'HitTest','off',[0 clim]);
            else
                imagesc(iprod,'HitTest','off');
            end

            axis image;
            colormap gray;
            title(['Einzel Reader: Frame: ',num2str(fileloop)]);
            set(plot4, 'ButtonDownFcn',{@focus_swap,guidata(gcbo)});

            if (get(handles.show_colorbar,'Value') == 1)
                focused = getappdata(0, 'focused');
                set(h,'CurrentAxes', focused);
                pos = get(focused, 'Position');
                colorbar('Position',[.947, pos(2), .015, pos(4)],'DrawMode','fast')
            end

            set(h,'CurrentAxes', plot4);
        end

        if n_boxes>0

            if preview %Only draw if preview is active
                hold on
                draw_boxes(n_boxes,boxes_xy,rbox);
            end

            for i=1:n_boxes
                if boxes_xy(i,3)==1 && failed(i) ~= 1
                    if preview %Only plot if preview is active
                        %plot(x_cm(i),y_cm(i),'.m','HitTest','off'); %centroid
                        %plot(xf_box(i),yf_box(i),'.b','HitTest','off'); %gaussian fit
                    end
                    total_molecules=total_molecules+1;
                    xcm_all(total_molecules)=x_cm(i);
                    ycm_all(total_molecules)=y_cm(i);
                    xf_all(total_molecules)=xf_box(i);
                    yf_all(total_molecules)=yf_box(i);
                    a0_all(total_molecules)=a0_box(i);
                    grab_sum_all(total_molecules)=grab_sum(i);
                    framenum_all(total_molecules)=fileloop;
                    xf_err_all(total_molecules)=xf_err(i);
                    yf_err_all(total_molecules)=yf_err(i);
                    a0_err_all(total_molecules)=a0_err(i);
                end
            end
            nmol_all(fileloop)=n_boxes;%%

            if preview %Remove the hold
                hold off
            end

            drawnow;              %Draw any boxes and update einzelreader image (flush queue and check waitbar if preview not active)
            waitbarxmod(compl,w); %Update the waitbar
        end

        if get(handles.frame_delay_check,'Value')
            delay = str2double(get(handles.frame_delay_edit,'String'))/1000;
            if delay ~= inf
                pause(delay);
            end
        end

        if preview  %If preview active, compute wf & merge on first, last, and nth frames (always)
            if fileloop == n_end
                setappdata(0,'Save',1); %Trigger image save on last frame
                save(temp_runtime);     %Save variables to a temporary file for function passing
%                 fpalm_render_einzelreader(handles,h);
            elseif fileloop == n_start+fs1-1
                fs1=fs1+fs0;
                save(temp_runtime);
%                 fpalm_render_einzelreader(handles,h);
            elseif fileloop == n_start
                save(temp_runtime);
%                 fpalm_render_einzelreader(handles,h);
            end
        end
    end

    if ~preview %If preview is off, continue to wf & merge at end and save the result
        plot1 = 0;
        save(temp_runtime);
        setappdata(0,'Save',1);
        fpalm_render_einzelreader(handles,h);
    else        %Otherwise delete progress bar and handle stored in appdata
        delete(w);
        rmappdata(h,'PrBar_Handle');
    end

    if get(handles.oc_wf,'Value') %save widefield image if selected
        if (file_info.part_name(length(file_info.part_name)) == '_') %Avoid saving with repeated seperators
            wf_file = [outpath,'/',file_info.part_name,'wf.tif'];
        else
            wf_file = [outpath,'/',file_info.part_name,'_wf.tif'];
        end
        imwrite(uint8((image_sum/max(image_sum(:)))*255),wf_file,'Compression','none');
    end

%Save Variables
%----------------
    if (file_info.part_name(length(file_info.part_name)) == '_') %Avoid saving with repeated seperators
        out_file = [outpath,file_info.part_name,num2str(n_start),'-',num2str(n_end),'_t',num2str(iprod_thresh),'-',num2str(threshold),'-',num2str(upper_threshold),'_npt',num2str(n_bright_pixel_threshold),'-',num2str(max_pixels_above_threshold),'.mat'];
    else
        out_file = [outpath,file_info.part_name,'_',num2str(n_start),'-',num2str(n_end),'_t',num2str(iprod_thresh),'-',num2str(threshold),'-',num2str(upper_threshold),'_npt',num2str(n_bright_pixel_threshold),'-',num2str(max_pixels_above_threshold),'.mat'];
    end

    if ~exist(outpath,'dir') %Make sure the directory exists
        answer = questdlg('Output directory could not be accessed. Choose a new save location?','Warning!','Yes','Discard','Yes');

        if strcmp(answer,'Yes')
            outpath = uigetdir();
            if ~outpath
                return
            end
            if outpath(length(outpath))~='/'
                outpath = [outpath,'/'];
            end

            if (file_info.part_name(length(file_info.part_name)) == '_')
                out_file = [outpath,file_info.part_name,num2str(n_start),'-',num2str(n_end),'_t',num2str(iprod_thresh),'-',num2str(threshold),'-',num2str(upper_threshold),'_npt',num2str(n_bright_pixel_threshold),'-',num2str(max_pixels_above_threshold),'.mat'];
            else
                out_file = [outpath,file_info.part_name,'_',num2str(n_start),'-',num2str(n_end),'_t',num2str(iprod_thresh),'-',num2str(threshold),'-',num2str(upper_threshold),'_npt',num2str(n_bright_pixel_threshold),'-',num2str(max_pixels_above_threshold),'.mat'];
            end
        else
            return
        end
    end

    prec_edit     = get(handles.prec_edit,'String');                %<- These to be saved with the
    bkgn          = str2double(get(handles.bkgn_noise,'String'));   %<- mat file for loading purposes
    ppp           = str2double(get(handles.pix_to_pho,'String'));   %<-
    jshift        = str2double(get(handles.jshift,'String'));       %<-
    ishift        = str2double(get(handles.ishift,'String'));       %<-
    exf           = str2double(get(handles.exf_edit,'String'));     %<-   expansion factor

    a0_phot=a0_all/ppp;    % peak amplitude of each molecule in photons
    N=npix*a0_phot;        % number of photons for each molecule

    %localization precision in um
    lp2=((psf_std^2)+(q^2)/12)*1./N+8*pi*(psf_std^4)*(bkgn^2)/(q^2)*1./(N.*N);
    lp=sqrt(lp2);

    list = who; %Use regular expressions to ensure handles are not saved
    match = regexp(list,'^plot|handles|\<h\>|\<w\>');
    for i=length(match):-1:1
        if match{i}
            list(i)=[];
        end
    end
    save(out_file,list{:}); %Save variables used in einzelreader.m
    setappdata(0,'last_einzel_save',out_file);  %Save location of einzelreader mat file for other functions to use
%----------------
    %Clean up temp files and appdata
    if exist(temp_runtime,'file')
        delete(temp_runtime)
    end
    if isappdata(0,'temp_runtime')
        rmappdata(0,'temp_runtime')
    end


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function [price_pi, se, conflevel_low, conflevel_high] = ...
    PIter_E(S, g, K, r, T, sigma, Nr, NSim, NSSim, type, getpaths, payoff)
% policy iteration using European options

% S: Path set
% K: Strike for analytic pricing
% r: riskless rate for analytic pricing
% T: Laufzeit der Option in Jahren
% sigma: volatility for analytic pricing
% NSim: number of simulations
% NSSim: number of simulations for sub-simulation
% type: 0 -> put, 1 -> call

dt = T/Nr;              % equidistant spacing
tau = Nr*ones(NSim,1);  % exercise rule for each path
iVec = (1:NSim)';       % index vector
for i = 1:Nr-1
    i_nexercise = tau == Nr;        % only ex if not already done
    % paths (realisation) where the stopping rule needs improvement
    I_nexercise = iVec(i_nexercise);

    price = BlackScholesPrice(S(i_nexercise,i+1), K, r, (1:Nr-i)'*dt,...
        sigma, type);                      % analytic price
    exbound = max(price,[],2);             % ex decision
    isubsim = g(i_nexercise,i) >= exbound; % index set indicating subsim

    if sum(I_nexercise(isubsim)) ~= 0       % if necessary
        Indicator = subsimulation(S(I_nexercise(isubsim),i+1), K, r, sigma, ...
            dt, NSSim, Nr-i, type,getpaths, payoff); % subsim

        Ind = iVec(I_nexercise(isubsim)); % index: payoff >= current rule
        % exercised befor this time? Use Indicator
        ind2 = g(I_nexercise(isubsim),i) >= Indicator; % ind: at ind2 and q
        Ind2 = iVec(ind2);                              % ind set for ind2
        if sum(ind2) ~= 0
            tau(Ind(Ind2)) = i; % final exercise
        end
    end
end

f = zeros(NSim,1); % sum payoffs for exercise times
for j = 1:NSim
    f(j) = g(j,tau(j));
end
price_pi = mean(f .* exp(-r*dt*tau));

sv = sqrt(1/(NSim-1)*sum((f*100 - price_pi * ones(NSim,1)).^2));
se = sv/sqrt(NSim);
conflevel_low = price_pi - 1.96 * sv/sqrt(NSim);
conflevel_high = price_pi + 1.96 * sv/sqrt(NSim);

end

function [price_local] = subsimulation(S, K, r, sigma, dt, NSim, Nr, type, getpaths, payoff)
    lenS = length(S);           % length of the path set S
    iVec = (1:NSim)';           % index set
    S2 = getpaths(S,NSim,Nr);   % new path set
    g2 = payoff(S2(:,2:end,:)); % evaluate option on path set S2

    price_local = zeros(lenS, 1);

    for k = 1:lenS
        payoff = zeros(NSim, Nr);
        for i=1:1:Nr-1
            for z=i:1:Nr-1
                i_nexercise = payoff(:,i) == 0; % check if exercised
                I_nexercise = iVec(i_nexercise);

                price = BlackScholesPrice(S2(I_nexercise,z,k),K,r, ...
                    (1:Nr-z)'*dt,sigma,type);       % analytic price
                exbound=max(price,[],2);            % bound for exercise

                exercise = g2(i_nexercise,z,k) >= exbound; % exercise
                payoff(I_nexercise(exercise),i) = ...
                    g2(I_nexercise(exercise),z,k) * exp(-r*dt*z);

            end

            finalexercise = payoff(:,i) == 0;   % finally not exercised
            payoff(finalexercise,i) = g2(finalexercise,Nr,k) ...
                * exp(-r*dt*Nr);                % final exercise

        end
        payoff(:,Nr) = g2(:,Nr,k) * exp(-r*dt*Nr);
        price_local(k) = max(mean(payoff));
    end

end


% Convert an edge list to an adjacency list.
%
% INPUTS: edge list, mx3, m - number of edges
% OUTPUTS: adjacency list
%
% Note: Information about edge weights (if any) is lost.
% GB: last updated, September 25, 2012

function adjL = edgeL2adjL(el)

nodes = unique([el(:,1)' el(:,2)']);
adjL=cell(numel(nodes),1);

for e=1:size(el,1); adjL{el(e,1)}=[adjL{el(e,1)},el(e,2)]; end


%% BVAR tutorial: FORECASTS
% Author:   Filippo Ferroni
% Date:     27/02/2020

clear all
close all
clc

addpath ../../cmintools/
addpath ../../bvartools/
pkg load statistics
pkg load io

%% %=========================================================================
%%% DIRECT METHODS %%%
%%=========================================================================

load('../BVAR tutorial/DataGK')
y = [logip logcpi gs1 ebp];

%% 1/ Cholesky

lags               = 12;
options.hor        = 48;
options.conf_sig   = 0.9;
dm1 = directmethods(y,lags,options);

% Define the IRF of Interest
% index of the shocks of interest (shock to gs1)
indx_sho              = [3];
% Data order
% 1. logip; 2. logcpi; 3. gs1; 4. ebp
% Change the order of the variables for the plot
% 1. gs1; 2. logcpi; 3. logip; 4. ebp
indx_var              = [3, 2, 1, 4];

% PLOT IRF
% Customize the IRF plot
% variables names for the plots
options.varnames      = {'1 year rate','CPI','IP','EBP'};
% names of the directory where the figure is saved
options.saveas_dir    = './dm_plt';
% names of the figure to save
options.saveas_strng  = 'Cholesky';
% name of the shock
options.shocksnames   = {'MP'};
% Compare with BVAR estimates
bvar_ = bvar(y,lags,options);
var_irf_sort = sort(bvar_.ir_draws,4);
% add IRF plot
options.add_irfs(:,:,:,1) = var_irf_sort(indx_var,:,indx_sho,round(bvar_.ndraws*0.95));
options.add_irfs(:,:,:,2) = var_irf_sort(indx_var,:,indx_sho,round(bvar_.ndraws*0.05));
% plot LP
plot_irfs_(dm1.ir_lp(indx_var,:,indx_sho,:),options)

options =rmfield(options,'add_irfs');

%% 2/ IV
% load the instruments
[numi,txti,rawi] = xlsread('../BVAR tutorial/factor_data.csv','factor_data');
% instrument must have the same lenght as the observed data
options.proxy  = nan(length(y),1);
% use the same instrument as GK
% instruments and data end in 2012m6
options.proxy(length(T)- length(numi)+1:end) = numi(:,4);

dm2 = directmethods(y,lags,options);

options0= options;
options0.fontsize =18;
options0.saveas_strng  = 'IV';
options0.nplots = [1 1];
options0.varnames = {'IP','CPI','1 year rate','EBP'};
% finally, the plotting command
norm = dm2.irproxy_lp(3,1,1,2)*4;
plot_irfs_(dm2.irproxy_lp(:,:,1,:)/norm,options0)

options1 = options0;
for vv = 1 :size(y,2)
    dm3 = directmethods (y(:,vv),lags,options);
    options1.saveas_strng  = ['IV_var' num2str(vv)];
    options1.varnames = options0.varnames(vv);
    % finally, the plotting command
    plot_irfs_(dm3.irproxy_lp(:,:,1,:)/norm,options1)
end

%% 3/ Bayesian LP

% run a VAR on presample data
presample = 96; % 8 years of presample
lags      = 12;
bvar_     = bvar(y(1:presample,:),lags);

% use the VAR estimates to set the priors for the LP
options.priors.name        = 'Conjugate';
% posterior mean of the VAR AR coeff and constant
options.priors.Phi.mean    = mean(bvar_.Phi_draws,3);
% average variance of the AR coeff and constant
options.priors.Phi.cov     = diag(mean(var(bvar_.Phi_draws,0,3),2));
% posterior mean of the Covariance of the VAR residuals
options.priors.Sigma.scale = mean(bvar_.Sigma_draws,3);
options.priors.Sigma.df    = size(bvar_.Phi_draws,1)-2;
options.priors.tau         = 0.5*ones(options.hor); %

options.proxy(1:presample,:) =[];

bdm = directmethods(y(presample+1:end,:),lags,options);

options.saveas_strng  = 'BLPCholesky';
% the plotting command
options.conf_sig   = 0.9;
options.fontsize   = 12;
plot_irfs_(bdm.ir_blp(indx_var,:,indx_sho,:),options)

options.saveas_strng  = 'BLPIV';

norm = median(bdm.irproxy_blp(3,1,1,:),4)*4;
% the plotting command
plot_irfs_(bdm.irproxy_blp(indx_var,:,1,:)/norm,options)

%% 4/ Optimize Shrinkage

options.priors.max_tau = 1; %
options.max_compute    = 1; % fmin search
bdm_opt                = directmethods(y(presample+1:end,:),lags,options);

% the plotting command
options.saveas_strng  = 'BLPCholeskyOpt';
plot_irfs_(bdm_opt.ir_blp(indx_var,:,indx_sho,:),options)

% the plotting command
options.saveas_strng  = 'BLPIVOpt';
plot_irfs_(bdm_opt.irproxy_blp(indx_var,:,1,:)*0.25,options)


function Ne = som_neighbors(sM,neigh)

% Ne = som_neighbors(sM,neigh)
%
% sM      (struct) map or data struct
%         (matrix) data matrix, size n x dim
% [neigh] (string) 'kNN' or 'Nk' (which is valid for a SOM only)
%                  for example '6NN' or 'N1'
%                  default is '10NN' for a data set and 'N1' for SOM
%
% Ne      (matrix) size n x n, a sparse matrix
%                  indicating the neighbors of each sample by value 1
%                  (note: the unit itself also has value 0)

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

if isstruct(sM),
  switch sM.type,
   case 'som_map',  M = sM.codebook;
   case 'som_data', M = sM.data; sM = [];
  end
else
  M = sM;
  sM = [];
end

n = size(M,1);

if nargin<2,
  if isempty(sM), neigh = '10NN'; else neigh = 'N1'; end
end

if strcmp(neigh(end-1:end),'NN'),
  k  = str2num(neigh(1:end-2));
  kmus = som_bmus(M,M,1:k+1);
  Ne = sparse(n,n);
  for i=1:n, Ne(i,kmus(i,:)) = 1; end
else
  if ~isstruct(sM), error('Prototypes must be in a map struct.'); end
  k  = str2num(neigh(2:end));
  N1 = som_unit_neighs(sM);
  Ne = sparse(som_neighborhood(N1,k)<=k);
end
Ne([0:n-1]*n+[1:n]) = 0; % remove self from neighbors

return;


% created: Zoya Bylinskii, Jan 2016

% Given a desired sigma blur value, this computes the cut off frequency
% required for the Gaussian low pass filter in the Fourier domain.
% This function runs Antonio's gaussian computation.

function [BF, gf] = run_antonioGaussian(img, sigma)

[sn, sm, c]=size(img);
n=max([sn sm]);

fc = n*sqrt(log(2)/(2*(pi^2)*(sigma^2)));

[BF, gf]=antonioGaussian(img, fc);


 function [alpha, beta, ok] = nufft_best_alpha(J, L, K_N)
%function [alpha, beta, ok] = nufft_best_alpha(J, L, K_N)
%
%	return previously numerically optimized alpha and beta
%	use L=0 to return best available choice of any L
%
%	Copyright 2001-12-17	Jeff Fessler	The University of Michigan

if nargin < 1, help(mfilename), error(mfilename), end
if nargin < 2, L=2; end
if nargin < 3, K_N=2; end

Jlist1 = 6;		% list of which J's
alpha1 = [...		% last colum is best beta
	1 -0.46		0.19;	% J=6
];

Jlist2 = 2:10;		% list of which J's
alpha2 = [...		% last colum is best beta
	1 -0.200 -0.04	0.34;	% J=2
	1 -0.485 0.090	0.48;
	1 -0.470 0.085	0.56;	% J=4
	1 -0.4825 0.12	0.495;
	1 -0.57 0.14	0.43;	% J=6
	1 -0.465 0.07	0.65;
	1 -0.540 0.16	0.47;	% J=8
	1 -0.625 0.14	0.325;	% J=9
	1 -0.57 0.185	0.43;	% J=10 5.9707e-07
];

Jlist3 = [4 6];		% list of which J's
alpha3 = [...		% last colum is best beta
	1 -0.5319 0.1522 -0.0199	0.6339;	% J=4 2.5953e-04
	1 -0.6903 0.2138 -0.0191	0.2254;	% J=6 1.0097e-04
];

if K_N == 2

	if L==0
		if any(J == Jlist3)
			L = 3;
		else
			L = 2;
		end	% current best
	end

	if L==1
		alpha = alpha1;
		Jlist = Jlist1;

	elseif L==2
		alpha = alpha2;
		Jlist = Jlist2;

	elseif L==3
		alpha = alpha3;
		Jlist = Jlist3;

	else
		warning 'L not done'
		alpha = nan;
		beta = nan;
		ok = 0;
		return
	end

else
	warning 'K_N not done'
	alpha = 1;
	beta = 0.5;
	ok = logical(1);
	return
end

if any(J == Jlist)
	j = find(J == Jlist);
	beta = alpha(j,end);
	alpha = alpha(j,1:(end-1));
	ok = logical(1);
else
	ok = logical(0);
	alpha = nan;
	beta = nan;
end


classdef IBEA < ALGORITHM
% <multi/many> <real/integer/label/binary/permutation>
% Indicator-based evolutionary algorithm
% kappa --- 0.05 --- Fitness scaling factor

%------------------------------- Reference --------------------------------
% E. Zitzler and S. Kunzli, Indicator-based selection in multiobjective
% search, Proceedings of the International Conference on Parallel Problem
% Solving from Nature, 2004, 832-842.
%------------------------------- 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".
%--------------------------------------------------------------------------

    methods
        function main(Algorithm,Problem)
            %% Parameter setting
            kappa = Algorithm.ParameterSet(0.05);

            %% Generate random population
            Population = Problem.Initialization();

            %% Optimization
            while Algorithm.NotTerminated(Population)
                MatingPool = TournamentSelection(2,Problem.N,-CalFitness(Population.objs,kappa));
                Offspring  = OperatorGA(Problem,Population(MatingPool));
                Population = EnvironmentalSelection([Population,Offspring],Problem.N,kappa);
            end
        end
    end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Comparison of different learning methods of Hawkes processes
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear

options.N = 200; % the number of sequences
options.Nmax = 100; % the maximum number of events per sequence
options.Tmax = 50; % the maximum size of time window
options.tstep = 0.1;
options.dt = 0.1;
options.M = 250;
options.GenerationNum = 10;
D = 3; % the dimension of Hawkes processes
nTest = 1;
nSeg = 5;
nNum = options.N/nSeg;

disp('Approximate simulation of Hawkes processes via branching process')
disp('Complicated gaussian kernel')
para1.kernel = 'gauss';
para1.w = 1.5;
para1.landmark = 0:4:12;
L = length(para1.landmark);
para1.mu = rand(D,1)/D;
para1.A = zeros(D, D, L);
for l = 1:L
    para1.A(:,:,l) = (0.5^l)*(0.5+rand(D));
end
para1.A = 0.9*para1.A./max(abs(eig(sum(para1.A,3))));
para1.A = reshape(para1.A, [D, L, D]);
Seqs1 = Simulation_Branch_HP(para1, options);
%Seqs1 = Simulation_Thinning_HP(para1, options);

%%
disp('Learning Hawkes processes via different methods')
alg1.LowRank = 0;
alg1.Sparse = 1;
alg1.alphaS = 1;
alg1.GroupSparse = 0;
alg1.outer = 5;
alg1.rho = 0.1;
alg1.inner = 8;
alg1.thres = 1e-5;
alg1.Tmax = [];
alg1.storeErr = 0;
alg1.storeLL = 0;

alg2.alpha = 10000;
alg2.inner = 3;
alg2.inner_g = 100;
alg2.outer = 8;
alg2.thres = 1e-5;
alg2.Tmax = [];
Err = zeros(nTest, nSeg);

for n = 1:nTest
    for i = nSeg

        [A, Phi] = ImpactFunc( para1, options );

        disp('Maximum likelihood estimation and basis representation')
        model1 = Initialization_Basis(Seqs1);
        model1 = Learning_MLE_Basis( Seqs1(1:i*nNum), model1, alg1 );
        [A1, Phi1] = ImpactFunc( model1, options );

        disp('Maximum likelihood estimation and ODE')
        model2.M = 1000;
        model2.D = 2;
        model2.dt = 0.02;
        model2.g = rand(model2.M, model2.D);
        model2.g = model2.g./repmat(sum(model2.g),[model2.M,1]);
        model2.A = rand(D, model2.D, D)./(model2.D*D^2);
        model2.mu = rand(D,1)./D;
        model2 = Learning_MLE_ODE( Seqs1(1:i*nNum), model2, alg2 );
        [A2, Phi2] = ImpactFunc_ODE( model2 );

        disp('Least squares and discretization')
        model3.D = D;
        model3.h = 1;
        model3.k = floor(options.M * options.dt/model3.h);
        model3 = Initialization_Discrete(Seqs1(1:i*nNum));
        model3 = Learning_LS_Discrete( Seqs1(1:i*nNum), model3 );

        figure
        title('Complicated Gaussian kernels')
        for u = 1:D
            for v = 1:D
                subplot(D,D,D*(u-1)+v)
                hold on
                plot(options.dt*(0:(size(Phi,2)-1)), Phi(v,:,u), '-')
                plot(options.dt*(0:(size(Phi1,2)-1)), Phi1(v,:,u), '-')
                plot(options.dt*(0:(size(Phi2,2)-1)), Phi2(v,:,u), '-')
                plot(model3.h*(0:(size(model3.A,2)-1)), model3.A(v,:,u), '-')
                hold off
                axis tight
                legend('Real', 'MLE-Basis', 'MLE-ODE', 'LS')
                xlabel('Time interval between events')
                ylabel(['\phi', sprintf('%d%d', u, v)])
            end
        end

    end
end


function [unitPos, unitSize] = getFootPrintRez( rez )

%for testing standalone
% load('C:\Users\labadmin\Documents\emouse_drift\nodrift_sn_series\rand_pos_2X_KS2_release\rc03_rezFinal.mat')

%input rez from KS1 or KS2, return array of unit "sizes"
%sites included in unit defined as those with abs(1st component of U) >
% 0.1*max(abs(U(:,1))
% size = diagonal of rectangle that contains the center of the sites, i.e.
% sqrt( (maxY-minY)^2 + (maxX-minX)^2 );

U = rez.U;
[nChan, nClu, nPC] = size(U);
unitPos = zeros(nClu,1);
unitSize = zeros(nClu,1);

nDist = 30;     %neighbor distance, in um
incFrac = 0.1;    %included sites have projection onto first PC this fraction of max

for j = 1:nClu
    currU = U(:,j,1);
    [maxU, maxI] = max(currU);
    [minU, minI] = min(currU);
    maxP = maxU - minU;
    unitPos(j) = rez.yc(maxI);
    inclSite = find(abs(currU) > incFrac*maxP);
    inclDist=[];
    for k = 1:numel(inclSite)
        inclDist(k) = sqrt( (rez.yc(inclSite(k)) - rez.yc(maxI))^2 + ...
                       (rez.xc(inclSite(k)) - rez.xc(maxI))^2 );
    end
    [sortDist, ~] = sort(inclDist);

    nextNearest = 0;
    currI = 1;
    while ((nextNearest < nDist) && currI < numel(inclDist))
        currI = currI + 1;
        nextNearest = sortDist(currI)-sortDist(currI-1);
    end
    if( nextNearest > nDist )
        %then last site tested was not contiguous with other included sites
        currI = currI - 1;
    end
    %fprintf( 'cluIndex, numIncl, currI: %d, %d, %d\n', j, numel(inclSite),currI);
    %unit radius est = sortDist(currI)
    unitSize(j) = 2*sortDist(currI);

end

end


function x = rotatearound(x0,theta,mu)

[n1,n2] = size(x0);
[m1,m2] = size(mu);
theta = -theta;
R = [cos(theta),  sin(theta),
     -sin(theta), cos(theta)];
didflip = false;
if n1 ~= 2 & n2 == 2,
  x0 = x0';
  n2 = n1;
  didflip = true;
end;
if m1 ~= 2 & m2 == 2,
  mu = mu';
  m2 = m1;
end;

if m2 ~= n2,
  mu = repmat(mu(:,1),[1,n2]);
end;

x = R * (x0 - mu) + mu;
if didflip,
  x = x';
end


function [VM, h, fit, e, param] = Det_Logit(V0,t,tc,Run)
%
% [theta,HH,C,P] = Anneal_Logit(theta0,t,tc,Run)
%
% Estimate inverse logit (IL) HRF model
% Creates fitted curve - 3 logistic functions to be summed together - from parameter estimates
%
% INPUT: V0, t, tc, Run
% Run = stick function
% tc = time course
% t = vector of time points
% V0 = initial value for the parameter vector
%
% By Martin Lindquist and Tor Wager
% Edited 10/01/09
%

% Find optimal values
options = optimset('MaxFunEvals',10000000,'Maxiter',10000000,'TolX',1e-8,'TolFun',1e-8,'Display','off');
VM = fminsearch(@msq_logit,V0,options,Run,t,tc);
VM

% Use optimal values to fit hemodynamic response functions
h = il_hdmf_tw2(t,VM(1:7));

%[param] = get_parameters2(h,t);
[param] = get_parameters_logit(h,t,VM(1:7));

len = length(Run);
fit = conv(Run, h);
fit = fit(1:len);

e = tc-fit;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   SUBFUNCTIONS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function m=msq_logit(V,Run, t, tc)

HR = il_hdmf_tw2(t,V(1:7));
len = length(Run);
timecourse = conv(Run, HR);
timecourse = timecourse(1:len);

m=sum((tc-timecourse).^2);

end

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

function [h,base] = il_hdmf_tw2(t,V)
% inverse logit -- creates fitted curve from parameter estimates
%
% t = vector of time points
% V = parameters

% 3 logistic functions to be summed together
base = zeros(length(t),3);
A1 = V(1);
T1 = V(2);
d1 = V(3);
A2 = V(4);
T2 = V(5);
A3 = V(6);
T3 = V(7);
d2 = -d1*(ilogit(A1*(1-T1)) - ilogit(A3*(1-T3)))/(ilogit(A2*(1-T2)) + ilogit(A3*(1-T3)));
d3 = abs(d2)-abs(d1);

base(:,1)= d1*ilogit(A1*(t-T1))';
base(:,2)= d2*ilogit(A2*(t-T2))';
base(:,3)= d3*ilogit(A3*(t-T3))';
h = sum(base,2)';

end

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

function [L] = ilogit(t)
L = exp(t)./(1+exp(t));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% function [param] = get_parameters2(hdrf,t)
% % Find model parameters
% %
% % Height - h
% % Time to peak - p (in time units of TR seconds)
% % Width (at half peak) - w
%
% % Calculate Heights and Time to peak:
%
% n = ceil(t(end)*0.8);
% [h,p] = max(abs(hdrf(1:n)));
% h = hdrf(p);
%
% if (h >0)
%     v = (hdrf >= h/2);
% else
%     v = (hdrf <= h/2);
% end;
%
% [a,b] = min(diff(v));
% v(b+1:end) = 0;
% w = sum(v);
%
% cnt = p-1;
% g =hdrf(2:end) - hdrf(1:(end-1));
% while((cnt > 0) & (abs(g(cnt)) <0.001)),
%     h = hdrf(cnt);
%     p = cnt;
%     cnt = cnt-1;
% end;
%
% param = zeros(3,1);
% param(1) = h;
% param(2) = p;
% param(3) = w;
%
% end

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


function paf = graph2paf(nodes, edges, sz, channelsOnly, sigma)
%GRAPH2PAF Converts a set of edges into part affinity fields.
% Usage:
%   graph2paf(nodes, edges, sz, sigma)
%
% Args:
%   nodes: set of points (N x 2)
%   edges: indices into nodes defining directed edges (E x 2)
%   sz: grid/image size (1 x 2)
%   channelsOnly: stack all PAFs along channels (dim 3) instead of dim 4 (default: true)
%   sigma: maximum distance from edge to keep (default: 5)
%
% Returns:
%   paf: part affinity fields (sz(1) x sz(2) x 2E) or (sz(1) x sz(2) x 2 x E)
%
% See also: pts2confmaps

if nargin < 4 || isempty(channelsOnly); channelsOnly = true; end
if nargin < 5 || isempty(sigma); sigma = 5; end

% Create image coordinate grid
[XX,YY] = meshgrid(1:sz(2), 1:sz(1));

% Create PAFs for each edge
E = size(edges,1);
paf = cell(E,1);
for i = 1:E
    % Pull out edge points
    src = nodes(edges(i,2),:);
    dst = nodes(edges(i,1),:);

    % Edge length
    L = norm(dst - src, 2);

    % Unit vectors
    V = (dst - src) ./ L; % pointing along edge
    Vp = [-V(:,2), V(:,1)]; % perpendicular

    % Signed distance along edge
    D1 = sum(V .* ([XX(:) YY(:)] - src),2);

    % Absolute distance orthogonal to edge
    D2 = abs(sum(Vp .* ([XX(:) YY(:)] - src),2));

    % Vector field mask
    paf_mask = reshape(D1 >= 0 & D1 <= L & D2 <= sigma, sz);

    % Create vector field along channels (X and Y)
    paf{i} = paf_mask .* permute(V, [1 3 2]);
end

% Merge all edge PAFs
if channelsOnly
    paf = cat(3, paf{:});
else
    paf = cat(4, paf{:});
end

end