%==============================================================================
%
% function [yc,His] = lBFGS(fctn,yc,varargin)
%
% limited BFGS optimizer
%
% Input:
% ------
%   fctn           function handle
%   yc          starting guess
%   varargin    optional parameter, see below
%
% Output:
% -------
%   yc          numerical optimizer (current iterate)
%   His         iteration history
%==============================================================================

function [yc,His] = lBFGS(fctn,yc,varargin)

if nargin ==0, % help and minimal example
  help(mfilename);
  E9_MRIhead_MLIRlBFGS_NGF_mbElas;
  yc = 'endOfMinimalExample';
  His = [];
  return;
end;

% parameter initialization -----------------------------------------------
maxIter      = 10;              % maximum number of iterations
tolJ         = 1e-3;            % for stopping, objective function
tolY         = 1e-2;            %   - " -     , current value
tolG         = 1e-2;            %   - " -     , norm of gradient
solver       = regularizer;
maxLBFGS     = 5;              % maximum number of BFGS vectors
LSmaxIter    = 10;              % maximum number of line search iterations
LSreduction  = 1e-4;            % minimal reduction in line search
vecNorm      = @norm;           % norm to be used for dJ and dy
yStop        = [];              % used for stopping in multi-level framework
Jstop        = [];              %
Plots        = @(iter,para) []; % for plots;

for k=1:2:length(varargin),     % overwrites default parameter
  eval([varargin{k},'=varargin{',int2str(k+1),'};']);
end;
objFctn = fctn([]);

if isempty(yStop), yStop  = yc; end; % yStop used for stopping only
% -- end parameter set-up   ----------------------------------------------

% some output
FAIRmessage([mfilename '(JM 2009/01/31)']);
fprintf('[ maxIter=%d / maxLBFGS=%d / tolJ=%s / tolY=%s / tolG=%s / length(yc)=%d ]\n',...
  maxIter,maxLBFGS,num2str(tolJ),num2str(tolY),num2str(tolG),length(yc));

% -- initialize  ---------------------------------------------------------
STOP = zeros(5,1);

zBFGS = [];     % memory for BFGS gradient directions
sBFGS = [];     % memory for BFGS directions
nBFGS  = 0;     % counter for number of limited BFGS directions

if isempty(Jstop),
  % evaluate objective function for stopping values and plots
  [Jstop,para] = fctn(yStop); Jstop = abs(Jstop) + (Jstop == 0);
  Plots('stop',para);
end;

% evaluate objective function for starting values and plots
[Jc,para,dJ,H0] = fctn(yc);
Plots('start',para);
iter = 0; yOld = 0*yc; Jold = Jc; y0 = yc;

hisStr    = {'iter','J','Jold-J','|\nabla J|','|dy|','LS'};
his        = zeros(maxIter+2,6);
his(1,1:3) = [-1,Jstop,Jstop-Jc];
his(2,:)   = [0,Jc,Jstop-Jc,vecNorm(dJ),vecNorm(yc-yStop),0];

% some output
fprintf('%4s %-12s %-12s %-12s %-12s %4s\n%s\n',...
  hisStr{:},char(ones(1,64)*'-'));
dispHis = @(var) ...
  fprintf('%4d %-12.4e %-12.3e %-12.3e %-12.3e %4d\n',var);
dispHis(his(1,:));
% -- end initialization   ------------------------------------------------

% ==============================================================================
% MAIN LOOP
% ==============================================================================
while 1,
  % check stopping rules
  STOP(1) = abs(Jold-Jc)  <= tolJ*(1+abs(Jstop));
  STOP(2) = (iter>0) && (norm(yc-yOld) <= tolY*(1+norm(y0)));
  STOP(3) = norm(dJ)      <= tolG*(1+abs(Jstop));
  STOP(4) = norm(dJ)      <= 1e3*eps;
  STOP(5) = (iter >= maxIter);
  if all(STOP(1:3)) || any(STOP(4:5)), break;  end;

  iter      = iter + 1;

  % update at most maxLBFGS BFGS directions
  if iter > 1,
    zz = (dJ - dJold)';
    ss =  yc - yOld;
    if zz'*ss > 0,
      start = 2-(nBFGS<maxLBFGS);
      zBFGS = [zBFGS(:,start:end),zz];
      sBFGS = [sBFGS(:,start:end),ss];
      nBFGS = min(maxLBFGS,nBFGS+1);
    else
      warning('   y''*s < 0, skip update');
    end;
  end;

  % compute search direction using recursive and limited BFGS
  dy = bfgsrec(solver,nBFGS,sBFGS,zBFGS,H0,-dJ');
  if iter == 1,
    if strcmp(objFctn,'NPIR'),
      m     = para.m;
      omega = para.omega;
      dim   = length(para.omega)/2;
      maxdy = norm(sqrt(sum(reshape(center(dy,m),[],dim).^2,2)),'inf');
      fac   = 0.5*max((omega(2:2:end)-omega(1:2:end)));
      if maxdy>fac,
        dy = (fac/maxdy)*dy;
        %H0 = fac*H0;%speye(length(dy),length(dy));
      end;
    else
      H0 = norm(dJ) * speye(length(dy),length(dy));
    end;
  end;
  % perform Armijo line-search
  [t,yt,LSiter] = Armijo(fctn,yc,dy,Jc,dJ,...
        'LSmaxIter',LSmaxIter,'LSreduction',LSreduction);
  if (t == 0),
    break;
  end; % break if line-search fails

  % update variables
  yOld = yc; Jold = Jc; dJold = dJ; yc = yt;
  [Jc,para,dJ] = fctn(yc);  % evaluate objective function

  % some output
  his(iter+2,:) = [iter,Jc,Jold-Jc,vecNorm(dJ),vecNorm(yc-yOld),LSiter];
  dispHis(his(iter+1,:));
  para.normdY = vecNorm(yc - yOld);
  Plots(iter,para);

end;%while; % end of iteration loop
% ==============================================================================

% clean up
His.str = hisStr;
His.his = his(1:iter+2,:);
fprintf('STOPPING:\n');
fprintf('%d[ %-10s=%16.8e <= %-25s=%16.8e]\n',STOP(1),...
  '(Jold-Jc)',(Jold-Jc),'tolJ*(1+|Jstop|)',tolJ*(1+abs(Jstop)));
fprintf('%d[ %-10s=%16.8e <= %-25s=%16.8e]\n',STOP(2),...
  '|yc-yOld|',norm(yc-yOld),'tolY*(1+norm(yc)) ',tolY*(1+norm(yc)));
fprintf('%d[ %-10s=%16.8e <= %-25s=%16.8e]\n',STOP(3),...
  '|dJ|',norm(dJ),'tolG*(1+abs(Jstop)',tolG*(1+abs(Jstop)));
fprintf('%d[ %-10s=%16.8e <= %-25s=%16.8e]\n',STOP(4),...
  'norm(dJ)',norm(dJ),'eps',1e3*eps);
fprintf('%d[ %-10s=  %-14d >= %-25s=  %-14d]\n',STOP(5),...
  'iter',iter,'maxIter',maxIter);

FAIRmessage([mfilename,' : done !']);

%------------------------------------------------------------------------------

function[d] = bfgsrec(solver,n,S,Z,H,d)

maxIterCG = 10; tolCG = 1e-2;
if isempty(solver)
  if isstruct(H),
    if isfield(H,'solver'),
      solver = H.solver;
    elseif isfield(H,'d2S') && isfield(H.d2S,'solver'),
      solver = H.d2S.solver;
    else
      error('solver has not been defined')
    end;

  end
end

if n == 0,
  switch solver,
    case {'MG-elastic'}
        d = MGsolver(d,H);
    case {'pcg'}
      L   = tril(H); % Symmetric Gauss Seidel Preconditioning,
      D   = diag(H); % L is lower, D is diagonal, U = L'
      SGS = @(x) L\(D.*(L'\x));
      d   = pcg(H,d,tolCG,maxIterCG,SGS);
    case 'PCG-curvature',
      M     = @(x) H.d2D.M;
      Afctn = @(x) M(x) + H.d2S.d2S(x,H.omega,H.m);
      % preconditioner
      Ddiag = H.d2D.M;
      D = Ddiag  +  H.d2S.diag(H.omega,H.m);
      PC = @(x) D.\x; % Jacobi preconditioner
      [d,flag,relres,iter] = pcg(Afctn,d,tolCG,maxIterCG,PC);

    otherwise,
      if isnumeric(H),
        % if H is a matrix, solve the linear system using MATLAB's backslash
        d = H\d;
      else
        error('nyi - solver %s', solver)
      end;
  end;
else
  alpha = (S(:,n)'*d)/(Z(:,n)'*S(:,n));
  d     = d - alpha*Z(:,n);
  d     = bfgsrec(solver,n-1,S,Z,H,d);
  d     = d + (alpha - (Z(:,n)'*d)/(Z(:,n)'*S(:,n)))*S(:,n);
end;
%==============================================================================


 function [hyp, nlZ, i] = trainLMGP(hyp0, inf, mean, cov, lik, input, target, inputDer, targetDer, deriveVar)
% trainLMGP - Function for the optimization (training) of LMGP model
% hyperparameters based on the training data via maximum marginal
% likelihood.
%
%% Syntax
%  function [hyp, nlZ, i] = trainlmgp(hyp, inf, mean, cov, lik, input, target, inputDer, targetDer, deriveVar, hyp0)
%
%% Description
%
% Function for the optimization (training) of LMGP model hyperparameters based on the training data via maximum
% marginal likelihood. It can be used only with the Gaussian covariance function and
% with the white noise model (sum of covSEard and covNoise).
% Uses routines gpSD00 and minimize.
% Based on the work of C.E.Rasmussen and R. Murray-Smith.
%
% Input:
% * hyp            ... the struct of hyperparameters
% * inf      	   ... the inference method 	      --> not used, for interface compatibility only
% * cov      	   ... the prior covariance function  --> not used, for interface compatibility only
% * mean    	   ... the prior mean function        --> not used, for interface compatibility only
% * lik      	   ... the likelihood function        --> not used, for interface compatibility only
% * input          ... the input part of the training data,  NxD matrix
% * target         ... the output part of the training data (ie. target), Nx1 vector
% * derivinput     ... the input part of the derivative training data, NEQxD matrix
% * derivtarget    ... target derivatives, NEQxD matrix
% * derivevariance ... variances of the local model prameters, NEQxD matrix
% * hyp0           ... intial hyperparameters (optional)
%
% Output:
% * loghteta       ... optimised hyperparameters
% * flogtheta      ... the minus log likelihood for the different runs (init. to 0)
% * i              ... the number of iterations needed for the last optimization
%
% See Also
% minimize.m, gpSD00.m, trainGP.m
%
% Examples
% demo_example_LMGP_training.m

fun_name = 'trainLMGP';

[n D] = size(target);
[nd D] = size(targetDer);

  if ~isstruct(hyp0)
    hyp0.cov = -rand(D+1,1);
    hyp0.lik = -rand(1,1);
  end
nlZ = 0;

[hyp, nlZtmp, i] = minimize(hyp0, 'gpSD00', -200, inf, mean, cov, lik, input,target, NaN*ones(n,1),...
    inputDer,targetDer, deriveVar);

if isempty(nlZtmp)
    nlZ = nlZ;
else
    nlZ = [nlZ nlZtmp(end)];
end

while abs(nlZ(end) - nlZ(end-1)) > 0.001
	[hyp, nlZtmp, i] = minimize(hyp, 'gpSD00', -200, inf, mean, cov, lik, input,target,NaN*ones(n,1),...
		inputDer,targetDer, deriveVar);
	if isempty(nlZtmp) % no improvement: at minimum
	  break
	end
	nlZ = [nlZ nlZtmp(end)];
end
if exp(hyp.lik) < 1e-6
  hyp.lik =log(1e-6);
end


function plotline(varargin)
%PLOTLINE Plot points specified by [x,y] pairs.
% Function PLOTLINE accepts an arbitrary number of
% [x,y] points and plots a line connecting them.
% In addition, it can accept a line specification
% string, and pass that string on to function plot.

% Define variables:
%   ii        -- Index variable
%   jj        -- Index variable
%   linespec  -- String defining plot characteristics
%   msg       -- Error message
%   varargin  -- Cell array containing input arguments
%   x         -- x values to plot
%   y         -- y values to plot
%
%  Record of revisions:
%      Date       Programmer          Description of change
%      ====       ==========          =====================
%    03/05/07    S. J. Chapman        Original code

% Check for a legal number of input arguments.
% We need at least 2 points to plot a line...
msg = nargchk(2,Inf,nargin);
error(msg);

% Initialize values
jj = 0;
linespec = '';

% Get the x and y values, making sure to save the line
% specification string, if one exists.
for ii = 1:nargin

   % Is this argument an [x,y] pair or the line
   % specification?
   if ischar(varargin{ii})

      % Save line specification
      linespec = varargin{ii};

   else

      % This is an [x,y] pair.  Recover the values.
      jj = jj + 1;
      x(jj) = varargin{ii}(1);
      y(jj) = varargin{ii}(2);

   end
end

% Plot function.
if isempty(linespec)
   plot(x,y);
else
   plot(x,y,linespec);
end


errData = data2plot;

clear ph
ccolors = [1 0 0; 0 1 0; 0.7,0.7,1];
symbols = {'o', 'd', 's'};
xx = 1:0.1:11;
yy = zeros(3,length(xx));
for iM = 1:3
    if iM == 2
        xm = zeros(1,N_ETA);
        for k = 1:N_ETA
            TF = isnan(errData(1:Nr,k,iM));
            xm(k) = median(errData(TF==0,k,iM),1);
        end
    else
        xm = median(errData(1:Nr,:,iM),1);
    end
    yy(iM,:) = spline(1:11,xm,xx);
end
figure; hold on
if shaded_region == 1
    fillh1 = fill([0.1 11.9 11.9 0.1], [10 10 ylimregion.*ones(1,2)],0.9*ones(1,3));
    fillh1.EdgeColor = 0.9*ones(1,3); fillh1.FaceAlpha = 0.5;
end
ph(1)=plot(xx,yy(1,:),'-r','LineWidth',1); hold on,
ph(2)=plot(xx(1:end),yy(2,1:end),'-g','LineWidth',1);
ph(3)=plot(xx(1:end),yy(3,1:end),'-','Color',[0.7,0.7,1],'LineWidth',1);
for iM = 1:3
    boxplot(errData(:,:,iM),'PlotStyle','compact','Colors',ccolors(iM,:), 'Symbol', symbols{iM}, ...
        'Widths',0.1); hold on
    delete(findobj(gca,'Type','text'))
end
set(gca,'xtick',[1:2:11],'xticklabel',num2str(eta_vec(1:2:end)'),'Position',[0.2 0.22 0.75 0.73])
xlim([0 12]), ylim(yaxlim)

if exist('LOG_SCALE')
    if LOG_SCALE == 1
        set(gca,'YScale','log')
        ylim([10^-3 yaxlim(2)])
        set(gca,'ytick',[10.^[-3:1:1]])
    end
end
xt = xlabel('Eta'); xt.Position = [115 -20 -0.1];
ylabel(ytext)
set(gca,'LineWidth',1, 'FontSize',14)
set(gcf,'Position',[100 100 300 200])
set(gcf,'PaperPositionMode','auto'),
print('-depsc2', '-painters', '-loose', '-cmyk', [figpath,'EX_LOTKA_PREDPERF_',InputSignalType,'_N',sprintf('%04g',Ntrain_vec(iN)),'_noise_',NARXtraining,'_',PostName,'_noleg.eps']);

l1 = legend(ph,'DMDc','SINDYc','NARX');
if exist('LegLoc')==1
    set(l1,'Location',LegLoc)
else
    set(l1,'Location','NorthWest')%'NorthWest')SouthEast
    l1.Position = [l1.Position(1)-0.01 l1.Position(2)+0.02 l1.Position(3)-0.01 l1.Position(4)];
end
print('-depsc2', '-painters', '-loose', '-cmyk', [figpath,'EX_LOTKA_PREDPERF_',InputSignalType,'_N',sprintf('%04g',Ntrain_vec(iN)),'_noise_',NARXtraining,'_',PostName,'.eps']);


function [ know, x ] = p09_sol ( n )

%*****************************************************************************80
%
%% P09_SOL returns the solution for problem 9.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 October 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the problem.  This value
%    is only needed for those problems with variable N.
%
%    Output, integer KNOW.
%    If KNOW is 0, then the solution is not known.
%    If KNOW is positive, then the solution is known, and is returned in X.
%
%    Output, real X(N), the solution, if known.
%
  know = 0;

  x = zeros ( n, 1 );

  return
end


%   Matlab script to input initial parameters for genas and genascum
%
%                                                R. Zuniga, 4/94

report_this_filefun(mfilename('fullpath'));

minmg = minma;
maxmg = maxma;
magstep = 0.5
%
if isempty(newcat), newcat = a; end   % verify whether to start with
% original catalogue
% make the interface for input
%
figure_w_normalized_uicontrolunits(mess)
clf
set(gcf,'Name','Genas Control Panel');
%  set(gcf,'visible','off');
set(gca,'visible','off');
set(gcf,'pos',[ 0.02  0.6 0.35 0.35])
%par1 = ((teb-t0b)*365)/100;
%
freq_field2=uicontrol('Style','edit',...
    'Position',[.80 .60 .15 .10],...
    'Units','normalized','String',num2str(minmg),...
    'Callback','minmg=str2double(get(freq_field2,''String'')); set(freq_field2,''String'',num2str(minmg));');

freq_field3=uicontrol('Style','edit',...
    'Position',[.80 .45 .15 .10],...
    'Units','normalized','String',num2str(maxmg),...
    'Callback','maxmg=str2double(get(freq_field3,''String'')); set(freq_field3,''String'',num2str(maxmg));');

freq_field=uicontrol('Style','edit',...
    'Position',[.80 .30 .15 .10],...
    'Units','normalized','String',num2str(magstep),...
    'Callback','magstep=str2double(get(freq_field,''String'')); set(freq_field,''String'',num2str(magstep));');

uicontrol('Style','Pushbutton',...
    'Position',[.80 .05 .15 .15 ],...
    'Units','normalized','Callback','web([''file:'' hodi ''/zmapwww/chap8.htm#997197''])','String','Info');

close_button=uicontrol('Style','Pushbutton',...
    'Position',[.60 .05 .15 .15 ],...
    'Units','normalized','Callback','welcome','String','Cancel');

genas_button1=uicontrol('Style','Pushbutton',...
    'Position',[.20 .05 .15 .15 ],...
    'Units','normalized',...
    'Callback','welcome,gogenas',...
    'String','Genas');

% genas_button2=uicontrol('Style','Pushbutton',...
%     'Position',[.40 .05 .15 .15 ],...
%     'Units','normalized',...
%     'Callback','welcome,inmakegr',...
%     'String','GenGrid');

txt5 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.65 0 ],...
    'Rotation',0 ,...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'Fontweight','bold',...
    'String','Minimum magnitude:');

txt4 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.48 0 ],...
    'Rotation',0 ,...
    'Fontweight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Maximum magnitude:');

txt1 = text(...
    'Color',[0 0 0 ],...
    'EraseMode','normal',...
    'Position',[0. 0.31 0 ],...
    'Rotation',0 ,...
    'Fontweight','bold',...
    'FontSize',ZmapGlobal.Data.fontsz.m ,...
    'String','Magnitude increment (step):');

set(gcf,'visible','on');


% batch_computeEntropy.m

dirPath = '/Volumes/deasylab1/Data/NSCLC Study';

dirPath = '/Users/aptea/Documents/MSKCC/Projects/Entropy_test';

%structureName = 'totallung';
structureName = 'ptv';

%Find all CERR files
fileC = {};
if strcmpi(dirPath,'\') || strcmpi(dirPath,'/')
    filesTmp = getCERRfiles(dirPath(1:end-1));
else
    filesTmp = getCERRfiles(dirPath);
end
fileC = [fileC filesTmp];

filesNotConvertedC = {};
etrpy = {};

%Loop over CERR plans
for iFile = 1:length(fileC)

    drawnow

    global planC stateS

    try
        planC = loadPlanC(fileC{iFile},tempdir);
        planC = updatePlanFields(planC);
        indexS = planC{end};
    catch
        continue
    end

    % Combine Iliacs
    structure_index = find(strcmpi(structureName,{planC{indexS.structures}.structureName}));

    if length(structure_index) > 1
        structure_index = structure_index(1);
    end

    if isempty(structure_index)

        filesNotConvertedC = [filesNotConvertedC, fileC{iFile}];
        continue;

    end

    doseNum = 1;

    % Check Units
    if any(strcmpi(planC{indexS.dose}(doseNum).doseUnits,{'cgy','cgrays','cgray'}))
        planC{indexS.dose}(doseNum).doseArray = planC{indexS.dose}(doseNum).doseArray / 100;
    end

    % Get scan associated with this structure
    scanNum = getStructureAssociatedScan(structure_index, planC);

    % Get structure mask
    [rV, cV, sV] = getUniformStr(structure_index, planC);

    % Get uniformized coords
    [xV, yV, zV] = getUniformScanXYZVals(planC{indexS.scan});

    % Get dose at structure locations
    dosesV = getDoseAt(doseNum, xV(cV), yV(rV), zV(sV), planC);

    % Get DVH
    %[planC, doseBinsV, volsHistV] = getDVHMatrix(planC, structure_index, doseNum);

    % Calculate Entropy
    [jnk,fName] = fileparts(fileC{iFile});
    etrpy{iFile,1} = fName;
    % etrpy{iFile,2} = entropy(dosesV./max(dosesV));
    % Manual Entrop calculation
    dose_hist = hist(dosesV,256);
    dose_hist(dose_hist == 0) = [];
    dose_hist = dose_hist./numel(dosesV);
    etrpy{iFile,2} = -sum(dose_hist.*log2(dose_hist));

    clear global planC stateS

end


function classifier = laprlsc(options,data)
% {laprlsc} trains a Laplacian RLSC.
%
%      classifier = laprlsc(options,data)
%
%      Note: This function is only a wrapper to 'lapsvmp', where the use of
%            a Hinge function for labeled data is disabled. See 'lapsvmp'
%            for the description of all required parameters.
%
% Author: Stefano Melacci (2009)
%         mela@dii.unisi.it

options.Hinge=0;
classifier=lapsvmp(options,data);
classifier.name='laprlsc';


function F_enhance= RSWHEg_gray( F )
% Bi Bi histogram equalization with recursively seperated weighted histgram
% equalization with mean and mean
% clear all;
% close all;
% clc;
%close figure;
% x0=imread('pout.tif');
%x0=imread('eswar.jpg');
% x0=imread('54.tif');
% x0=imread('source24_1.tif');
% figure;
% imshow(x0);
% x0=imread('untitled.bmp');
 %x0=imread('plane.bmp');
%x0=uint8(x0);
%
%  %x0=imread('12.bmp');
% %u=double(i);
% h = [0.0086,0.0856,0.0086;
%      0.0856,0.8561,0.0856;
%      0.0086,0.0856,0.0086];
% h = h/sum1(h(:));  % Normalize the filter
% uSmooth = conv2padded(double(x0),double(h));
%figure(1);
%imshow(uint8(uSmooth));
 %luma=uint8(uSmooth(:,:,1));
%  XM=0;
% y0=rgb2ycbcr(x0);
luma=F;%(y0(:,:,1));
%luma=wiener2(luma);
%luma=luma-60;
[m,n]=size(luma);
%luma=luma;
% cb=y0(:,:,2);
% cr=y0(:,:,3);
k=mean(mean(luma));
XM=k;
XG=round(255/2);
[pixelCounts bins] = imhist(luma, 256);
[m12,xmax]=max(imhist(luma,256));
[m21,xmin]=min(imhist(luma,256));
Pmax=(max(imhist(luma,256))/(m*n));
Pmin=(min(imhist(luma,256))/(m*n));
beta=Pmax*((abs(XM-XG))/(xmax-xmin));
r=round(k);
l=length(luma(luma<=r));
         listindex=find(luma<=r);
 k1=reshape(luma(listindex),l,1);%obtained below fist mean values put it into an arry
 k2=mean(k1);%find mean of mean in first half
 k3=round(k2);%round to nearest integer to find pdf and cdf till first quarter
  sum1=0;
 l1=length(luma(luma<=k3));%find all  values in luma falls below fist mean
 listindex1=find(luma<=k3);%all  values in luma falls below fist mean given in their locations
 k4=reshape(luma(listindex1),l1,1);%arrange all fist mean values in a vector
     xpdf=hist(k4,[0:k3]);%pdf from 0:r
     xpdf=xpdf/(m*n);
     %alpa0=max(cumsum(xpdf/(m*n)));%from line 39 to 48 new rswhe code add this to other quarters
     alpa=(cumsum(xpdf));
     alpa0=alpa(end);
      %xpdf=xpdf/l1;%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form 0 to r.
      sum1=0;
      for l2=0:k3

          pw(l2+1)=(Pmax*((xpdf(l2+1)-Pmin)/(Pmax-Pmin))).^alpa0+beta;
          sum1=sum1+pw(l2+1);
      end
       for l2=0:k3
          pwn(l2+1)=pw(l2+1)/(sum1);
      end
      %plot(pwn);
      %(imhist(luma));
      %xlabel('gray levels up to mean');
      %ylabel('pdf up to mean');
      %title('histogram for half an image up to mean');
      %sk=xpdf*triu(ones(k3+1));
      sk=pwn*triu(ones(k3+1));
%       figure(2);
%       plot(sk);
%       xlabel('gray levels upto 1st mean');
%       ylabel('cdf upto mean');
%       title('cdf for half  of an image up to ist mean');
     % alpha=0.7;
      for l2=0:k3
          if(xpdf(l2+1)>0)
              list1=find(k4==l2);%find value in an vector i.e converted from matrix
              %list(list1)=alpha*sk(l2+1)*(k3+1)+(1-alpha)*(k3+1);
              list(list1)=(sk(l2+1)*(k3+1));%map dont disturb to get bhe as
              %list(list1)=alpha*sk(l2+1)*(k3+1)+(1-alpha)*(k3+1);
              %it is 13/3/2011
              ert(l2+1)=(sk(l2+1)*(k3+1));
          end
      end
          p=zeros(m,n);
      p(listindex1)= list; %listindex1 mxn locations list transformed values.
%      figure(3);
%      imshow(p);
%      xlabel('gray levels up to first mean');
%       ylabel('luma component equilized image up to first mean');
%      title('processed luma image up to first mean');
     k=mean(mean(luma));
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%2nd quarter
r=round(k);
l=length(luma(luma<=r));
        listindex=find(luma<=r);
 k1=reshape(luma(listindex),l,1);%obtained below fist mean values put it into an arry
 k2=mean(k1);%find mean of mean in first half
 k3=round(k2);%round to nearest integer to find pdf and cdf till first quarter
%   sum1=0;
   b=k3;
%  l2=length(luma(luma>k3));%find all  values in luma falls below fist mean
  listindex2=find((luma>k3)&(luma<=r));%all  values in luma falls below fist mean given in their locations
  l2=length(listindex2);
  k5=reshape(luma(listindex2),l2,1);%arrange all fist mean values in a vector
      x2pdf=hist(k5,[k3+1:r]);%pdf from 0:r
       x2pdf=x2pdf/(m*n);%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form 0 to r.
       %alpa1=max(cumsum(x2pdf/(m*n)));%from line 39 to 48 new rswhe code add this to other quarters
       alpa=(cumsum(x2pdf));%/(m*n)))
       alpa1=alpa(end);
      %x2pdf=x2pdf/l2;%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form 0 to r.
      sum1=0;
      for l2k=0:r-(k3+1)
          pw1(l2k+1)=(Pmax*((x2pdf(l2k+1)-Pmin)/(Pmax-Pmin))).^alpa1+beta;
          sum1=sum1+pw1(l2k+1);
      end
       for l2k=0:r-(k3+1)
          pw1n(l2k+1)=pw1(l2k+1)/(sum1);
      end
%        figure(4);
%        plot(x2pdf);
%        xlabel('gray levels 2nd mean');
%        ylabel('pdf of 2nd mean');
%        title('histogram for 2nd mean');
       sk2=pw1n*triu(ones(r-k3));
%        figure(5);
%        plot(sk2);
%        xlabel('gray levels of 2nd mean');
%        ylabel('cdf upto mean');
%        title('cdf for half  of an image of 2nd mean');
       k2u=1;
       for l3=k3+1:r
           if(pw1n(k2u)>0)
               list2=find(k5==l3);%find value in an vector i.e converted from matrix
               %list1(list2)=alpha*(sk2(k2u)*(r-k3)+(k3+1))+(1-alpha)*(k3+1);
               list1(list2)=((k3+1)+(sk2(k2u))*(r-k3-1));%map dont disturb to
               %list1(list2)=alpha*(sk2(k2u)*(r-k3)+(k3+1))+(1-alpha)*(k3+1);
               %get BHE 13/3/2011
               ert(l3)=((k3+1)+(sk2(k2u))*(r-k3-1));
           end
               k2u=k2u+1;

       end

       p(listindex2)= list1;
%       figure(6);
%       imshow(p);
%      xlabel('gray levels up to first 2nd mean');
%       ylabel('luma component equilized image 2nd mean');
%      title('processed luma image up to 2nd mean');
 %lupper30=length(luma(luma>r);
%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 lupper30=length(luma(luma>r));
%for i=0:r
    %if(luma(luma<=r))
        listindexupper3=find(luma>r);
   % end
%end
 k1upper=reshape(luma(listindexupper3),lupper30,1);
 mean3=mean(k1upper);
  r3=round(mean3);
 %length30=length((luma<=r3)&(luma>r));
  listindexupper30=find((luma>r)&(luma<=r3));
  length30=length(listindexupper30);
  k30upper=reshape(luma(listindexupper30),length30,1);

  %length30=length((luma<=r3)&(luma>r));
%  sum1=0;
alpa=0;
      xpdfupper30=hist(k30upper,[r+1:r3]);%pdf from r+1:r3
      xpdfupper30=xpdfupper30/(m*n);%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form r+1 to 255.
%alpa2=max(cumsum(xpdfupper30/(m*n)));%from line 39 to 48 new rswhe code add this to other quarters
alpa=(cumsum(xpdfupper30));%/(m*n)))
alpa2=alpa(end);
      %x3pdf=xpdfupper30/length30;%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form 0 to r.
sum1=0;
      for l2k=0:r3-(r+1)
          %pw2(l2k+1)=(Pmax*((x3pdf(l2k+1)-Pmin)/(Pmax-Pmin))).^alpa2+beta;
          pw2(l2k+1)=(Pmax*((xpdfupper30(l2k+1)-Pmin)/(Pmax-Pmin))).^alpa2+beta;
          sum1=sum1+pw2(l2k+1);
      end
       for l2k=0:r3-(r+1)
          pw2n(l2k+1)=pw2(l2k+1)/(sum1);
      end
% figure(7);
%      plot(pw2n);
%      xlabel('gray levels   3rd mean');
%      ylabel('pdf of 3rd mean');
%      title('histogram for upper half an image  3rd mean');
      skupper30=pw2n*triu(ones(r3-r));
%       figure(8);
%       plot(skupper30);
%       xlabel('gray levels after mean');
%       ylabel('cdf after mean');
%       title('cdf for upper half  of an image after mean');
      k3u=1;
      for k3upper=(r+1):r3
          if(pw2n(k3u)>0)
              list1upper30=find(k30upper==k3upper);%find value in an vector i.e converted from matrix
              listnew(list1upper30)=((r+1)+skupper30(k3u)*(r3-r-1));%map dont
              %listnew(list1upper30)=alpha*(skupper30(k3u)*(r3-r)+(r+1))+(1-alpha)*(r+1);
              %disturg to get original heq 14/3/2011
              %listnew(list1upper30)=alpha*(skupper30(k3u)*(r3-r)+(r+1))+(1-alpha)*(r+1);
              ert(k3upper)=((r+1)+skupper30(k3u)*(r3-r-1));
          end
         k3u=k3u+1;

     end

%           p2=zeros(m,n);

     p(listindexupper30)= listnew;
%     figure(9);
%      imshow(p);
%      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     listindexupper40=find(luma>r3);
     lupper40=length(listindexupper40);
   % end
%end
 k1upper40=reshape(luma(listindexupper40),lupper40,1);
 %sum1=0;
 %for i=0:r
 alpa=0;
     xpdfupper40=hist(k1upper40,[r3+1:255]);%pdf from r+1:255
     xpdfupper40=xpdfupper40/(m*n);%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form r+1 to 255.
alpa=(cumsum(xpdfupper40));%/(m*n)));%from line 39 to 48 new rswhe code add this to other quarters
alpa3=alpa(end);
     % x4pdf=xpdfupper40/lupper40;%normalized pdf to get nk/n,l=sum1 of xpdf,total no of pixels form 0 to r.
sum1=0;
      for l2k=0:(255-(r3+1))
          pw3(l2k+1)=(Pmax*((xpdfupper40(l2k+1)-Pmin)/(Pmax-Pmin))).^alpa3+beta;
          sum1=sum1+pw3(l2k+1);
      end
       for l2k=0:(255-(r3+1))
          pw3n(l2k+1)=pw3(l2k+1)/(sum1);
      end
% figure(10);
%      plot(xpdfupper40);
%      xlabel('gray levels after 4mean');
%      ylabel('pdf after 4mean');
%      title('histogram for upper half an image after 4mean');
     skupper40=pw3n*triu(ones(255-r3));
%      figure(11);
%      plot(skupper40);
%      xlabel('gray levels after 4mean');
%      ylabel('cdf after 4mean');
%      title('cdf for upper half  of an image after 4mean');
     k4u=1;
     for k4upper=(r3+1):255
         if(pw3n(k4u)>0)
             list1upper40=find(k1upper40==k4upper);%find value in an vector i.e converted from matrix
             %for k2u=1:58
             %listnew4(list1upper40)=alpha*(198+skupper40(k4u))*(255-r3)+(1-alpha)*(r3+1);
             listnew4(list1upper40)=(r3+1)+skupper40(k4u)*(255-r3-1);%map
             %listnew4(list1upper40)=alpha*((r3+1+skupper40(k4u))*(255-r3))+(1-alpha)*(r3+1);
                    % listnew4(list1upper40)=alpha*(198+skupper40(k4u)*(255-r3))+(1-alpha)*(r3+1);
             %dont disturb to get original bbhe 14/3/2011
         %end
         ert(k4upper)=(r3+1)+skupper40(k4u)*(255-r3-1);
         end
         k4u=k4u+1;
     end

%      for i=0:l-1
          %p3=zeros(m,n);
%          if (p(listindex))
%              p(:)=list;
%          end
%      end

     p(listindexupper40)= listnew4;
%     figure(12);
%     imshow(p);
%     xlabel('gray levels after 4mean');
%      ylabel('luma component equilized image after 4mean');
%      title('processed luma image after 4mean');
     ommmmm=p;
     F_enhance=ommmmm;
     end
     %ommmmm=p1+p;
%     figure(13);
%     imshow(ommmmm);
%      colormap('gray');
%       xlabel('gray level');
%      ylabel('combined lower and upper half luma component equilized image');
%      title('combined luma image');
% %     figure(8);
%     image(om);
% %     for j1=0:255
% %         count=0;
% %         for i1=0:m*n-1
% %             if om(i1+1)==j1
% %                 count=count+1;
% %             end
% %         end
% %             prob(j1+1)=count/m*n;
% %     end
% %     figure(16);
% %     plot(prob);
% %
% %    for j2=0:255
% %         count1=0;
% %         for i2=0:m*n-1
% %             if luma(i2+1)==j2
% %                 count1=count1+1;
% %             end
% %         end
% %             prob2(j2+1)=count1/m*n;
% %     end
% %     figure(17);
% %     plot(prob2);
% %     xlabel('gray levels after mean');
% %      ylabel('luma component equilized image after mean');
% %      title('processed luma image after mean');
% %     ommmmm=p1+p;
% %     figure(7);
% %      colormap('gray');
% %       xlabel('gray level');
% %      ylabel('combined lower and upper half luma component equilized image');
% %      title('combined luma image');
% %     image(ommmmm);
%k=imshow(ommmmm);
%      cat1=cat(3,ommmmm,cb,cr);
% %     figure(14);
% %     imshow(cat1);
% % %     xlabel('gray level(ycbcr)');
% %      ylabel('combined lower and upper half luma,cromablue,croma red component equilized image');
% %      title('luma croma b and r color processed image');
%     catconversion=ycbcr2rgb(uint8(cat1));
%     figure(15);
%     imshow(uint8(ommmmm));
%     xlabel('gray level(rgb)');
%      ylabel('combined lower and upper half  RGB component equilized image');
%      title('converted from ycbcr2rgb color(RGB) processed image');
% YM=0;
%      YM=mean(mean(ommmmm));
%      AMBE=abs(XM-YM);
%      disp('Absolute mean brightness error=');
%      disp(AMBE);
     %MSE = meanSquareError(luma, ommmmm);
    % figure(16);
%disp('mean Square Error = ');
%disp(MSE);
%PSNR1 = PSNR(luma, ommmmm);
%figure(17);
% disp('Peak Signal to Noise Ratio = ');
% disp(PSNR1);
% E=entropy(uint8(ommmmm));
% disp('Entropy=');
% disp(E);
%      figure(16);
%      (imhist(uint8(ommmmm)));


function cluster_orthviews_overlap_3colors(mask1, mask2, mask3, varargin)
% Plot three clusters on the orthviews, and their intersections for
% activations and deactivations in intermediate colors
%
% :Usage:
% ::
%
%    cluster_orthviews_overlap_3colors(mask1, mask2, mask3, ['colors', colors cell], ['surface'] )
%
% Positive effects only!
%
% :Inputs:
%
%   mask1 mask2 mask3 are either image names (preferred!) or clusters
%   structures.  for clusters structures, need to add .dim field
%   and you need the 2010 object-oriented code in the canlab repository.
%
% ..
%    tor wager, june 2010
%    A good function, but not polished yet.  needs debugging for various
%    minor issues.
% ..

colors = {[0 0 1] [1 0 0] [1 1 0]};
dosurface = 0;

for i = 1:length(varargin)
    if ischar(varargin{i})
        switch varargin{i}
            % reserved keywords
            case 'betas'
            case 'design'

                % functional commands
            case 'colors', colors = varargin{i+1};
            case 'surface', dosurface = 1;

            otherwise, warning(['Unknown input string option:' varargin{i}]);
        end
    end
end

if isstruct(mask1) && isstruct(mask2) && isstruct(mask3)
    loadfromfile = 0;
elseif ischar(mask1) && ischar(mask2) && ischar(mask3)
    loadfromfile = 1;
else
    error('Inputs must be all cl structs or mask filenames');
end

if loadfromfile

    [maskInfo1, dat1] = iimg_read_img(mask1, 2);
    [maskInfo2, dat2] = iimg_read_img(mask2, 2);
    [maskInfo3, dat3] = iimg_read_img(mask3, 2);

    % positive only
    dat1 =  dat1 > 0;
    dat2 =  dat2 > 0;
    dat3 =  dat3 > 0;

    int_dat = iimg_intersection(mask1, mask2, 'posneg'); % intersections
    pos12 = int_dat(:, 1);

    int_dat = iimg_intersection(mask1, mask3, 'posneg'); % intersections
    pos13 = int_dat(:, 1);

    int_dat = iimg_intersection(mask2, mask3, 'posneg'); % intersections
    pos23 = int_dat(:, 1);

    pos123 = pos12 & pos13;

    intersect_all = any([pos12 pos13 pos23 pos123], 2);

    %remove higher-order intersections from  mask dat
    dat1(intersect_all) = 0;
    dat2(intersect_all) = 0;
    dat3(intersect_all) = 0;

    pos12(pos123) = 0;
    pos23(pos123) = 0;
    pos13(pos123) = 0;

    % make clusters
    clear cl

    cl{1} =  iimg_indx2clusters(dat1, maskInfo1);
    cl{2} =  iimg_indx2clusters(dat2, maskInfo2);
    cl{3} =  iimg_indx2clusters(dat3, maskInfo3);

    cl{4} =  iimg_indx2clusters(pos12, maskInfo1);
    cl{5} =  iimg_indx2clusters(pos13, maskInfo2);
    cl{6} =  iimg_indx2clusters(pos23, maskInfo3);

    cl{7} =  iimg_indx2clusters(pos123, maskInfo1);

else
    % Work from clusters directly

    % convert to masks

    if ~isfield(mask1, 'dim') || isempty(mask1(1).dim) || ...
            ~isfield(mask2, 'dim') || isempty(mask2(1).dim) || ...
            ~isfield(mask3, 'dim') || isempty(mask3(1).dim)

        error('Enter .dim (image dimension in voxels) field in all cl structs. e.g., [91 109 91]');
    end

    r = cluster2region(mask1);
    m1 = region2imagevec(r);

    r = cluster2region(mask2);
    m2 = region2imagevec(r);

    r = cluster2region(mask3);
    m3 = region2imagevec(r);

    m1 = replace_empty(m1);
    m2 = replace_empty(m2);
    m3 = replace_empty(m3);

    dat1 =  m1.dat > 0;
    dat2 =  m2.dat > 0;
    dat3 =  m3.dat > 0;

    pos123 = all([dat1 dat2 dat3], 2);
    pos12 = all([dat1 dat2], 2);
    pos23 = all([dat2 dat3], 2);
    pos13 = all([dat1 dat3], 2);

    intersect_all = any([pos12 pos13 pos23 pos123], 2);

    %remove higher-order intersections from  mask dat
    dat1(intersect_all) = 0;
    dat2(intersect_all) = 0;
    dat3(intersect_all) = 0;

    pos12(pos123) = 0;
    pos23(pos123) = 0;
    pos13(pos123) = 0;

    % make clusters
    clear cl

    cl{1} =  iimg_indx2clusters(dat1, m1.volInfo);
    cl{2} =  iimg_indx2clusters(dat2, m2.volInfo);
    cl{3} =  iimg_indx2clusters(dat3, m3.volInfo);

    cl{4} =  iimg_indx2clusters(pos12, m1.volInfo);
    cl{5} =  iimg_indx2clusters(pos13, m1.volInfo);
    cl{6} =  iimg_indx2clusters(pos23, m1.volInfo);

    cl{7} =  iimg_indx2clusters(pos123, m1.volInfo);

end

% set colors for overlap
% colors{end+1} = {mean([colors{1}; colors{2}])};
% colors{end+1} = {mean([colors{1}; colors{3}])};
% colors{end+1} = {mean([colors{2}; colors{3}])};
%
% colors{end+1} = {mean([colors{1}; colors{2}; colors{3}])};

colors(end+1) = {2*mean([colors{1}; colors{2}])}; colors{end}(colors{end} > 1) = 1;
colors(end+1) = {2*mean([colors{1}; colors{3}])}; colors{end}(colors{end} > 1) = 1;
colors(end+1) = {2*mean([colors{2}; colors{3}])}; colors{end}(colors{end} > 1) = 1;

colors(end+1) = {3*mean([colors{1}; colors{2}; colors{3}])};

cluster_orthviews();
for i = 1:7
    if ~isempty(cl{i}), cluster_orthviews(cl{i}, colors(i), 'add', 'solid'); end
end

cluster_orthviews_montage(10, 'axial', [], 'onerow', 'range', [-35 55]);
h = findobj(gcf,'Type', 'Text'); set(h, 'FontSize', 18) %delete(h);

cluster_orthviews_montage(10, 'sagittal', [], 'onerow', 'range', [-40 40]);
h = findobj(gcf,'Type', 'Text'); set(h, 'FontSize', 18) %delete(h);

if dosurface

    create_figure;
    s = addbrain('hires left'); set(s, 'FaceColor', [.5 .5 .5], 'FaceAlpha', 1);
    for i = 1:7
        cluster_surf(cl{i}, colors(i), 2, s);
    end
    for i = 4:7
        cluster_surf(cl{i}, colors{i}(1), 2, s);
    end

    scn_export_papersetup; saveas(gcf, 'cluster_overlap_3colors_Lmedial.png');
    view(270, 0); lightFollowView
    scn_export_papersetup; saveas(gcf, 'cluster_overlap_3colors_Lateral.png');

    create_figure('s2');
    s = addbrain('hires right'); set(s, 'FaceColor', [.5 .5 .5], 'FaceAlpha', 1);
    for i = 1:3
        cluster_surf(cl{i}, colors(i), 2, s);
    end
    for i = 4:7
        cluster_surf(cl{i}, colors{i}(1), 2, s);
    end
    lightFollowView
    scn_export_papersetup; saveas(gcf, 'cluster_overlap_3colors_Rmedial.png');
    view(90, 0); lightFollowView
    scn_export_papersetup; saveas(gcf, 'cluster_overlap_3colors_Rateral.png');

    create_figure('s3');
    s = addbrain('limbic');
    s = [s addbrain('brainstem')];
    axis auto
    set(s, 'FaceColor', [.5 .5 .5]);
    set(s(end-1), 'FaceAlpha', .15);
    view(135, 10)
    for i = 1:3
        cluster_surf(cl{i}, colors(i), 2, s);
    end
    for i = 4:7
        cluster_surf(cl{i}, colors{i}(1), 2, s);
    end
    scn_export_papersetup; saveas(gcf, 'cluster_overlap_3colors_Lmedial.png');

end

end


function A_sym = symetrizeMatrix(A)
[i,j,k]=find(A);
W=sparse([i; j], [j; i], ones(size(k,1)*2,1));
A_help=sparse([i; j], [j; i], [k; k]);
[i,j,k]=find(A_help);
[i,j,kk]=find(W);
A_sym=sparse(i,j,(kk.^(-1)).*k); %Now Kantennr_sym is a symetric form of Kantennr


classdef CompressingVademecumData < handle

    properties (Access = private)
        qV
        rhoV
        xiV
        phiV
        cellDataSameSign
        cellDataDifferentSign
        phiIndeces
    end

    properties (Access = private)
        compressedFileName
        nMx
        nMy
        nPhiQuarter
        nPhiT
    end

    methods (Access = public)

        function obj = CompressingVademecumData()
            obj.init();
            obj.initVariables();
            obj.loadVademecumDataBase();
            obj.compute();
            obj.saveData();
        end

    end

    methods (Access = private)

        function init(obj)
            obj.compressedFileName = 'OptimalSuperEllipses';
            obj.nMx = 20;
            obj.nMy = 20;
            obj.nPhiQuarter = 10;
            obj.nPhiT = obj.computeNphiT();
        end

        function nPT = computeNphiT(obj)
            n0  = obj.nPhiQuarter;
            n1  = 2*(n0 -1)+1;
            nPT = 2*(n1 -1)+1;
        end

        function initVariables(obj)
            nmx = obj.nMx;
            nmy = obj.nMy;
            np = obj.nPhiT;
            obj.qV   = zeros(nmx,nmy,np);
            obj.rhoV = zeros(nmx,nmy,np);
            obj.xiV  = zeros(nmx,nmy,np);
            obj.phiV = zeros(nmx,nmy,np);
        end

        function loadVademecumDataBase(obj)
            s.nMx = obj.nMx;
            s.nMy = obj.nMy;
            s.nPhi = obj.nPhiQuarter;
            v = VademecumDataLoader(s);
            obj.cellDataSameSign = v.cellDataSameSign;
            obj.cellDataDifferentSign = v.cellDataDifferentSign;
        end

        function compute(obj)
            for iMx = 1:obj.nMx
                for iMy = 1:obj.nMy
                    for iPhi = 1:nPhi
                        obj.computePhiIndices(iPhi)
                        obj.computeXiValues(iMx,iMy,iPhi);
                        obj.computeRhoValues(iMx,iMy,iPhi);
                        obj.computePhiValues(iMx,iMy,iPhi);
                        obj.computeQValues(iMx,iMy,iPhi);
                        obj.plotFigures(iMx,iMy,iPhi);
                    end
                end
            end
        end

        function computePhiIndices(obj,iPhi)
            iphi1 = iPhi;
            iphi2 = 2*nPhi - iPhi;
            iphi3 = 2*(nPhi -1) + iPhi;
            iphi4 = 2*(2*nPhi -1) - iPhi;
            obj.phiIndeces = [iphi1,iphi2,iphi3,iphi4];
        end

        function computeXiValues(obj,iMx,iMy,iPhi)
             [cS,cD] = obj.obtainCellData(obj,iMx,iMy,iPhi);
             xiQ = [cS.xi cS.xi cD.xi cD.xi];
             ind = obj.phiIndeces;
             obj.xiV(iMx,iMy,ind) = xiQ;
        end

        function computeRhoValues(obj,iMx,iMy,iPhi)
             [cS,cD] = obj.obtainCellData(obj,iMx,iMy,iPhi);
             rhoQ = [cS.rho cS.rho cD.rho cD.rho];
             ind = obj.phiIndeces;
             obj.rhoV(iMx,iMy,ind) = rhoQ;
        end

        function computePhiValues(obj,iMx,iMy,iPhi)
            [cS,cD] = obj.obtainCellData(obj,iMx,iMy,iPhi);
            qQ = [cS.phi pi/2-cS.phi cD.phi 3*pi/2-cD.phi];
            ind = obj.phiIndeces;
            obj.qV(iMx,iMy,ind) = qQ;
        end

        function computeQValues(obj,iMx,iMy,iPhi)
            [cS1,cD1] = obj.obtainCellData(obj,iMx,iMy,iPhi);
            [cS2,cD2] = obj.obtainCellData(obj,iMy,iMx,iPhi);
            qQ = [cS1.q cS2.q cD1.q cD2.q];
            ind = obj.phiIndeces;
            obj.qV(iMx,iMy,ind) = qQ;
        end

        function [cS,cD] = obtainCellData(obj,iMx,iMy,iPhi)
           cS = obj.cellDataSameSign{iMx}{iMx,iMy,iPhi};
           cD = obj.cellDataDifferentSign{iMx}{iMx,iMy,iPhi};
        end

        function plotFigures(obj,iMx,iMy,iPhi)
            [cS1,cD1] = obj.obtainCellData(obj,iMx,iMy,iPhi);
            [cS2,cD2] = obj.obtainCellData(obj,iMy,iMx,iPhi);
            obj.plotFigure(cS1,1);
            obj.plotFigure(cD1,2);
            obj.plotFigure(cS2,3);
            obj.plotFigure(cD2,4);
        end

       function saveData(obj)
            q = obj.qV;
            rho = obj.rhoV;
            xi  = obj.xiV;
            phi = obj.phiV;
            save(obj.compressedFileName,'q','rho','xi','phi')
        end

    end

    methods (Access = private, Static)

        function [xiP,rhoP,phiP,qP] = loadData(cP)
            xiP  = cP.xi;
            rhoP = cP.rho;
            phiP = cP.phi;
            qP   = cP.q;
        end

        function plotFigure(cellData,nFigure)
            figure(nFigure);
            clf
            cellData.mesh.plot;
            drawnow
        end

    end

end


% repeat a matrix
%
function [grad] = B_transpose(future_layers, curr_layer)
future_grad = GetFutureGrad(future_layers, curr_layer);

grad = future_grad';

end


%kvspatial 'Compute Spatial Features Using NxM Window (K1)'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vspatial.pane file
%
% Parameters:
% InputFile: i 'Input Image ', required: 'input image filename'
% Integer: w 'Window width ', default: 3: 'window width argument'
% Integer: h 'Window height', default: 3: 'window height argument'
% OutputFile: o 'Output Image', required: 'output image filename'
%
% Example: o = kvspatial(i, {'i','';'w',3;'h',3;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% vspatial - Compute Spatial Features Using NxM Window  (K1)
%
%  DESCRIPTION
% .I vspatial
% performs a spatial feature extraction on an image using a selected
% statistical operation.  The statistical operation is computed, using
% overlapping windows, over the entire image.  The center pixel is updated
% in each window based on the calculated statistics of that window.
%
% The input image, which must be of data storage type BYTE, corresponds
% to the -i argument.  The output image, which corresponds to the -o
% argument, is stored as data type FLOAT.  The output image may be a
% multiband image depending on how many spatial operators were selected.
% The resulting image will have a border of pixels of value 0, since the
% window operation does not calculate values for border pixels.
%
% The width and height of the window is specified by the -w and -h window
% width and height arguments.  The width and height arguments cannot be an
% even number.  The window dimensions must be odd (ie. 3x3, 5x5, 7x7, etc.),
% since the center pixel is replaced with the computed value of the window
% data.  The default window size is 3x3.
%
% Each pixel in the image is updated with a computed value except the border
% pixels.  A 3x3 window will result in a border of one pixel, a 5x5 window
% will result in a border of two pixels, etc.
%
% There are six statistical operations that may be selected.  Any combination
% of the statistical operations may be selected by toggling the desired
% argument on (ie. argument followed by a 1).  The default for each argument
% is unselected (ie. argument followed by a 0), except -m (mean), which is
% selected.  The six possible statistical operations and their arguments are:
% .DS
%   -m  --  calculates the mean of the image.
%   -v  --  calculates the variance of the image.
%   -c  --  calculates the contrast of the image.
%   -s  --  calculates the angular second moment of the image.
%   -e  --  calculates the entropy of the image.
%   -d  --  calculates the dispersion of the image.
% .DE
% The resulting feature vector may contain from one to six bands of data,
% depending upon the number of arguments selected.
%
% All input images must be of data storage type BYTE.
%
% All output images are of data storage type FLOAT.
%
%
%
%  EXAMPLES
% vspatial -i input_image.xv -w 5 -h 5 -m 0 -v 1 -e 1 -o output_image
%
% the input image must of type BYTE; the selected width and height of the
% window is 5 x 5, which will result in a border width of two pixels in the
% output image.  The mean spatial operator is unselected (default is selected),
% and the variance and entropy operations are selected, which will result in
% an output image (feature vector) of 2 bands, based on the operations selected.
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
% All input images must be of data storage type BYTE.
%
% All output images are of data storage type FLOAT.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kvspatial(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kvspatial(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'w', 3;'h', 3;'o', '__output'};
maxval={0,64,64,0};
minval={0,1,1,0};
istoggle=[0,1,1,0];
was_set=istoggle * 0;
paramtype={'InputFile','Integer','Integer','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'vspatial"  '],Inputs,narglist);


function [ results ] = run_DAT_AFFINE( seq, res_path, bSaveImage )

project_dir = fileparts(fileparts(fileparts(mfilename('fullpath'))));
addpath(fullfile(project_dir, 'trackers', 'DAT', 'src'));

visualization = 0;
use_normal_size = 1;
normal_height = 360;
normal_width = 640;
I = imread(seq.s_frames{1});
if use_normal_size
  scale_height = size(I, 1) / normal_height;
  scale_width = size(I, 2) / normal_width;
else
  scale_height = 1;
  scale_width = 1;
end
% Load annotations
groundtruth = seq.init_rect;
groundtruth = groundtruth ./ [scale_width, scale_height, scale_width, scale_height];

% Load default settings
cfg = affine_parameters_dat();

% Tracking
frames = 1:length(seq.s_frames);
times = zeros(size(frames));
rects = zeros(length(frames), 4);
spf = tic;
for frame = frames
  I = imread(seq.s_frames{frame});
  % I = imresize(I, [360, 640]);
  if use_normal_size
    I = imresize(I, [normal_height, normal_width]);
  end

  ttrack = tic;
  if frame == 1
    [state, location] = tracker_dat_initialize(I, groundtruth, cfg);
  else
    [state, location] = tracker_dat_update(state, I, cfg);
  end
  times(frame) = toc(ttrack);
  % Visualization
  % rects(frame, :) = location*2;
  rects(frame, :) = location .* [scale_width, scale_height, scale_width, scale_height];
  if visualization
    figure(1), clf
    imshow(I)
    rectangle('Position', location, 'EdgeColor', 'b', 'LineWidth', 2);
    drawnow
  end
end
spf = toc(spf);

results.res = rects;
results.type='rect';
results.fps = length(frames)/spf;

end


function h=m_rectangle(long,lat,width,height,varargin)
%M_RECTANGLE Create rectangle, rounded-rectangle, or ellipse
%   M_RECTANGLE adds a default rectangle to the current map axes.
%
%   M_RECTANGLE(long,lat,width,height) creates a rectangle in 2-D coordinates.
%   The long and lat elements determine the location and the width and height
%   elements determine the size. The function plots into the current axes
%   without clearing existing content from the axes.
%   M_RECTANGLE(long,lat,width,height,flag) creates different rectangle. If
%   flag=0(default),it is a normal rectangle. If flag=1, it is a curve box
%   determined to the projection.
%
%   M_RECTANGLE(...,'Curvature',cur) adds curvature to the sides
%   of the rectangle. For different curvatures along the horizontal and
%   vertical sides, specify cur as a two-element vector of the form
%   [horizontal vertical]. For the same length of curvature along all
%   sides, specify cur as a scalar value. Specify values between 0 (no
%   curvature) and 1 (maximum curvature). Use [1 1] to create an ellipse or
%   circle.
%
%   M_RECTANGLE(...,Name,Value) specifies rectangle properties using one or
%   more Name,Value pair arguments. It is the same as function rectangle.
%
%   M_RECTANGLE(container,...) creates the rectangle in the axes, group, or
%   transform specified by container, instead of in the current axes.
%
%   R = M_RECTANGLE(...) returns the rectangle object created.
%
%   Execute GET(R), where R is a rectangle object, to see a list of
%   rectangle object properties and their current values.
%   Execute SET(R) to see a list of rectangle object properties and legal
%   property values.
%

% Shi Weiheng (tfoterye@gmail.com) 25/Mar/18
%
% Based on m_quiver written by Prof Rich Pawlowicz.
% Comments mainly come from function rectangle.
% This software is provided "as is" without warranty of any kind. But
% it's mine, so you can't sell it.
%

global MAP_PROJECTION MAP_VAR_LIST

% Have to have initialized a map first

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

if (varargin{1}==0 || varargin{1}==1)
    flag=varargin{1};
    varargin1={varargin{2:end}};
else
    flag=0;
    varargin1=varargin;
end

[X,Y]=m_ll2xy(long,lat,'clip','off');
[X1,Y1]=m_ll2xy(long+width,lat+height,'clip','off');
[X2,Y2]=m_ll2xy(long,lat+height,'clip','off');
[X3,Y3]=m_ll2xy(long+width,lat,'clip','off');

[small_x1,small_y1]=m_ll2xy(long:width/100:long+width,lat*ones(1,101),'clip','off');
[small_x2,small_y2]=m_ll2xy(long:width/100:long+width,(lat+height)*ones(1,101),'clip','off');

if flag==0
h=rectangle('Position',[X,Y,X1-X,Y1-Y],varargin1{:});
end
if flag==1
   h=line( [X,small_x1,X1,small_x2(end:-1:1),X],[Y,small_y1,Y1,small_y2(end:-1:1),Y],varargin1{:});
end
set(h,'tag','m_rectangle');
if nargout==0
 clear h
end


 function X = nufft(x, st)
%function X = nufft(x, st)
%|
%| Compute d-dimensional NUFFT of signal/image x
%|
%| in
%|	x	[N1 N2 ... Nd (L)]	L input image(s) of size
%|						N1 x N2 x ... x Nd
%|	st	structure		precomputed by nufft_init()
%| out
%|	X	[M (L)]			output spectra
%|
%| Copyright 2003-5-30, Jeff Fessler, University of Michigan

% if no arguments, then run some self tests
if (nargin < 1) || (nargin == 1 && streq(x, 'test'))
	help([mfilename '.m'])

	printm('Starting nufft() self test; after a wait, shows small errors')
	if 0
		Jd = [5 4 4];
		Nd = [23 15 19];
		alpha_user = {1, 1, 1}; % default alpha, beta
		beta_user = {0.5, 0.5, 0.5};
	else
		Jd = [5 6];
		Nd = [60 75];
		alpha_user = {1, 1};
		beta_user = {0.5, 0.5};
	end
	Kd = 2 * Nd;
	gam = 2*pi ./ Kd;
	n_shift = zeros(size(Nd));

	if 1
		oldarg = {Nd(1), Nd(2), Jd(1), Jd(2), Kd(1), Kd(2)};
		printm('err alf1 %g best %g', ...
			max(col(nufft2_err_mm('all', oldarg{:}, 1))), ...
			max(col(nufft2_err_mm('all', oldarg{:}, 'best'))) )
	end
	rng(0)
	x = randn(Nd);
%	x = [[1:Nd(1)]'*ones(1,3), ones(Nd(1), Nd(2)-3)]; % test signal
%	x = zeros(N1, N2); x(1,1) = 1;
	if 0 % test with uniform frequency locations
		o1 = 2 * pi * [0:(N1-1)]' / N1;
		o2 = 2 * pi * [0:(N2-1)]' / N2;
		[o1, o2] = ndgrid(o1, o2);
		Xf = fft2(x);
	else
		if length(Nd) == 3 % nonuniform frequencies
			[o1, o2, o3] = ndgrid(linspace(0,gam(1),11), ...
				linspace(0,gam(2),13), linspace(0,gam(3),5));
			om = [	[o1(:); [0 7.2 2.6 3.3]'], ...
				[o2(:); [0 4.2 -1. 5.5]'], ...
				[o3(:); [0 1.1 -2. 3.4]'] ];
		else
			[o1, o2] = ndgrid(linspace(-3*gam(1),3*gam(1),41), ...
				linspace(-2*gam(2),gam(2),31));
			om = [	[o1(:); [0 7.2 2.6 3.3]'], ...
				[o2(:); [0 4.2 -1. 5.5]'] ];
		end
		Y.d = dtft(x, om, 'n_shift', n_shift);
	end

	s.tab = nufft_init(om, Nd, Jd, Kd, n_shift, 'table', 2^12, 'minmax:kb');
	Y.tab = nufft(x, s.tab);
	printm('table0		max%%diff = %g', max_percent_diff(Y.d, Y.tab))

	s.mmkb = nufft_init(om, Nd, Jd, Kd, n_shift, 'minmax:kb');
	Y.mmkb = nufft(x, s.mmkb);
	printm('minmax:kb	max%%diff = %g', max_percent_diff(Y.d, Y.mmkb))

	if 0 % test multiple input case
		xx = x; xx(:,:,:,2) = x; xx(:,:,:,3) = x;
		Y.tmp = nufft(xx, s.mmkb);
		Y.tmp = Y.tmp(:,1);
		printm('multi	max%%diff = %g', max_percent_diff(Y.mmkb, Y.tmp))
	return
	end

	% kaiser with minmax best alpha,m
	s.kb = nufft_init(om, Nd, Jd, Kd, n_shift, 'kaiser');
	Y.kb = nufft(x, s.kb);
	printm('kaiser		max%%diff = %g', max_percent_diff(Y.d, Y.kb))

	% kaiser with user-specified supoptimal alpha,m for comparison
	s.ku = nufft_init(om, Nd, Jd, Kd, n_shift, 'kaiser', ...
		s.kb.kb_alf + 0.1*ones(size(s.kb.kb_alf)), s.kb.kb_m);
	Y.ku = nufft(x, s.ku);
	printm('kaiser-user	max%%diff = %g', max_percent_diff(Y.d, Y.ku))

	s.mmtu = nufft_init(om, Nd, Jd, Kd, n_shift, 'minmax:tuned');
	Y.mmtu = nufft(x, s.mmtu);
	printm('minmax:tuned	max%%diff = %g', max_percent_diff(Y.d, Y.mmtu))

	s.mm = nufft_init(om, Nd, Jd, Kd, n_shift, 'minmax:user', ...
		alpha_user, beta_user);
	Y.mm = nufft(x, s.mm);
	printm('minmax:user	max%%diff = %g', max_percent_diff(Y.d, Y.mm))

	if 0 % test 'uniform' scaling
		s.un = nufft_init(om, Nd, Jd, Kd, n_shift, 'uniform')
		Y.un = nufft(x, s.un);
		printm('user-unif max%%diff = %g', max_percent_diff(Y.mm, Y.un))
	return
	end

%	s1 = nufft_init(om, Nd, Jd, Kd, n_shift, 'loop', 'kaiser');
%	printm('kb loop max %% difference = %g', max_percent_diff(sn.p,s1.p))

 if 0 % test against old 2D version
	s2 = nufft2_init_kb(om, oldarg{:}, n_shift, 'kaiser');
%	Y2 = nufft2(x, s2);
%	printm('KB 2d vs nd max%%diff = %g', max_percent_diff(Y2, Y.kb))
	printm('KB 2d vs nd max%%diff = %g', max_percent_diff(s2.p,s.kb.p))

	s2 = nufft2_init(om, oldarg{:}, n_shift, 0, 'best');
	printm('tuned 2d vs nd max%%diff = %g', max_percent_diff(s2.p,s.mmtu.p))

	s2 = nufft2_init(om, oldarg{:}, n_shift, 0); % minmax
	printm('user 2d vs nd max%%diff = %g', max_percent_diff(s2.p,s.mm.p))

 end
return
end

Nd = st.Nd;
Kd = st.Kd;

dims = size(x);
dd = length(Nd);
if ndims(x) < dd, fail 'input signal has too few dimensions', end
if any(dims(1:dd) ~= Nd), fail 'input signal has wrong size', end

% the usual case is where L=1, i.e., there is just one input signal.
if ndims(x) == dd
	x = x .* st.sn; % apply scaling factors
	Xk = col(fftn_fast(x, Kd)); % [*Kd] oversampled FFT, padded at end

% otherwise, collapse all excess dimensions into just one
else
	xx = reshape(x, [prod(Nd) prod(dims((dd+1):end))]); % [*Nd *L]
	L = size(xx, 2);
	Xk = zeros(prod(Kd), L, class(xx)); % [*Kd *L]
	for ll=1:L
		xl = reshape(xx(:,ll), [Nd 1]); % l'th signal
		xl = xl .* st.sn; % scaling factors
		Xk(:,ll) = col(fftn_fast(xl, [Kd 1]));
	end
end

% interpolate using precomputed sparse matrix
% or with tabulated interpolator
if ~isfield(st, 'interp_table')
	X = st.p * Xk; % [M *L]
else
	X = feval(st.interp_table, st, Xk);
end

if ndims(x) > dd
	X = reshape(X, [st.M dims((dd+1):end)]); % [M (L)]
end


function Path = TestPathInGraph(DAG,Start,End)
% Input:DAG is the graph, p the start point, q the end point.
% Output:if there is a path from p to q, return Path = 1,otherwise Path = 0;

% test the cycle by DFS algorithm
Path = 0;
Visited = zeros( 1,size( DAG,1 ) );
[ List,Visited ] = SearchPath( DAG,Start,[],Visited );

    while isempty( List ) == 0
         %Node = List(1)
         Descendant = List(1);
         if Descendant == End
             Path = 1;
             break;
         end
         List( 1 )=[];
         if Visited( Descendant ) ==0
            [List,Visited] = SearchPath(DAG,Descendant,List,Visited);
         end
    end
end

function [ List,Visited ] = SearchPath( DAG,Start,L,V )
 V( Start ) = 1;
 Visited=V;
 Descendant = find( DAG(Start,:) ~= 0 );
 List = [L Descendant];
end


%compute dtailinflmag
function [data,units]=compute_dtailinflmag(trx,n)

%
larvae=trx.exp2flies{n};
numlarvae=numel(larvae);
dtailinflmag=cell(1,numlarvae);
for i=1:numlarvae
    larva=larvae(i);
    dtailinflmag{1,i}=(trx(larva).tailinflmag(2:end)-trx(larva).tailinflmag(1:end-1))./trx(larva).dt;
end

units=parseunits('mm/s');
data=dtailinflmag;


function [update] = polynomial_expansion_registration(...
    moving, fixed, multiModal, transformationModel, varargin)
% POLYNOMIAL_EXPANSION_REGISTRATION Estimates a displacement field using polynomial expansion
%
% INPUT ARGUMENTS
% moving                    - Moving image
% fixed                     - Fixed image
% multiModal                - Set whether to perform multi-modal or
%                             uni-modal image registration
%                             false/true
% transformationModel       - Transformation model for estimating the
%                             displacement field
%                             'translation', 'affine', 'non-rigid'
%
% OPTIONAL INPUT ARGUMENTS
% 'signalModel'             - Local signal model to use when computing the
%                             polynomial expansion transformation
%                             'linear' (deafult), 'quadratic'
%
% 'numberOfChannels'        - Number of channels to use in when computing
%                             the entropy (based on channel coding). This
%                             is only relevant if multiModal is set to
%                             true.
%                             Default value is 8
%
% OUTPUT ARGUMENTS
% update
%   displacementUpdate      - Estimated update field
%   certaintyUpdate         - Certainty related to the estimated update field
%   transformationMatrix    - Estimate transformation matrix (only if

% Copyright (c) 2012 Daniel Forsberg
% danne.forsberg@outlook.com
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

%% Set up default parameters
signalModel = 'linear';
numberOfChannels = 8;

% Overwrites default parameter
for k=1:2:length(varargin)
    eval([varargin{k},'=varargin{',int2str(k+1),'};']);
end;

%%
dims = ndims(moving);

if multiModal && strcmp(signalModel,'quadratic')
	error(['Multi-modal image registration using polynomial expansion',...
		' is only available for the linear signal model'])
end

switch dims
    case 2
		[update] = ...
			polynomial_expansion_registration2d(...
			moving, fixed,...
			'signalModel',signalModel,...
			'transformationModel',transformationModel,...
			'multiModal',multiModal,...
			'numberOfChannels',numberOfChannels);
    case 3
		[update] = ...
			polynomial_expansion_registration3d(...
			moving, fixed,...
			'signalModel',signalModel,...
			'transformationModel',transformationModel,...
			'multiModal',multiModal,...
			'numberOfChannels',numberOfChannels);
end


function layer = vl_nnconvt(varargin)
%VL_NNCONVT Additional options for vl_nnconvt (CNN deconvolution)
%   Y = Layer.vl_nnconvt(X, F, B) computes the convolution-transpose of the
%   image X with the filter bank F and biases B. See help vl_nnconvt for
%   more details.
%
%   This method overloads MatConvNet's vl_nnconvt function for Layer
%   objects, so that instead of executing vl_nnconvt, a new Layer object is
%   returned. X, F and B can be other Layers, including Params, or
%   constants.
%
%   The overloaded method accepts the same options as Layer.vl_nnconv.

  layer = vl_nnconv(varargin{:}, 'transpose', true) ;

end


function lagplot(c)
   %lagplot

   % Author: Michael West, Geophysical Institute, Univ. of Alaska Fairbanks
   % $Date$
   % $Revision$

   % PREP PLOT
   figure('Color','w','Position',[50 50 600 500]);
   set(gcf,'DefaultAxesFontSize',14);
   imagesc(c.lags);
   title('Lag time for maximum correlation (s)');

   % ADD DATES TO AXES
   n = length(c.trig);
   ticvals = 1:round(n/25):n;
   set(gca,'XTick',ticvals);
   set(gca,'YTick',ticvals);
   yt = get(gca,'YTick');
   set(gca,'YTickLabel',datestr(c.trig(yt),'yyyy-mm-dd HH:MM'),'FontSize',6);

   % DRESS UP THE FIGURE
   cmap = load('colormap_lag.txt');
   colormap(cmap);
   colorbar;
   xlabel('Event number');
   ylabel('Event date');

   %PRINT OUT FIGURE
   set(gcf, 'paperorientation', 'portrait');
   set(gcf, 'paperposition', [1.25 2.5 6 6] );
   %print(gcf, '-depsc2', 'FIG_tartan.ps')
end


classdef FitNetModel < matlab.mixin.SetGet
    %FitNetModel Summary of this class goes here
    %   Detailed explanation goes here

    properties
        %Time
        t0(1,1) double = 0;
        tOffset(1,1) double = 0;

        %Constant
        const(1,1) double = 0;
        varConst(1,1) logical = false;
        constUb(1,1) double = 0;
        constLb(1,1) double = 0;

        %Neural Network
        net(1,1)
        varNetWB logical;
        netWbUb double = 0;
        netWbLb double = 0;
        hiddenSizes double = 5;
        gpuAvail(1,1) double = gpuDeviceCount("available");
    end

    methods
        function obj = FitNetModel(hiddenSizes)
            obj.hiddenSizes = hiddenSizes;
            obj.net = FitNetModel.createNetwork(hiddenSizes);

            netWb = abs(getwb(obj.net));
            obj.netWbUb = 100 * netWb;
            obj.netWbLb = 100 * (-netWb);
            obj.varNetWB = false(size(netWb));

            obj.gpuAvail = gpuDeviceCount("available");
        end

        function value = getValueAtTime(obj,ut)
            if(obj.gpuAvail > 0)
                gpuStr = 'yes';
            else
                gpuStr = 'no';
            end

            dt = (ut - obj.t0) + obj.tOffset;
            value = sim(obj.net,dt, 'UseGPU',gpuStr);
        end

        function wbParams = getWbParams(obj)
            wbParams = getwb(obj.net);
        end

        function value = getWbParamAtInd(obj, ind)
            wbParams = obj.getWbParams();
            value = wbParams(ind);
        end

        function setWbParamAtInd(obj, newVal, ind)
            wbParams = obj.getWbParams();
            wbParams(ind) = newVal;
            obj.net = setwb(obj.net, wbParams);
        end

        function listBoxStr = getListboxStr(obj)
            listBoxStr = {};

            for(i=1:length(obj.varNetWB))
                listBoxStr{i} = sprintf('Parameter %u', i); %#ok<AGROW>
            end
        end

        function newModel = deepCopy(obj)
            newModel = FitNetModel(obj.hiddenSizes);
            newModel.net = setwb(newModel.net, getwb(obj.net));

            newModel.t0 = obj.t0;
            newModel.tOffset = obj.tOffset;

            %Constant
            newModel.const = obj.const;
            newModel.varConst = obj.varConst;
            newModel.constUb = obj.constUb;
            newModel.constLb = obj.constLb;

            %Neural Network
            newModel.varNetWB = obj.varNetWB;
            newModel.netWbUb = obj.netWbUb;
            newModel.netWbLb = obj.netWbLb;
        end

        function t0 = getT0(obj)
            t0 = obj.t0;
        end

        function setT0(obj, newT0)
            obj.t0 = newT0;
        end

        function timeOffset = getTimeOffset(obj)
            timeOffset = obj.tOffset;
        end

        function setTimeOffset(obj, timeOffset)
            obj.tOffset = timeOffset;
        end

        function setConstValueForContinuity(obj, contValue)
            value = obj.getValueAtTime(obj.t0);

            obj.const = contValue - value;
        end

        function numVars = getNumVars(obj)
            numVars = 1 + numel(obj.varNetWB);
        end

        function x = getXsForVariable(obj)
            x = getwb(obj.net);
            x = x(obj.varNetWB);

            if(obj.varConst)
                x = [obj.const, x(:)'];
            end

            x = x(:)';
        end

        function updateObjWithVarValue(obj, x)
            if(obj.varConst)
                obj.const = x(1);
            end

            x = x(2:end);
            if(any(obj.varNetWB))
                wb = getwb(obj.net);
                wb(obj.varNetWB) = x(obj.varNetWB);
                obj.net = setwb(obj.net, wb);
            end
        end

        function [lb, ub] = getBndsForVariable(obj)
            lb = [obj.constLb obj.netWbLb(:)'];
            ub = [obj.constUb obj.netWbUb(:)'];
        end

        function setBndsForVariable(obj, lb, ub)
            obj.constLb = lb(1);
            obj.constUb = ub(1);

            obj.netWbLb = lb(2:end);
            obj.netWbUb = ub(2:end);
        end

        function useTf = getUseTfForVariable(obj)
            useTf = [obj.varConst, obj.varNetWB(:)'];
        end

        function setUseTfForVariable(obj, useTf)
            obj.varConst = useTf(1);
            obj.varNetWB = useTf(2:end);
        end

        function nameStrs = getStrNamesOfVars(obj)
            x = getwb(obj.net);
            nameStrs = {'Constant Offset'};

            for(i=1:length(x)) %#ok<*NO4LP>
                nameStrs{end+1} = sprintf('Parameter %u', i); %#ok<AGROW>
            end
        end

        function varsStoredInRad = getVarsStoredInRad(obj)
            varsStoredInRad = true;

            x = getwb(obj.net);
            for(i=1:length(x)) %#ok<*NO4LP>
                varsStoredInRad = horzcat(varsStoredInRad, false); %#ok<AGROW>
            end
        end

        function randomizeWB(obj)
            rands = obj.netWbLb + (obj.netWbUb - obj.netWbLb).*rand(size(obj.netWbLb));
            obj.net = setwb(obj.net, rands);
        end
    end

    methods(Static, Access=private)
        function net = createNetwork(hiddenSizes)
%             [x,t] = simplefit_dataset;

            net = fitnet(hiddenSizes);
            net = init(net);
%             net = configure(net,x,t);
        end
    end

    methods(Static)
        function obj = loadobj(obj)
            obj.gpuAvail = gpuDeviceCount("available");
        end
    end
end


%ELLIPSES_DEMO  One-line description here, please.
%
%   output = ellipses_demo(input)
%
%   Example
%   ellipses_demo
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2019-08-09,    using Matlab 9.6.0.1072779 (R2019a)
% Copyright 2019 INRA - Cepia Software Platform.

load fisherIris;
figure; hold on; set(gca, 'fontsize', 14);
colors = {'b', 'g', 'm'};
hi = zeros(1,3);
for i = 1:3
  pts = meas((1:50)+(i-1)*50, 3:4);
  hi(i) = drawPoint(pts, 'marker', 'o', 'color', colors{i}, 'markerfacecolor', colors{i});
  drawEllipse(equivalentEllipse(pts), 'color', colors{i}, 'linewidth', 2);
end
legend(hi, species([1 51 101]), 'Location', 'NorthWest');

print(gcf, 'equivalentEllipse_demo.png');


function results = run_DeepSTRCF(seq, res_path, bSaveImage)

% Feature specific parameters
hog_params.cell_size = 4;
hog_params.compressed_dim = 10;
hog_params.nDim = 31;

grayscale_params.colorspace='gray';
grayscale_params.cell_size = 4;

cn_params.tablename = 'CNnorm';
cn_params.useForGray = false;
cn_params.cell_size = 4;
cn_params.nDim = 10;

cnn_params.nn_name = 'imagenet-vgg-m-2048.mat'; % Name of the network
cnn_params.output_layer = [10];           % Which layers to use
cnn_params.downsample_factor = [1];           % How much to downsample each output layer
cnn_params.input_size_mode = 'adaptive';        % How to choose the sample size
cnn_params.input_size_scale = 1;                % Extra scale factor of the input samples to the network (1 is no scaling)

% Which features to include
params.t_features = {
    struct('getFeature',@get_cnn_layers, 'fparams',cnn_params),...
    struct('getFeature',@get_colorspace, 'fparams',grayscale_params),...
    struct('getFeature',@get_fhog,'fparams',hog_params),...
    struct('getFeature',@get_table_feature, 'fparams',cn_params),...
};

% Global feature parameters
params.t_global.cell_size = 4;                  % Feature cell size

% Image sample parameters
params.search_area_shape = 'square';    % The shape of the samples
params.search_area_scale = 4.5;         % The scaling of the target size to get the search area
params.min_image_sample_size = 200^2;   % Minimum area of image samples
params.max_image_sample_size = 250^2;   % Maximum area of image samples

% Spatial regularization window_parameters
params.feature_downsample_ratio = [4, 14]; %  Feature downsample ratio (We found that decreasing the downsampling ratios of CNN layer may benefit the performance)
params.reg_window_max = 1e5;           % The maximum value of the regularization window
params.reg_window_min = 1e-3;           % The minimum value of the regularization window

% Detection parameters
params.refinement_iterations = 1;       % Number of iterations used to refine the resulting position in a frame
params.newton_iterations = 5;           % The number of Newton iterations used for optimizing the detection score
params.clamp_position = false;          % Clamp the target position to be inside the image

% Learning parameters
params.output_sigma_factor = 1/16;		% Label function sigma
params.temporal_regularization_factor = [15 15]; % The temporal regularization parameters

% ADMM parameters
params.max_iterations = [2 2];
params.init_penalty_factor = [1 1];
params.max_penalty_factor = [0.1, 0.1];
params.penalty_scale_step = [10, 10];

% Scale parameters for the translation model
params.number_of_scales = 5;            % Number of scales to run the detector
params.scale_step = 1.01;               % The scale factor

% Visualization
params.visualization = 1;               % Visualiza tracking and detection scores

% GPU
params.use_gpu = true;                 % Enable GPU or not
params.gpu_id = [];                     % Set the GPU id, or leave empty to use default

% Initialize
params.seq = seq;

% Run tracker
results = tracker(params);


function Xk = nufft_table_adj(st, X)
%function Xk = nufft_table_adj(st, X)
% adjoint of table-based nufft interpolation.
% in
%	st		structure from nufft_init
%	X [M,?]		DTFT values
% out
%	Xk [*Kd,?]	DFT coefficients
% Copyright 2004-3-30, Jeff Fessler and Yingying Zhang, University of Michigan

dd = length(st.Kd);

% t = omega / gamma
tm = zeros(size(st.om));
for id=1:dd
	gam = 2*pi / st.Kd(id);
	tm(:,id) = st.om(:,id) / gam;
end

if size(X,1) ~= st.M
	error 'X size problem'
end

% adjoint of phase shift
if isvar('st.phase_shift') & ~isempty(st.phase_shift)
	X = X .* conj(st.phase_shift);
end

if isreal(X)
	X = complexify(X);
end

if dd == 1
	Xk = interp1_table_adj_mex(X, st.h{1}, ...
		int32(st.Jd), int32(st.Ld), tm, int32(st.Kd(1)));

elseif dd==2
	Xk = interp2_table_adj_mex(X, st.h{1}, st.h{2}, ...
		int32(st.Jd), int32(st.Ld), tm, int32(st.Kd));

elseif dd==3
	Xk = interp3_table_adj_mex(X, st.h{1}, st.h{2}, st.h{3}, ...
		int32(st.Jd), int32(st.Ld), tm, int32(st.Kd));

else
	error '> 3d not done'
end


clear;
%% load file

path_to_package = '';   % path to the folder that contains the package
addpath(genpath(path_to_package));

filename = '';      % path to stack tiff file
%foldername = '';    % path to folder that contains a sequence of tiff files

if exist([filename(1:end-3),'mat'],'file')
    data = matfile([filename(1:end-3),'mat'],'Writable',true);
else
    sframe=1;						% user input: first frame to read (optional, default 1)
    num2read=[];					% user input: how many frames to read   (optional, default until the end)
    chunksize=1000;                 % user input: read and map input in chunks (optional, default read all at once)
    data = memmap_file(filename,sframe,num2read,chunksize);
    %data = memmap_file_sequence(foldername);
end

%% Set parameters
sizY = size(data,'Y');                  % size of data matrix
patch_size = [32,32];                   % size of each patch along each dimension (optional, default: [32,32])
overlap = [4,4];                        % amount of overlap in each dimension (optional, default: [4,4])

patches = construct_patches(sizY(1:end-1),patch_size,overlap);
K = 8;                                            % number of components to be found
tau = 8;                                          % std of gaussian kernel (size of neuron)
p = 0;                                            % order of autoregressive system (p = 0 no dynamics, p=1 just decay, p = 2, both rise and decay)
merge_thr = 0.8;                                  % merging threshold
sizY = data.sizY;

options = CNMFSetParms(...
    'd1',sizY(1),'d2',sizY(2),...
    'search_method','ellipse','dist',3,...      % search locations when updating spatial components
    'deconv_method','constrained_foopsi',...    % activity deconvolution method
    'temporal_iter',2,...                       % number of block-coordinate descent steps
    'ssub',2,...
    'tsub',4,...
    'fudge_factor',0.98,...                     % bias correction for AR coefficients
    'merge_thr',merge_thr,...                    % merging threshold
    'gSig',tau...
    );

%% Run on patches

[A,b,C,f,S,P,RESULTS,YrA] = run_CNMF_patches(data,K,patches,tau,p,options);

%% order and plot

[A_or,C_or,S_or,P] = order_ROIs(A,C,S,P); % order components

contour_threshold = 0.95;                 % amount of energy used for each component to construct contour plot
figure;
[Coor,json_file] = plot_contours(A_or,reshape(P.sn,sizY(1),sizY(2)),contour_threshold,1); % contour plot of spatial footprints
%savejson('jmesh',json_file,'filename');        % optional save json file with component coordinates (requires matlab json library)


function [src,sfi] = zSpecularFreeImage(src)
Lambda = 0.6;
camDark = 20;
r = src.rgb(:,:,1); g = src.rgb(:,:,2); b = src.rgb(:,:,3);
src.i(intersect(intersect(find(r<camDark),find(g<camDark)),...
    find(b<camDark))) = z.CAMERA_DARK;
c = z.MaxChroma(src.rgb);
dI = (z.Max(src.rgb).*(3*c-1))./(c*(3*Lambda-1));
sI = (z.Total(src.rgb)-dI)/3;
drgb = min(255,max(0,src.rgb-sI));
sfi.rgb = drgb;
end


function plotData(x, y)
%PLOTDATA Plots the data points x and y into a new figure

plot(x, y, 'rx', 'MarkerSize', 10); % Plot the data
% Hint: You can use the 'rx' option with plot to have the markers
%       appear as red crosses. Furthermore, you can make the
%       markers larger by using plot(..., 'rx', 'MarkerSize', 10);

ylabel('Profit in $10,000s'); % Set the y ? axis label
xlabel('Population of City in 10,000s'); % Set the x ? axis label

figure; % open a new figure window

end


function [clusterID,EventType,AlgoInfo] = calc_decluster_gardKnop(mCatalog,nMethod,SetMain)
	% decluster earthquake catalog using the Windowing technique in space and time (Knopoff & Gardner)
	%
	% [mCatDecluster, mCatAfter, vCluster, vCl, vMainCluster] = CALC_DECLUSTER_GARDKNOP(mCatalog,nMethod)
	% ----------------------------------------------------------------------------------------------------------
	%
	% Decluster earthquake catalog using the Windowing technique in space and time by
	% Knopoff & Gardner, GJR astr. Soc, 28, 311-313, 1972
	% Gardner & Knopoff, BSSA, 64,5, 1363-1367, 1974
	% using different windows
	%
	% Incoming variables
	% mCatalog : Incoming earthquake catalog (ZMAP format)
	% nMethod  : Window length for declustering (see calc_windows.m)
	%            1: Gardener & Knopoff, 1974
	%            2: Gruenthal pers. communication
	%            3: Urhammer, 1986
	%
	% Outgoing variables:
	% mCatDecluster : Declustered earthquake catalog
	% mCatAfter     : Catalog of aftershocks (and foreshocks)
	% vCluster      : Vector indicating only aftershocks/foreshocls in cluster using a cluster number
	% vCl           : Vector indicating all events in clusters using a cluster number
	% vMainCluster  : Vector indicating mainshocks of clusters using a cluster number
	%
	% J. Woessner, woessner@seismo.ifg.ethz.ch
	% last update: 29.08.02

	%% Added:
	% 31.07.02 Correction for problem of mainshocks with a cluster number as aftershocks belong to two sequences
	% 31.07.02 Corrected fMaxClusterMag(nMagCount) to fMaxClusterMag, since counting variable not needed
	% 31.07.02 Improved resizing time window by adding time difference from initial event to bigger aftershock
	% 13.08.02 Added waitbars
	% 28.08.02 Changed distance determination using now distance and repmat
	% 29.08.02 Cluster determination strategy change: Now selecting all aftershocks using the window of the first shock,
	%          adding the events from the bigger aftershocks (later labelled mainshocks); calc_decluster_ver3.m keeps
	%          resizing technique

	%%% Remember: Improve zero length cluster problem which might appear

	%% Initialize Vectors and Matrices

	import mapseis.declustering.calc_windows_gardKnop;

	%edited for MapSeis: DE 2011
	%This is the first release of the Gardner Knopoff method for mapseis, the code is mainly the same as the zmap version, there might be
	%lot to gain performancewise in case of a rewriting of the code, but for know this should be alright.

	if nargin<3
		SetMain=false;
	end

	mCatDecluster = [];
	mCatAfter = [];
	vCluster = zeros(length(mCatalog),1); % Initialize all events as mainshock
	vCl = zeros(length(mCatalog),1); % Initialize all events as mainshock
	vSel = zeros(length(mCatalog),1); % Initialize all events as mainshock
	vMainCluster = zeros(length(mCatalog),1); % Initialize

	%[B,MagSortID] = sort(mCatalog(:,6),'descend');

	[nXSize, nYsize] = size(mCatalog);
	if nXSize == 0
	    disp('Load new catalog');
	    return
	end

	vDecDate = mCatalog(:,3);
	nCount = 0;    % Variable of cluster number

	fMagThreshold = min(mCatalog(:,6)); % Set Threshold to minimum magnitude of catalog
	hWaitbar1 = waitbar(0,'Identifying clusters...');
	set(hWaitbar1,'Numbertitle','off','Name','Decluster percentage');
	for nEvent=1:length(mCatalog(:,6))
	    %nEvent
	    %nCount
	    %nEvent=MagSortID(iCount);
	    if vCluster(nEvent) == 0

	        fMagnitude(nEvent) = mCatalog(nEvent, 6);

	                  %% Define first aftershock zone and determine magnitude of strongest aftershock
	            fMag = fMagnitude(nEvent);
	            [fSpace, fTime] = calc_windows_gardKnop(fMagnitude(nEvent), nMethod);
	            fSpaceDeg = km2deg(fSpace);

	            %% This first if is for events with no location given
	            if isnan(mCatalog(nEvent,1)) %Does this ever happen??? Maybe in a special study (DE)
	                %Select what's on the same time??? (DE)
	                vSel = (mCatalog(:,3) == mCatalog(nEvent,3));

	            else
	            	%Select what is in range (DE)
	                mPos = [mCatalog(nEvent, 1) mCatalog(nEvent,2)];
	                mPos = repmat(mPos,length(mCatalog(:,1)), 1);
	                mDist = abs(distance(mCatalog(:,1), mCatalog(:,2), mPos(:,1), mPos(:,2)));
	                vSel = ((mDist <= fSpaceDeg) & (vDecDate(:,1)-vDecDate(nEvent,1) >= 0) &...
	                    (vDecDate(:,1)-vDecDate(nEvent,1) <= fTime) & vCluster(nEvent) == 0);

	            end;% End of isnan(mCatalog)

	            %maybe here and especially later is a change needed, because it might be expensive to find the "positon"
	            %in th array later (DE)
	            mTmp = mCatalog(vSel,:);

	            if length(mTmp(:,1)) == 1  % Only one event thus no cluster; IF to determine cluster or not
	                fMaxClusterMag = fMag;

	            else
	                fMaxClusterMag = max(mTmp(:,6));
	                [nIndiceMaxMag] = find(mTmp(:,6) == fMaxClusterMag);
	                fTimeMaxClusterMag = mTmp(max(nIndiceMaxMag),3);

	                %can't stand while loops, try to eliminate it (DE) %probably just sort the whole catalog with magnitude
	                %The while looks ugly but the time it uses is small
	                % Search for event with bigger magnitude in cluster and add to cluster
	                while fMaxClusterMag-fMag > 0
	                    [fSpace, fTime] = calc_windows_gardKnop(fMaxClusterMag, nMethod);
	                    fSpaceDeg = km2deg(fSpace);

	                    %% Adding aftershocks from bigger aftershock
	                    mPos = [mTmp(min(nIndiceMaxMag),1) mTmp(min(nIndiceMaxMag),2)];
	                    mPos = repmat(mPos,length(mCatalog(:,1)), 1);
	                    mDist = abs(distance(mCatalog(:,1), mCatalog(:,2), mPos(:,1), mPos(:,2)));
	                    vSel2 = ((mDist <= fSpaceDeg) & (vDecDate(:,1)-mTmp(min(nIndiceMaxMag),3) >= 0) &...
	                        (vDecDate(:,1)-mTmp(min(nIndiceMaxMag),3) <= fTime) & vCluster == 0);
	                    mTmp = mCatalog(vSel2,:);
	                    %vSel = (vSel > 0 | vSel2 > 0); % Actual addition %>0 not needed both are logical vectors (DE)
	                    vSel = vSel|vSel2;
	                    if isempty(mTmp) % no events in aftershock zone
	                        break;
	                    end;

	                    fMag = fMaxClusterMag;
	                    fMaxClusterMag = max(mTmp(:,6));
	                    [nIndiceMaxMag] = find(mTmp(:,6) == fMaxClusterMag);
	                    fTimeMaxClusterMag = mTmp(max(nIndiceMaxMag),3);

	                    if fMaxClusterMag - fMag == 0 % no bigger event in aftershock zone
	                        break;
	                    end;

	                end;  % End of while

	                nCount = nCount + 1; % Set cluster number

	            end; % End of if length(mTmp)

	            [vIndice]=find(vSel); % Vector of indices with Clusters
	            vTmpCluster(vIndice,:) = nCount;
	            %length(vTmpCluster(vIndice,:));
	            nI=1; % Variable counting the length of the cluster
	            % Select the right numbers for the cluster using the indice vector vIndice
	            % First: Insert cluster number after check for length
	            % Second: Check if it's a mainshock
	            % Third: Keep the former cluster indice;
	            while nI <= length(vIndice)
	                if (~isempty(vTmpCluster(vIndice(nI))) & length(vTmpCluster(vIndice,:)) > 1 & vCluster(vIndice(nI)) == 0)
	                    vCluster(vIndice(nI)) = vTmpCluster(vIndice(nI));
	                    %vEventnr(vIndice,:) = nEvent;
	                elseif  (~isempty(vTmpCluster(vIndice(nI))) & length(vTmpCluster(vIndice,:)) == 1 & vCluster(vIndice(nI)) == 0)
	                    vCluster(vIndice(nI)) = 0;
	                else
	                    vCluster(vIndice(nI)) = vCluster(vIndice(nI));
	                end;
	                nI=nI+1;
	            end; %End of while nI
	            %                 nCount = nCount + 1; % Set cluster number %% Watch
	            %             end; % End of if to determine cluster or not %% Watch
	            %%% Check if the Cluster is not just one event which can happen in case of keeping the former
	            %%% cluster number in preceeding while-Loop
	            vSelSingle = (vCluster == nCount);
	            [vIndiceSingle] = find(vSelSingle);
	            %vTmpSingle(vIndiceSingle,:);
	            if length(vIndiceSingle) == 1
	                %nCount
	                %vIndiceSingle
	                vCluster(vIndiceSingle)=0; % Set the event as mainsock
	                nCount = nCount-1; % Correct the cluster number down by one
	            end;

	    end; % End of if checking if vCluster == 0
	    if rem(nEvent,100) == 0
	        waitbar(nEvent/length(mCatalog(:,6)))
	    end; % End updating waitbar
	end; % End of FOR over mCatalog
	close(hWaitbar1);
	%nCount
	%% vCL Cluster vector with mainshocks in it; vCluster is now modified to get rid of mainshocks
	vCl = vCluster;

	%% Matrix with cluster indice, magnitude and time
	mTmpCat = [vCluster mCatalog(:,6) mCatalog(:,3)];
	%% Delete largest event from cluster series and add to mainshock catalog
	hWaitbar2 = waitbar(0,'Identifying mainshocks in clusters...');
	set(hWaitbar2,'Numbertitle','off','Name','Mainshock identification ');
	for nCevent = 1:nCount
	    %nCevent
	    vSel4 = (mTmpCat(:,1) == nCevent); % Select cluster
	    mTmpCat2 = mCatalog(vSel4,:);
	    fTmpMaxMag = max(mTmpCat2(:,6)); % Select max magnitude of cluster
	    vSelMag = (mTmpCat2(:,6) == fTmpMaxMag);
	    [nMag] = find(vSelMag);
	    if length(nMag) == 1
	        vSel5 = (mTmpCat(:,1) == nCevent & mTmpCat(:,2) == fTmpMaxMag); % Select the event
	        [vIndiceMag] = find(vSel5); % Find indice
	        vCluster(vIndiceMag) = 0;  % Set cluster value to zero, so it is a mainshock
	        vMainCluster(vIndiceMag) = nCevent; % Set mainshock vector to cluster number
	    elseif length(nMag) == 0
	        disp('Nothing in ')
	        nCevent
	    else
	        vSel = (mTmpCat(:,1) == nCevent & mTmpCat(:,2) == fTmpMaxMag);
	        mTmpCat3 = mCatalog(vSel,:);
	        [vIndiceMag] = min(find(vSel)); % Find minimum indice of event with max magnitude in cluster
	        vCluster(vIndiceMag) = 0;  % Set cluster value to zero, so it is a mainshock
	        vMainCluster(vIndiceMag) = nCevent;  % Set mainshock vector to cluster number
	    end;
	    if rem(nCevent,20) == 0
	        waitbar(nCevent/nCount)
	    end; % End updating waitbar
	end; % End of For nCevent
	close(hWaitbar2);
	%% Create a catalog of aftershocks (mCatAfter) and of declustered catalog (mCatDecluster)
	vSel = (vCluster(:,1) > 0);
	%mCatDecluster=mCatalog(~vSel,:);
	%mCatAfter = mCatalog(vSel,:);

	%create the wanted output for mapseis
	%clusterID,EventType,AlgoInfo
	EventType = categorical(ones(length(mCatalog,1)),...
		[0 1 2 3],...
		{'unclassified','single event','mainshock','aftershock'});
	clusterID=vCl;

	%the type first
	EventType(vCl~=0)='mainshock';
	EventType(vCluster~=0)='aftershock';
	clusterID(clusterID==0)=NaN;

	%The original does not set a mainshock if all earhquakes in a cluster have the same Magnitude, this part will
	%if SetMain is set to true choose the first eq as mainshock, which is as the catalog should be sorted by time
	%the first in the list
	%Also does the original code determine the length of the clusters, this here will do it
	uniqueClust=unique(clusterID(~isnan(clusterID)));
	ClusterLength=zeros(numel(uniqueClust),1);
	if SetMain
		for i=1:numel(ClusterLength);
			ClusterLength(i)=sum(clusterID==uniqueClust(i));

			if all(EventType(clusterID==uniqueClust(i))=='aftershock')
				TheInder=find(clusterID==uniqueClust(i));
				EventType(TheInder(1))='mainshock';
			end
		end

	else
		for i=1:numel(ClusterLength);
			ClusterLength(i)=sum(clusterID==uniqueClust(i));
		end

	end

	CalcParameter.Method=nMethod;
	CalcParameter.SetMain=SetMain;

	AlgoInfo.Type='Gardner-Knopoff-mapseis-v1';
	AlgoInfo.UsedConfig=CalcParameter;
	AlgoInfo.CalculationDate=date;
	AlgoInfo.ClusterLengths=ClusterLength;
	AlgoInfo.largest_Eq=[];

end


function check = uniform_check ( a, b )

%*****************************************************************************80
%
%% UNIFORM_CHECK checks the parameters of the Uniform CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the parameters of the PDF.
%    A < B.
%
%    Output, logical CHECK, is true if the parameters are legal.
%
  if ( b <= a )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'UNIFORM_CHECK - Fatal error!\n' );
    fprintf ( 1, '  B <= A.\n' );
    check = 0;
    return
  end

  check = 1;

  return
end


function display_element ( prefix, element )

%*****************************************************************************80
%
%% DISPLAY_ELEMENT lists the coordinates of nodes making up an element.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 June 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string PREFIX, the common filename prefix for the node and
%    element files.
%
%    Input, integer ELEMENT, the index of the element.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'DISPLAY_ELEMENT\n' );
  fprintf ( 1, '  List coordinates of the nodes making up an element.\n' );
  fprintf ( 1, '  Element and node file prefix is "%s".\n', prefix );

  element_filename = sprintf ( '%s_elements.txt', prefix );
  node_filename = sprintf ( '%s_nodes.txt', prefix );

  element_node = load ( element_filename );
  node_xyz = load ( node_filename );

  [ element_num, element_order ] = size ( element_node );
  [ node_num, dim_num ] = size ( node_xyz );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  LEO ordering:\n' );
  fprintf ( 1, '  Node coordinates for element %d\n', element );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   I     N          X                 Y               Z\n' );
  fprintf ( 1, '\n' );
  for j = 1 : element_order
    n = element_node(element,j);
    fprintf ( 1, '  %2d  %4d  %14.6g  %14.6g  %14.6g\n', j, n, node_xyz(n,1:3) );
  end

  leo_to_gmsh = [...
     1,  2,  3,  4,  5, ...
     7, 10, 11,  8,  6, ...
    12, 18, 19, 13, 20, ...
    14,  9, 15, 16, 17 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Gmsh ordering:\n' );
  fprintf ( 1, '  Node coordinates for element %d\n', element );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   I     N          X                 Y               Z\n' );
  fprintf ( 1, '\n' );
  for j = 1 : element_order
    k = leo_to_gmsh(j);
    n = element_node(element,k);
    fprintf ( 1, '  %2d  %4d  %14.6g  %14.6g  %14.6g\n', j, n, node_xyz(n,1:3) );
  end
  return
end