function [delete]=PlotInitialStateMatrix3D(ToPlotOrNot)

if ToPlotOrNot==1
    for k=1:size(state,3)
        for j=1:size(state,2)
            for i=1:size(state,1)
                if state(i,j,k)==1
                    plot3(x(i,j,k),y(i,j,k),z(i,j,k),'k.');hold on;
                end
            end
        end
    end
end
axis square;box on

github-repos/MATLAB/Sable-mcbench-benchmarks/mcbench-benchmarks-ba13b2f0296ef49491b95e3f984c7c41fccdb6d8/34985-monte-carlo-simulation-of-three-dimensional-grain-growth-code-version-no-1-basic/Monte Carlo Simulation Q-state Potts model 3D square-lattice - microstructure/PlotInitialStateMatrix_3D_QPOTTS.m


function f = processmulti1D(fun,varargin)

% function f = processmulti1D(fun,varargin)
%
% <fun> is a function that expects a row vector as the first argument
% <varargin> is a set of inputs.  the first input should be one or multiple row vectors
%   concatenated along the first dimension.  the remaining inputs are the
%   same as expected by <fun>.
%
% apply <fun> to each vector and concatenate the results together (along the first dimension).
%
% example:
% isequal(processmulti1D(@mean,[1 2 3; 4 5 6]),[2; 5])

  prev = warning('query');  % make sure stupid warning about obsolete blkproc doesn't come on
  warning('off');
f = [];
for p=1:size(varargin{1},1)
  if p==1
    f = feval(fun,varargin{1}(p,:),varargin{2:end});  % this ensures class is respected
  else
    f = cat(1,f,feval(fun,varargin{1}(p,:),varargin{2:end}));
  end
end
  warning(prev);


classdef TestConvertPointsFromHomogeneous
    %TestConvertPointsFromHomogeneous

    methods (Static)
        function test_numeric_3d
            pts = shiftdim([1,2,1; 4,5,1], -1);
            dst = cv.convertPointsFromHomogeneous(pts);
            validateattributes(dst, {class(pts)}, {'size',[2 1 3-1]});
        end

        function test_numeric_4d
            pts = shiftdim([1,2,3,1; 4,5,6,1], -1);
            dst = cv.convertPointsFromHomogeneous(pts);
            validateattributes(dst, {class(pts)}, {'size',[2 1 4-1]});
        end

        function test_cellarray_3d
            pts = {[1,2,1], [4,5,1]};
            dst = cv.convertPointsFromHomogeneous(pts);
            validateattributes(dst, {'cell'}, {'vector', 'numel',numel(pts)});
            cellfun(@(p) validateattributes(p, {'numeric'}, ...
                {'vector', 'numel',3-1}), dst);
        end

        function test_cellarray_4d
            pts = {[1,2,3,1], [4,5,6,1]};
            dst = cv.convertPointsFromHomogeneous(pts);
            validateattributes(dst, {'cell'}, {'vector', 'numel',numel(pts)});
            cellfun(@(p) validateattributes(p, {'numeric'}, ...
                {'vector', 'numel',4-1}), dst);
        end

        function test_all_formats_and_dims
            verify_numeric = @(M,n,d) assert( ...
                ismatrix(M) && isequal(size(M),[n d-1]));
            verify_cell = @(C,n,d) assert( ...
                iscell(C) && numel(C)==n && ...
                all(cellfun(@isvector, C)) && ...
                all(cellfun(@numel, C) == (d-1)));
            % 3D/4D to 2D/3D
            n = 10;
            klass = {'double', 'single'};
            for k=1:numel(klass)
                for d=[3 4]
                    % Nxd numeric matrix
                    ptsH = rand([n,d], klass{k});
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {klass{k}}, {'2d', 'size',[n d-1]});

                    % Nx1xd numeric matrix
                    ptsH = rand([n,1,d], klass{k});
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {klass{k}}, {'3d', 'size',[n 1 d-1]});

                    % 1xNxd numeric matrix
                    ptsH = rand([1,n,d], klass{k});
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {klass{k}}, {'3d', 'size',[n 1 d-1]});

                    % Nx1 cell array of 1xd points
                    ptsH = num2cell(rand([n,d], klass{k}), 2);
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {'cell'}, {'vector', 'numel',n});
                    cellfun(@(p) validateattributes(p, {'numeric'}, ...
                        {'vector', 'numel',d-1}), pts);

                    % 1xN cell array of 1xd points
                    ptsH = num2cell(rand([n,d], klass{k}), 2).';
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {'cell'}, {'vector', 'numel',n});
                    cellfun(@(p) validateattributes(p, {'numeric'}, ...
                        {'vector', 'numel',d-1}), pts);

                    % 1xN cell array of dx1 points
                    ptsH = num2cell(rand([d,n], klass{k}), 1);
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {'cell'}, {'vector', 'numel',n});
                    cellfun(@(p) validateattributes(p, {'numeric'}, ...
                        {'vector', 'numel',d-1}), pts);

                    % Nx1 cell array of dx1 points
                    ptsH = num2cell(rand([d,n], klass{k}), 1).';
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                    validateattributes(pts, {'cell'}, {'vector', 'numel',n});
                    cellfun(@(p) validateattributes(p, {'numeric'}, ...
                        {'vector', 'numel',d-1}), pts);
                end
            end
        end

        function test_last_dimension
            % xn = 0, xn = 1, and arbitrary xn
            for xn=[0 1 rand()]
                for d=[3 4]
                    ptsH = {[rand(1,d-1),xn], [rand(1,d-1),xn]};
                    pts = cv.convertPointsFromHomogeneous(ptsH);
                end
            end
        end

        function test_error_argnum
            try
                cv.convertPointsFromHomogeneous();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function output = ...
  AnalyzeAperiodicity(x, fs, f0, frame_time, analysis_condition)
% F0 refinement and aperiodicity analysis
%
% output = ...
%   AnalyzeAperiodicity(x, fs, f0, frame_time, analysis_condition)
%
%  Input argument
%    x: speech signal, one dimensional column vector
%    fs: sampling frequency (Hz)
%    f0: initial F0 estimate (Hz)
%    frame_time: time location of the center of the analysis window
%    analysis_condition: structure variable with following fields
%      n_harmonics_for_H : number of harmonic components to use in
%        harmonics based F0 refinement
%      window_magnification_for_H : time window stretching facotor from
%        the permissible shortest length
%      enable_downsampling_for_H : 1: enables down sampling before analysis
%      conditions_for_T : structure variable array for defining condition
%        for time-warping based F0 refinement with the following fields
%        n_harmonics : number of harmonics to be uses
%        window_magnification : time window stretching facotor from
%          the permissible shortest length
%        enable_downsampling : 1: enables down sampling before analysis
%
%  Return value
%    output : structure variable with the following fields
%      aperiodicity_matrix : aperiodicity of each harmonic component
%      refined_f0 : refined F0 (Hz)
%      frame_time : analysis window center location at each frame (s)

% Copyright 2016 Google Inc. All Rights Reserved
% Author: hidekik@google.com (Hideki Kawahara)

narginchk(4, 5);
if nargin < 5, analysis_condition = GenerateAperiodicityAnalysisCondition; end;
start_tic = tic;
n_harmonics_for_H = analysis_condition.n_harmonics_for_H;
window_magnification_for_H = analysis_condition.window_magnification_for_H;
enable_downsampling_for_H = analysis_condition.enable_downsampling_for_H;
% Since at the very beginning F0 information is not very reliable,
% it is necessary to refine it without using F0 adaptive time warping
% Effects of time warping propagates to all the following process.
% The fundamental component is usually damaged by microphone low-cut for
% preventing proximity effect and background noise is stronger in lower
% frequency region. In addition, time warping procedure is fragile.
% It should be used carefully.
[refined_f0, ~] = RefineF0byHarmonics(x, fs, f0, frame_time, ...
  n_harmonics_for_H, window_magnification_for_H, enable_downsampling_for_H);
% Recursively apply time-warping based F0 refinement
conditions_for_T = analysis_condition.conditions_for_T;
n_steps = size(conditions_for_T, 2);
f0_last = refined_f0;
for ii = 1:n_steps
  [refined_f0, aperiodicity_matrix] = ...
    RefineF0byTimeWarping(x, fs, f0_last, frame_time, ...
                          conditions_for_T(ii).n_harmonics , ...
                          conditions_for_T(ii).window_magnification, ...
                          conditions_for_T(ii).enable_downsampling);
  f0_last = refined_f0;
end;
output = struct('aperiodicity_matrix', aperiodicity_matrix, ...
                'refined_f0', f0_last, 'sampling_frequency', fs, ...
                'frame_time', frame_time, 'elapsed_time', toc(start_tic));
end


Network Resnet50 {
	Layer CONV1 {
		Type: CONV
		Stride { X: 2, Y: 2 }
		Dimensions { K: 64, C: 3, R: 7, S: 7, Y:224, X:224 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(14,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_1_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 64, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_1_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 64, R: 3, S: 3, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_1_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 64, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_1_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_2_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_2_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 64, R: 3, S: 3, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_2_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 64, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_2_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_3_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_3_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 64, C: 64, R: 3, S: 3, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_3_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 64, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV2_3_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_1_1 {
		Type: CONV
		Stride { X: 2, Y: 2 }
		Dimensions { K: 128, C: 256, R: 1, S: 1, Y: 56, X: 56 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_1_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 128, R: 3, S: 3, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_1_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 128, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_1_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 512, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_2_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 256, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_2_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 128, R: 3, S: 3, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_2_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 128, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_1_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 512, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_3_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 256, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_3_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 128, R: 3, S: 3, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_3_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 128, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_3_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 512, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_4_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 256, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_4_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 128, C: 128, R: 3, S: 3, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_4_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 128, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV3_4_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 512, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_1_1 {
		Type: CONV
		Stride { X: 2, Y: 2 }
		Dimensions { K: 256, C: 512, R: 1, S: 1, Y: 28, X: 28 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_1_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_1_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_1_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_2_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_2_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_2_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_2_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_3_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_3_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_3_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_3_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_4_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_4_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_4_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_4_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_5_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_5_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_5_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_5_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_6_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_6_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 256, C: 256, R: 3, S: 3, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_6_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1024, C: 256, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV4_6_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_1_1 {
		Type: CONV
		Stride { X: 2, Y: 2 }
		Dimensions { K: 512, C: 1024, R: 1, S: 1, Y: 14, X: 14 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_1_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 512, R: 3, S: 3, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_1_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 2048, C: 512, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_1_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 2048, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_2_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 2048, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_2_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 512, R: 3, S: 3, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_2_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 2048, C: 512, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_2_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 2048, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_3_1 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 2048, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_3_2 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 512, C: 512, R: 3, S: 3, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(10,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_3_3 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 2048, C: 512, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer CONV5_3_Residual {
		Type: DSCONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1, C: 2048, R: 1, S: 1, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

	Layer FC1000 {
		Type: CONV
		Stride { X: 1, Y: 1 }
		Dimensions { K: 1000, C: 2048, R: 7, S: 7, Y: 7, X: 7 }
		Dataflow {
			TemporalMap(1,1) K;
			TemporalMap(1,1) C;
			SpatialMap(Sz(R), 1) Y;
			TemporalMap(8,8) X;
			Cluster(8, P);
			SpatialMap(Sz(S), 1) X;
			TemporalMap(Sz(R), Sz(R)) R;
			TemporalMap(Sz(R), Sz(R)) S;
		}

	}

}


function [ly] = ft2ly(ft)
% Convert length from feet to light years.
% Chad A. Greene 2012
ly = ft*3.221738542107e-17;


function [Eft, Covft, ljpyt, Eyt, Covyt] = gpia_jpred(gp_array, x, y, varargin)
%GPIA_JPRED  Prediction with Gaussian Process GP_IA solution.
%
%  Description
%    [EFT, COVFT] = GPIA_JPRED(GP_ARRAY, X, Y, XT, OPTIONS)
%    takes a cell array of GP structures together with matrix X of
%    training inputs and vector Y of training targets, and
%    evaluates the predictive distribution at test inputs XT with
%    parameters marginalized out with IA. Returns a posterior mean
%    EFT and covariance COVFT of latent variables.
%
%    [EFT, COVFT, JPYT, EYT, COVYT] = GPIA_JPRED(GP, X, Y, XT, 'yt', YT, ...)
%    returns also logarithm of the predictive joint density PYT of
%    the observations YT at test input locations XT with parameters
%    marginalized out with IA. This can be used for example in the
%    cross-validation. Here Y has to be vector. Returns also
%    posterior predictive mean EYT and covariance COVYT.
%
%    [EF, COVF, LJPY, EY, COVY] = GPIA_JPRED(GP, X, Y, OPTIONS)
%    evaluates the predictive distribution at training inputs X
%    and logarithm of the joint predictive density JPY of the training
%    observations Y.
%
%    OPTIONS is optional parameter-value pair
%      predcf - index vector telling which covariance functions are
%               used for prediction. Default is all (1:gpcfn). See
%               additional information below.
%      tstind - a vector/cell array defining, which rows of X belong
%               to which training block in *IC type sparse models.
%               Deafult is []. In case of PIC, a cell array
%               containing index vectors specifying the blocking
%               structure for test data. IN FIC and CS+FIC a vector
%               of length n that points out the test inputs that
%               are also in the training set (if none, set TSTIND=[])
%      yt     - optional observed yt in test points (see below)
%      z      - optional observed quantity in triplet (x_i,y_i,z_i)
%               Some likelihoods may use this. For example, in case
%               of Poisson likelihood we have z_i=E_i, that is,
%               expected value for ith case.
%      zt     - optional observed quantity in triplet (xt_i,yt_i,zt_i)
%               Some likelihoods may use this. For example, in case
%               of Poisson likelihood we have z_i=E_i, that is, the
%               expected value for the ith case.
%
%    NOTE! In case of FIC and PIC sparse approximation the
%    prediction for only some PREDCF covariance functions is just
%    an approximation since the covariance functions are coupled in
%    the approximation and are not strictly speaking additive
%    anymore.
%
%    For example, if you use covariance such as K = K1 + K2 your
%    predictions Eft1 = gpia_pred(gp_array, X, Y, X, 'predcf', 1) and
%    Eft2 = gpia_pred(gp_array, x, y, x, 'predcf', 2) should sum up to
%    Eft = gpia_pred(gp_array, x, y, x). That is Eft = Eft1 + Eft2. With
%    FULL model this is true but with FIC and PIC this is true only
%    approximately. That is Eft \approx Eft1 + Eft2.
%
%    With CS+FIC the predictions are exact if the PREDCF covariance
%    functions are all in the FIC part or if they are CS
%    covariances.
%
%    NOTE! When making predictions with a subset of covariance
%    functions with FIC approximation the predictive variance can
%    in some cases be ill-behaved i.e. negative or unrealistically
%    small. This may happen because of the approximative nature of
%    the prediction.
%
%  See also
%    GP_PRED, GP_SET, GP_IA
%
% Copyright (c) 2009 Ville Pietil�inen
% Copyright (c) 2009-2010 Jarno Vanhatalo
% Copyright (c) 2011-2012 Ville Tolvanen
% Copyright (c) 2012 Aki Vehtari

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

  ip=inputParser;
  ip.FunctionName = 'GPIA_JPRED';
  ip.addRequired('gp_array', @iscell);
  ip.addRequired('x', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
  ip.addRequired('y', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
  ip.addOptional('xt', [], @(x) isempty(x) || (isreal(x) && all(isfinite(x(:)))))
  ip.addParamValue('yt', [], @(x) isreal(x) && all(isfinite(x(:))))
  ip.addParamValue('z', [], @(x) isreal(x) && all(isfinite(x(:))))
  ip.addParamValue('zt', [], @(x) isreal(x) && all(isfinite(x(:))))
  ip.addParamValue('predcf', [], @(x) isempty(x) || ...
                   isvector(x) && isreal(x) && all(isfinite(x)&x>0))
  ip.addParamValue('tstind', [], @(x) isempty(x) || iscell(x) ||...
                   (isvector(x) && isreal(x) && all(isfinite(x)&x>0)))
  if numel(varargin)==0 || isnumeric(varargin{1})
    % inputParser should handle this, but it doesn't
    ip.parse(gp_array, x, y, varargin{:});
  else
    ip.parse(gp_array, x, y, [], varargin{:});
  end
  xt=ip.Results.xt;
  yt=ip.Results.yt;
  z=ip.Results.z;
  zt=ip.Results.zt;
  predcf=ip.Results.predcf;
  tstind=ip.Results.tstind;
  if isempty(xt)
    xt=x;
    if isempty(tstind)
      if iscell(gp_array)
        gptype=gp_array{1}.type;
      else
        gptype=gp_array.type;
      end
      switch gptype
        case {'FULL' 'VAR' 'DTC' 'SOR'}
          tstind = [];
        case {'FIC' 'CS+FIC'}
          tstind = 1:size(x,1);
        case 'PIC'
          if iscell(gp)
            tstind = gp_array{1}.tr_index;
          else
            tstind = gp_array.tr_index;
          end
      end
    end
    if isempty(yt)
      yt=y;
    end
    if isempty(zt)
      zt=z;
    end
  end

  % pass these forward
  options=struct();
  if ~isempty(yt);options.yt=yt;end
  if ~isempty(z);options.z=z;end
  if ~isempty(zt);options.zt=zt;end
  if ~isempty(predcf);options.predcf=predcf;end
  if ~isempty(tstind);options.tstind=tstind;end

  if nargout > 2 && isempty(yt)
    pyt = NaN;
  end

  nGP = numel(gp_array);

  % Make predictions with different models in gp_array
  for i1=1:nGP
    P_TH(:,i1) = gp_array{i1}.ia_weight;
    if nargout <= 2
      [Efts(:,i1), Covfts(:,:,i1)]=gp_jpred(gp_array{i1},x,y,xt,options);
    else
      [Efts(:,i1), Covfts(:,:,i1), ljpyts(i1), Eyts(:,i1), Covyts(:,:,i1)]=gp_jpred(gp_array{i1},x,y,xt, options);
    end
  end

  % Calculate mean and variance of the distributions
  Eft = sum(bsxfun(@times,Efts,P_TH), 2);
  % Calculate covariances of means
  Efts = bsxfun(@minus,Efts,Eft);
  for i1=1:nGP
    CovEfts(:,:,i1)=Efts(:,i1)'*Efts(:,2);
  end
  % Covariance is E(Cov)+Cov(E)
  Covft = squeeze(sum(bsxfun(@times, Covfts, permute(P_TH,[1 3 2])), 3)) ...
          + sum(bsxfun(@times, CovEfts, permute(P_TH,[1 3 2])), 3);

  % Calculate jpyt with weight given in P_TH.
  if nargout > 2
    if isempty(yt)
      ljpyt = [];
    else
      ljpyt = log(sum(exp(ljpyts)'.*P_TH));
    end
  end

  if nargout > 3
    Eyt = sum(bsxfun(@times,Eyts,P_TH),2);
    Covyt = squeeze(sum(bsxfun(@times, Covyts, permute(P_TH,[1 3 2])), 3)) ...
            + diag(sum(bsxfun(@times,bsxfun(@minus,Eyts,Eyt).^2, P_TH),2));
  end


%--- help for generic/simulate ---
%
%  simulate - simulates a RISE model
%
%  ::
%
%
%    [db,states,retcode] = simulate(obj,varargin)
%
%  Args:
%
%     - **obj** [rfvar|dsge|rise|svar]: model object
%
%     - **varargin** : additional arguments including but not restricted to
%
%       - **simul_periods** [integer|{100}]: number of simulation periods
%
%       - **simul_burn** [integer|{100}]: number of burn-in periods. This
%       should not be confused with forecast_conditional_sampling_burnin, which
%       is used in the sampling from the truncated multivariate normal
%       distribution.
%
%       - **simul_historical_data** [ts|struct|{''}]: historical data from
%           which the simulations are based. If empty, the simulations start at
%           the steady state.
%
%       - **simul_history_end_date** [char|integer|serial date]: last date of
%           history
%
%       - **simul_regime** [integer|vector|function handle|{[]}]: regimes for
%           which the model is simulated. When it is a function handle, then it
%           should accept as inputs y (array over all regimes),
%           regimes_1_t_1(regimes from 1 to t-1), sims_1_t_1(the simulated
%           series up to t-1),varargin (possibly further arguments to the
%           function handle). The output is a logical vector that is true for
%           the columns that are acceptable/feasible and false otherwise.
%
%       - **simul_to_time_series** [{true}|false]: if true, the output is a
%           time series, else a cell array with a matrix and information on
%           elements that help reconstruct the time series.
%
%       - **simul_honor_constraints** [true|{false}]: honor restrictions during
%           simulations. If true, agents have to be able anticipate the future.
%
%       - **simul_frwrd_back_shoot** [true|{false}]: uses an algorithm that
%       checks the constraints are satisfied at all horizons instead of just
%       one at a time.
%
%       - **simul_shock_uncertainty** [{true}|false]: draw shocks over the
%       simulation horizon.
%
%       - **simul_honor_constraints_through_switch** [true|{false}]: if true,
%       constraints are honored through the switching mechanism. In that case
%       the number of regimes should be greater than 1. If false, constraints
%       are honored through an anticipatory behavior. In this case, there
%       should be shocks that are foreseen.
%
%       - **simul_anticipate_zero** [true|{false}]: When shocks are drawn, this
%       option allows to impose that agents continue to see only the
%       contemporaneous shocks.
%
%       - **simul_bgp_deviation** [true|{false}]: When the model is
%       nonstationary, a growth component appears in the solution. This option
%       enables or disables that component.
%
%  Returns:
%     :
%
%     - **db** [struct|cell array]: if **simul_to_time_series** is true, the
%       output is a time series, else a cell array with a matrix and
%       information on elements that help reconstruct the time series.
%
%     - **states** [vector]: history of the regimes over the forecast horizon
%
%     - **retcode** [integer]: if 0, the simulation went fine. Else something
%       got wrong. In that case one can understand the problem by running
%       decipher(retcode)
%
%  Note:
%
%     - **simul_historical_data** contains the historical data as well as
%       conditional information over the forecast horizon. It may also include
%       as an alternative to **simul_regime**, a time series with name
%       **regime**, which indicates the regimes over the forecast horizon.
%
%  Example:
%
%     See also:
%
%    Other functions named simulate
%
%       arima/simulate           garch/simulate
%       conjugateblm/simulate    gjr/simulate
%       customblm/simulate       regARIMA/simulate
%       diffuseblm/simulate      sde/simulate
%       dsge/simulate            semiconjugateblm/simulate
%       dtmc/simulate            ssm/simulate
%       egarch/simulate          varm/simulate
%       empiricalblm/simulate    vecm/simulate
%


function [CEImage] = runCLAHE(Image,XRes,YRes,Min,Max,NrX,NrY,NrBins,Cliplimit)

%  "Contrast Limited Adaptive Histogram Equalization"
%  by Karel Zuiderveld, karel@cv.ruu.nl
%  in "Graphics Gems IV", Academic Press, 1994
%  (Ported to Matlab by Leslie Smith)
%
%   These functions implement Contrast Limited Adaptive Histogram Equalization.
%   The main routine (CLAHE) expects an input image that is stored contiguously in
%   memory;  the CLAHE output image overwrites the original input image and has the
%   same minimum and maximum values (which must be provided by the user).
%   This implementation assumes that the X- and Y image resolutions are an integer
%   multiple of the X- and Y sizes of the contextual regions. A check on various other
%   error conditions is performed.
%
%
%    Image - The input/output image
%    XRes - Image resolution in the X direction
%    YRes - Image resolution in the Y direction
%    Min - Minimum greyvalue of input image (also becomes minimum of output image)
%    Max - Maximum greyvalue of input image (also becomes maximum of output image)
%    NrX - Number of contextial regions in the X direction (min 2, max uiMAX_REG_X)
%    NrY - Number of contextial regions in the Y direction (min 2, max uiMAX_REG_Y)
%    NrBins - Number of greybins for histogram ("dynamic range")
%    Cliplimit - Normalized cliplimit (higher values give more contrast)
%  The number of "effective" greylevels in the output image is set by uiNrBins; selecting
%  a small value (eg. 128) speeds up processing and still produce an output image of
%  good quality. The output image will have the same minimum and maximum value as the input
%  image. A clip limit smaller than 1 results in standard (non-contrast limited) AHE.

% [XRes,YRes]=size(Image);
% CEimage = Image;
CEImage = zeros(XRes,YRes);
if Cliplimit == 1
    return
end

NrBins=max(NrBins,128);
XSize = round(XRes/NrX);
YSize = round(YRes/NrY);
NrPixels = XSize*YSize;
XSize2 = round(XSize/2);
YSize2 = round(YSize/2);

if Cliplimit > 0
    ClipLimit = max(1,Cliplimit*XSize*YSize/NrBins);
else
    ClipLimit = 1E8;
end

LUT=makeLUT(Min,Max,NrBins);
% avgBin = NrPixels/NrBins;
Bin=1+LUT(round(Image));

Hist = makeHistogram(Bin,XSize,YSize,NrX,NrY,NrBins);
if Cliplimit > 0
    Hist = clipHistogram(Hist,NrBins,ClipLimit,NrX,NrY);
end
Map=mapHistogram(Hist,Min,Max,NrBins,NrPixels,NrX,NrY);

% Interpolate
xI = 1;
for i = 1:NrX+1
    if i == 1
        subX = XSize/2;
        xU = 1;
        xB = 1;
    elseif i == NrX+1
        subX = XSize/2;
        xU = NrX;
        xB = NrX;
    else
        subX = XSize;
        xU = i - 1;
        xB = i;
    end
    yI = 1;
    for j = 1:NrY+1
        if j == 1
            subY = YSize/2;
            yL = 1;
            yR = 1;
        elseif j == NrY+1
            subY = YSize/2;
            yL = NrY;
            yR = NrY;
        else
            subY = YSize;
            yL = j - 1;
            yR = j;
        end
        UL = Map(xU,yL,:);
        UR = Map(xU,yR,:);
        BL = Map(xB,yL,:);
        BR = Map(xB,yR,:);
        subImage = Bin(xI:xI+subX-1,yI:yI+subY-1);
        subImage = interpolate(subImage,UL,UR,BL,BR,subX,subY);
        CEImage(xI:xI+subX-1,yI:yI+subY-1) = subImage;
        yI = yI + subY;
    end
    xI = xI + subX;
end


function vissurf = get_cube_visible_surface(cube, vp)

% cube surfaceid
% botid = 1; % 1: bottom
% frtid = 2; % 2: front
% lftid = 3; % 3: left
% rhtid = 4; % 4: right
% bckid = 5; % 5: back
% topid = 6; % 6: top

% cube junc3 id
%   5---6   1------2
%  /   /|   |      |
% 1---2 8   3------4    ....
% |   |/     \    /
% 3---4       7--8
%
% 1: front,top,left
% 2: front,top,right
% ...
% 8: back,bottom,right

%% determine visible surfaces

regionid1 = getregionid(cube.junc3(1).pt(1), cube.junc3(1).pt(2), vp);
regionid2 = getregionid(cube.junc3(2).pt(1), cube.junc3(2).pt(2), vp);
regionid3 = getregionid(cube.junc3(3).pt(1), cube.junc3(3).pt(2), vp);
regionid4 = getregionid(cube.junc3(4).pt(1), cube.junc3(4).pt(2), vp);

% vissurf = zeros(1,5); % [1234(front), 1256(top), 3478(bot), 1357(left), 2468(right)]
vissurf = zeros(1,6); % 3478(bot), 1234(front), 1357(left), 2468(right), 5678(back), 1256(top)

%bot
if (regionid3==1 || regionid3==2) && (regionid4==1 || regionid4==2)
    vissurf(1) = 1;
end

%front -- always visible
vissurf(2) = 1;

%left
if (regionid1==2 || regionid1==4) && (regionid3==2 || regionid3==4)
    vissurf(3) = 1;
end

%right
if (regionid2==1 || regionid2==3) || (regionid4==1 || regionid4==3)
    vissurf(4) = 1;
end

%back -- always invisible
vissurf(5) = 0;

%top
if (regionid1==3 || regionid1==4) && (regionid2==3 || regionid2==4)
    vissurf(6) = 1;
end

%% old
% % % regionid1 = getregionid(cube.junc3(1).pt(1), cube.junc3(1).pt(2), vp);
% % % regionid2 = getregionid(cube.junc3(2).pt(1), cube.junc3(2).pt(2), vp);
% % % regionid3 = getregionid(cube.junc3(3).pt(1), cube.junc3(3).pt(2), vp);
% % % regionid4 = getregionid(cube.junc3(4).pt(1), cube.junc3(4).pt(2), vp);
% % %
% % % vissurf = zeros(1,5); % [1234(front), 1256(top), 3478(bot), 1357(left), 2468(right)]
% % % %front -- always visible
% % % vissurf(1) = 1;
% % % %top
% % % if (regionid1==3 || regionid1==4) && (regionid2==3 || regionid2==4)
% % %     vissurf(2) = 1;
% % % end
% % % %bot
% % % if (regionid3==1 || regionid3==2) && (regionid4==1 || regionid4==2)
% % %     vissurf(3) = 1;
% % % end
% % % %left
% % % if (regionid1==2 || regionid1==4) && (regionid3==2 || regionid3==4)
% % %     vissurf(4) = 1;
% % % end
% % % %right
% % % if (regionid2==1 || regionid2==3) || (regionid4==1 || regionid4==3)
% % %     vissurf(5) = 1;
% % % end


% Wrapper for vl_nnscale2D block
% inputs{1} :   X     : 1 x 2 x n x b
% inputs{2} :   S     : 1 x 1 x 1 x b
% outputs{1}:   y     : 1 x 2 x n x b

classdef scale2D < dagnn.Layer
    methods
        function outputs = forward(~, inputs, ~)

            useGPU = isa(inputs{1}, 'gpuArray');
            if useGPU
                outputs{1} = gpuArray( vl_nnscale2D(gather(inputs{1}), gather(inputs{2})) );
            else
                outputs{1} = vl_nnscale2D(inputs{1}, inputs{2});
            end

        end

        function [derInputs, derParams] = backward(~, inputs, ~, derOutputs)

            useGPU = isa(inputs{1}, 'gpuArray');
            if useGPU
                [y,dsdy] =  vl_nnscale2D(gather(inputs{1}), gather(inputs{2}), gather(derOutputs{1}));
                derInputs = {gpuArray(y),gpuArray(dsdy)};
            else
                [y,dsdy] =  vl_nnscale2D(inputs{1}, inputs{2}, derOutputs{1});
                derInputs = {y,dsdy};
            end

            derParams = {};
        end

        function outputSizes = getOutputSizes(~, inputSizes)
            outputSizes = inputSizes{1};
        end

        function obj = scale2D(varargin)
            obj.load(varargin);
        end
    end
end


classdef MTCMO < ALGORITHM
% <multi> <real/integer/label/binary/permutation> <constrained>
% Multitasking constrained multi-objective optimization

%------------------------------- Reference --------------------------------
% K. Qiao, K. Yu, B. Qu, J. Liang, H. Song, C. Yue, H. Lin, and K. C. Tan,
% Dynamic auxiliary task-based evolutionary multitasking for constrained
% multi-objective optimization, IEEE Transactions on Evolutionary
% Computation, 2022.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

% This function is written by Kangjia Qiao

    methods
        function main(Algorithm,Problem)
            %% Generate random population
            Population1 = Problem.Initialization();
            Fitness1    = CalFitness(Population1.objs,Population1.cons);

            Population2 = Problem.Initialization();
            Fitness2   = CalFitness(Population2.objs,Population2.cons);

            cons = [Population1.cons;Population2.cons];
            cons(cons<0) = 0;
            VAR0 = max(sum(cons,2));
            if VAR0 == 0
                VAR0 = 1;
            end
            X=0;

            %% Optimization
            while Algorithm.NotTerminated(Population1)
                %% Udate the epsilon value
                cp  = (-log(VAR0)-6)/log(1-0.5);
                VAR = VAR0*(1-X)^cp;
                %% Offspring generation
                MatingPool1 = TournamentSelection(2,Problem.N,Fitness1);
                Offspring1  = OperatorGAhalf(Problem,Population1(MatingPool1));

                MatingPool2 = TournamentSelection(2,Problem.N,Fitness2);
                Offspring2  = OperatorGAhalf(Problem,Population2(MatingPool2));
                %% Environmental selection
                [Population1,Fitness1] = Main_task_EnvironmentalSelection([Population1,Offspring1,Offspring2],Problem.N,true);
                [Population2,Fitness2] = Auxiliray_task_EnvironmentalSelection([Population2,Offspring2,Offspring1],Problem.N,VAR);
                X = X + 1/(Problem.maxFE/Problem.N);
            end
        end
    end
end


% rmart() - Remove eye artifacts from EEG data using regression with
%           multiple time lags. Each channel is first made mean-zero.
%           After JL Kenemans et al., Psychophysiology 28:114-21, 1991.
%
%   Usage: >> rmart('datafile','outfile',nchans,chanlist,eogchan,[threshold])
% Example: >> rmart('noisy.floats','clean.floats',31,[2:31],7)
%
%   Input:   datafile - input float data file, multiplexed by channel
%            outfile  - name of output float data file
%            nchans   - number of channels in datafile
%            chanlist - indices of EEG channel(s) to process (1,...,nchans)
%            eogchan  - regressing channel indices(s) (1,...,nchans)
%            threshold- abs threshold value to trigger regression {def|0 -> 80}
%
% Output: Writes [length(chanlist),size(data,2)] floats to 'outfile'
%
% Note: Regression epoch length and number of lags are set in the script.
%       Some machines may require a new byte_order value in the script.
%       note that runica() -> icaproj() should give better results! See
%       Jung et al., Psychophysiology 111:1745-58, 2000.
%
% Author: Tzyy-Ping Jung, SCCN/INC/UCSD, La Jolla, 1997

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

% 2-22-97  Tzyy-Ping Jung  CNL/Salk Institute, La Jolla, CA
% 2-24-97  Formatted for ICA package release -Scott Makeig
% 12-10-97 Changed name from rmartifact to rmart for toolbox inclusion -sm
% 12-11-97 Adapted to read/write a float matrix -sm & sw
% 09-14-00 Added comments and help -sm
% 01-25-02 reformated help & license -ad

function rmart(datafile,outfile,nchans,chanlist,eogchan,threshold)

if nargin < 5
   help rmart
   return
end

%
% The following parameters may be fine-tuned for a data set
%
DEF_THRESHOLD = 80; % trigger regression on blocks exceeding this (default)
epoch         = 80; % remove artifacts in successive blocks of this length
nlags         = 40; % perform multiple regression filtering of this length

byte_order    = 'b';% (machine-dependent) byte order code for fopen();
MAKE_MEAN_ZERO = 1  % 1/0 flag removing mean offset from each channel

fprintf('Performing artifact regression on data in %s.\n',datafile);

if nargin<6
   threshold = 0;
end
if threshold == 0,
   threshold = DEF_THRESHOLD;
end
fprintf('Regression threshold %g.\n',threshold);

%
% Read the input data
%
[fid,msg]=fopen(datafile,'r',byte_order); % open datafile
if fid < 3,
  fprintf('rmart() - could not open data file: %s\n',msg);
  exit 1
end
data=(fread(fid,'float'))';
status=fclose('all');
if rem(length(data),nchans) == 0 % check length
   fprintf('rmart() - data length not divisible by %d chans.\n',nchans);
    return
end

data = reshape(data,nchans,length(data)/nchans);
[chans,frames] = size(data);
fprintf('Data of size [%d,%d] read.\n',chans,frames);
eog = data(eogchan,:);
data = data(chanlist,:);
procchans = length(chanlist);

fprintf('Regression epoch length %d frames.\n',epoch);
fprintf('Using %d regression lags.\n',nlags);
if length(eogchan)> 1
  fprintf('Processing %d of %d channels using %d EOG channels.\n',...
                        procchans,chans,length(eogchan));
else
  fprintf('Processing %d of %d channels using EOG channel %d.\n',...
                        procchans,chans,eogchan);
end

%
% Process the data
%
for i=1:procchans
  chan = chanlist(i);
  idx=[];
  frame=1+epoch/2+nlags/2;
  if MAKE_MEAN_ZERO
    data(chan,:) = data(chan,:) - mean(data(chan,:)); % make mean-zero
  end

  % Search the EOG & EEG records for values above threshold,
  % Selected frame numbers are registered in the variable "idx".
  % The entries in "idx" are at least epoch apart to avoid double
  % compensation (regression) on the same portion of the EEG data.

  while frame <= length(eog)-epoch/2-nlags/2,  % foreach epoch in channel
    stop = min(frame+epoch-1,eogframes);
    tmp= ...
        find( abs(eog(frame:stop)) >= threshold ...
             | abs(data(chan,frame:stop)) >= threshold);
                                           % find beyond-threshold values
    if length(tmp) ~= 0
      mark = tmp(1)+frame-1;
      if  length(idx) ~= 0
        if mark-idx(length(idx))  < epoch,
           idx=[idx idx(length(idx))+epoch]; % To guarantee idx(i) & idx(i-1)
                                             % are at least EPOCH points apart
           frame = idx(length(idx))+epoch/2;
        else
           idx=[idx mark];
           frame = mark + epoch/2;
        end
      else
        idx=[idx mark];
        frame = mark + epoch/2;
      end
    else
      frame=frame+epoch;
    end
  end % while

  % For each registered frame, take "epoch" points
  % surrounding it from the EEG, and "epoch + lag" points
  % from the EOG channel. Then perform multivariate
  % linear regression on EEG channel.

  for j=1:length(idx);
     art=ones(1,epoch);
     eogtmp=eog(idx(j)-epoch/2-nlags/2:idx(j)+epoch/2-1+nlags/2);

     % Collect EOG data from lag/2 points before to lag/2 points
     % after the regression window.
     for J=nlags:-1:1,
       art=[art ; eogtmp(J:J+epoch-1)];
     end
     eegtmp=data(chan,idx(j)-epoch/2:idx(j)+epoch/2-1);

     eegeog=eegtmp*art';        % perform the regression here
     eogeog=art*art';
     b=eegeog/eogeog;
     eegtmp=eegtmp-b*art;
     data(chan,idx(j)-epoch/2:idx(j)+epoch/2-1)=eegtmp;
   end % j
end % i

%
% Write output file
%
[fid,msg]=fopen(outfile,'w',byte_order);
if fid < 3
  fprintf('rmart() - could not open output file: %s\n',msg);
  return
end
count = fwrite(fid,data,'float');
if count == procchans*frames,
  fprintf('Output file "%s" written, size = [%d,%d] \n\n',...
             outfile,procchans,frames);
else
  fprintf('rmart(): Output file "%s" written, SIZE ONLY [%d,%g]\n',...
             outfile,procchans,count/procchans);
end
fclose('all');


% A demo for evaluation on SYSU-MM01 dataset using features learned by deep
% zero padding in "RGB-Infrared Cross-Modality Person Re-identification"

% Features of each cameras are saved in seperated mat files named "name_cam#.mat"
% In the mat files, feature{id}(i,:) is a row feature vector of the i-th image of id
feature_info.name = 'feat_deep_zero_padding';
feature_info.dir = './feature';
result_dir = './result'; % directory for saving result

setting.mode = 'all_search'; %'all_search' 'indoor_search'
setting.number_shot = 1; % 1 for single shot, 10 for multi-shot

model.test_fun = @euclidean_dist; % Similarity measurement function
% (You could define your own function in the same way as euclidean_dist function)
model.name = 'euclidean'; % model name
model.para = []; % No parameter is needed for euclidean distance here
% (If mahalanobis distance is used, the parameter can be the metric M learned from training data)

% load data split
content = load('./data_split/test_id.mat'); % fixed testing person IDs
data_split.test_id = content.id;

content = load('./data_split/rand_perm_cam.mat'); % fixed permutation of samples in each camera
data_split.rand_perm_cam = content.rand_perm_cam;

% evaluation
performance = evaluation_SYSU_MM01(feature_info, data_split, model, setting, result_dir);


function [d,x0,xv,idx,delay_offset] = driving_function_imp_localwfs_vss(x0,xs,src,conf)
%DRIVING_FUNCTION_IMP_LOCALWFS_VSS driving signal for local WFS using focused
%sources as virtual secondary sources
%
%   Usage: [d,x0,xv,idx,delay_offset] =
%               driving_function_imp_localwfs_vss(x0,xs,src,conf)
%
%   Input parameters:
%       x0          - position and direction of the secondary source / m [nx7]
%       xs          - position of virtual source or direction of plane
%                     wave / m [1x3]
%       src         - source type of the virtual source
%                         'pw' - plane wave (xs is the direction of the
%                                plane wave in this case)
%                         'ps' - point source
%                         'ls' - line source
%                         'fs' - focused source
%       conf        - configuration struct (see SFS_config)
%
%   Output parameters:
%       d             - driving signals [mxn]
%       x0            - position, direction, and weights of the real secondary
%                       sources / m [nx7]
%       xv            - position, direction, and weights of the virtual
%                       secondary sources / m [mx7]
%       idx           - index of the selected sources from the original x0
%                       matrix [mx1]
%       delay_offset  - additional added delay, so you can correct it
%
%   See also: plot_sound_field, sound_field_mono_wfs
%
%   References:
%       Spors and Ahrens (2010) - "Local Sound Field Synthesis by Virtual
%       Secondary Sources", 40th Conference of the Audio Engineering Society,
%       Paper 6-3, http://www.aes.org/e-lib/browse.cfm?elib=15561
%

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

%% ===== Checking of input  parameters ==================================
nargmin = 4;
nargmax = 4;
narginchk(nargmin,nargmax);
isargsecondarysource(x0);
isargxs(xs);
isargchar(src);
isargstruct(conf);

%% ===== Configuration ==================================================
virtualconf = conf;
virtualconf.usetapwin = conf.localwfs_vss.usetapwin;
virtualconf.tapwinlen = conf.localwfs_vss.tapwinlen;
virtualconf.secondary_sources.size = conf.localwfs_vss.size;
virtualconf.secondary_sources.center = conf.localwfs_vss.center;
virtualconf.secondary_sources.geometry = conf.localwfs_vss.geometry;
virtualconf.secondary_sources.number = conf.localwfs_vss.number;
virtualconf.wfs = conf.localwfs_vss.wfs;
virtualconf.nfchoa = conf.localwfs_vss.nfchoa;
virtualconf.driving_functions = conf.localwfs_vss.driving_functions;
method = conf.localwfs_vss.method;

%% ===== Computation ====================================================
if strcmp('fs',src)
    error(['%s: %s is not a supported method source type! Try to use a', ...
        ' point source, if the source is inside the secondary source array', ...
        ' but not inside the virtual secondary source array'], ...
        upper(mfilename),src);
end

% Determine driving functions of virtual array with different sfs methods
switch method
case 'wfs'
    % === Wave Field Synthesis ===
    % Create virtual source array
    xv = virtual_secondary_source_positions(x0,xs,src,conf);
    % Secondary_source_selection
    xv = secondary_source_selection(xv, xs, src);
    % Optional tapering
    xv = secondary_source_tapering(xv,virtualconf);
    % Driving functions for virtual source array
    [dv,~,~,delay_offset] = driving_function_imp_wfs(xv,xs,src,virtualconf);
case 'nfchoa'
    % === Near-Field-Compensated Higher Order Ambisonics ===
    % Create virtual source array
    xv = secondary_source_positions(virtualconf);
    % Driving functions for virtual source array
    [dv,~,delay_offset] = driving_function_imp_nfchoa(xv,xs,src,virtualconf);
otherwise
    error('%s: %s is not a supported method for localsfs!',upper(mfilename),...
      method);
end

% Select secondary sources
[x0,idx] = secondary_source_selection(x0,xv(:,1:6),'vss');
% Driving functions for real source array
[d,delay_vss] = driving_function_imp_wfs_vss(x0,xv,'fs',dv,conf);
% add delay
delay_offset = delay_offset + delay_vss;


function fcn_Plot_StationaryLeader(p_all_time, v_all_time, a_all_time, error_all, aDiff_all)
close all

global nodenum edgenum neighborMat dim simTime leaderNum kp kv
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plot a subset of the data, because too much data
delta=50;
time_all=v_all_time.time(1:delta:end);
p_all=p_all_time.signals.values(1:delta:end,:);
v_all=v_all_time.signals.values(1:delta:end,:);
a_all=a_all_time.signals.values(1:delta:end,:);
error_all=error_all.signals.values(1:delta:end,:);
aDiff_all=aDiff_all.signals.values(1:delta:end,:);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
linewidth=0.5;
dotsize=7;
fontsize=7;%15;
formationColor=0*[0 0 1];
% edgeColorList=zeros(nodenum,3);
faceColorList=zeros(nodenum,3);
for i=1:nodenum
    if i<=leaderNum
        faceColorList(i,:)=[1,0,0];
    else
        faceColorList(i,:)=[0,0,1];
    end
end
for i=1:nodenum
    if i<=leaderNum
        markerList(i)={'o'};
    else
        markerList(i)={'o'};
    end
end
for i=1:nodenum
    if i<=leaderNum
        linestyleList(i)={'-'};
    else
        linestyleList(i)={'--'};
    end
end
%% plot trajectory
figure;
subplot(4,1,[1,2,3]); % to make the axis short
hold on; box on;
set(gca, 'fontSize', fontsize)
set(get(gca, 'xlabel'), 'String', 'x (m)', 'fontSize', fontsize);
set(get(gca, 'ylabel'), 'String', 'y (m)', 'fontSize', fontsize);
%set(get(gca, 'zlabel'), 'String', 'z (m)', 'fontSize', fontsize);
axis equal
set(gca, 'fontsize', fontsize);
%plot trajectory
for i=1:nodenum
    if dim==2
        xi_all=p_all(:,2*i-1);
        yi_all=p_all(:,2*i);
        plot(xi_all, yi_all, ':', 'linewidth', linewidth, 'color', faceColorList(i,:));
    else
        xi_all=p_all(:,3*i-2);
        yi_all=p_all(:,3*i-1);
        zi_all=p_all(:,3*i);
        plot3(xi_all, yi_all, zi_all, ':', 'linewidth', linewidth, 'color', faceColorList(i,:));
    end
end
% plot obstacle
leftx=18;
width=5;
h=rectangle('Position', [leftx, 1.8, width, 15]);
set(h, 'faceColor', 0.4*ones(1,3))
h=rectangle('Position', [leftx, -16.5, width, 14.5]);
set(h, 'faceColor', 0.4*ones(1,3))
h=rectangle('Position', [leftx, -25, width, 6.5]);
set(h, 'faceColor', 0.4*ones(1,3))
text(20.5, -9, 'Obstacle','color', 'w', 'FontSize', 8, 'horizontalAlignment', 'center', 'FontWeight', 'normal', 'Rotation', 0, 'fontname', 'Times');

axis tight
xlim=get(gca,'xlim');
set(gca,'xlim', xlim+[-5,5]);
ylim=get(gca,'ylim');
set(gca,'ylim', ylim+[-4,3]);
% title
%set(get(gca, 'title'), 'String', 'Trajectory', 'fontsize', fontsize);

%% plot intermediate formations
dataNum=size(p_all,1);
hMarkerAll=zeros(nodenum,1);
index=[1,floor(dataNum/10*1.4),floor(dataNum/10*2.2),floor(dataNum/10*3.2),floor(dataNum/10*4.47),...
    floor(dataNum/10*5.3),floor(dataNum/10*6.45),floor(dataNum/10*7.2),floor(dataNum/10*8),floor(dataNum/10*9),floor(dataNum/10*10)]; % for 2D scale big example
% index=[1,floor(dataNum/10*10)];
for k=1:size(index,2)
    idx=index(k);
    for i=1:nodenum
        for j=1:nodenum
            if neighborMat(i,j)==1
                if dim==2
                    pi=p_all(idx,2*i-1:2*i)';
                    pj=p_all(idx,2*j-1:2*j)';
                    line([pi(1),pj(1)], [pi(2),pj(2)], 'linewidth', 0.5, 'color', formationColor);
                    %fcn_plotArrow((pi+pj)/2, (pj-pi)/norm(pj-pi), initialColor, linewidth)
                else
                    pi=p_all(idx,3*i-2:3*i)';
                    pj=p_all(idx,3*j-2:3*j)';
                    line([pi(1),pj(1)], [pi(2),pj(2)], [pi(3),pj(3)], 'linewidth', 0.5, 'color', formationColor);
                    %fcn_plotArrow((pi+pj)/2, (pj-pi)/norm(pj-pi),
                    %initialColor, linewidth)
                end
            end
        end
    end
    for i=1:nodenum
        if dim==2
            xi=p_all(idx,2*i-1);
            yi=p_all(idx,2*i);
            hMarkerAll(i)=plot(xi, yi, char(markerList(i)), 'MarkerEdgeColor', 'k', 'MarkerFaceColor', faceColorList(i,:), 'markersize', dotsize, 'linewidth', 0.5);
            text(xi, yi, num2str(i),'color', 'w', 'FontSize', 5, 'horizontalAlignment', 'center', 'FontWeight', 'bold');
        else
            xi=p_all(idx,3*i-2);
            yi=p_all(idx,3*i-1);
            zi=p_all(idx,3*i);
            hMarkerAll(i)=plot3(xi, yi, zi, char(markerList(i)), 'MarkerEdgeColor', 'k', 'MarkerFaceColor', faceColorList(i,:), 'markersize', dotsize, 'linewidth', 1);
        end
    end
end
hLegendTraj=legend([hMarkerAll(1),hMarkerAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'West');
%set(hLegendTraj, 'pos', [0.14, 0.72, 0.2375, 0.1333]);
% axis tight
% margin=1;
% xlim=get(gca,'xlim');
% set(gca,'xlim', xlim+[-margin,margin]);
% ylim=get(gca,'ylim');
% set(gca,'ylim', ylim+[-margin,margin]);

% plot time for corresponding formation
text(0, 5, strcat('t=',num2str(time_all(index(1)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(10, 5, strcat('t=',num2str(time_all(index(2)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(33, 5, strcat('t=',num2str(time_all(index(4)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(45, 5, strcat('t=',num2str(time_all(index(5)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(50, -7, strcat('t=',num2str(time_all(index(6)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(50, -17, strcat('t=',num2str(time_all(index(7)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(38, -22, strcat('t=',num2str(time_all(index(8)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(28, -22, strcat('t=',num2str(time_all(index(9)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(14, -22, strcat('t=',num2str(time_all(index(10)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');
text(3, -22, strcat('t=',num2str(time_all(index(11)),'%.1f'),'s'),'color', 'k', 'FontSize', fontsize+1, 'horizontalAlignment', 'center', 'FontName', 'times');

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plot error
figure
subplot(5,1,1) % to make the axis short
hold on; box on
% set the format of the axis
set(gca, 'fontSize', fontsize)
% set(get(gca, 'xlabel'), 'String', 'Time (s)', 'fontSize', fontsize);
set(get(gca, 'ylabel'), 'String', 'Tracking error', 'fontSize', fontsize);
set(gca, 'xlim', [0,simTime])
% set(gca, 'ylim', [0,10])
plot(time_all, error_all, 'color', 'm', 'linewidth', 1)
% set(get(gca, 'title'), 'String', strcat('Tracking error: kp=',num2str(kp),', kv=',num2str(kv)), 'fontsize', fontsize);

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plot velocity
% figure
hLineAll=zeros(nodenum,1);
if dim==2
    % x velocity
    subplot(5,1,2)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, v_all(:,2*i-1), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'x-velocity (m/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    set(gca, 'ylim', [-3,3])
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
    % y velocity
    subplot(5,1,3)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, v_all(:,2*i), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'y-velocity (m/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    set(gca, 'ylim', [-3,3])
%     set(get(gca, 'xlabel'), 'String', 'Time (s)', 'fontSize', fontsize);
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
elseif dim==3 % plot vx and vy
    % x velocity
    subplot(3,1,1)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, v_all(:,3*i-2), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'x-velocity (m/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
    % title
    set(get(gca, 'title'), 'String', 'Velocity', 'fontsize', fontsize);
    % y velocity
    subplot(3,1,2)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, v_all(:,3*i-1), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'y-velocity (m/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(3)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
    % z velocity
    subplot(3,1,3)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, v_all(:,3*i), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'xlabel'), 'String', 'Time (sec)', 'fontSize', fontsize);
    set(get(gca, 'ylabel'), 'String', 'z-velocity (m/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(3)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
end

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plot acceleration
% figure
hLineAll=zeros(nodenum,1);
if dim==2
    % x velocity
    subplot(5,1,4)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, a_all(:,2*i-1), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'x-acceleration (m^2/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
    % title
%     set(get(gca, 'title'), 'String', 'Acceleration', 'fontsize', fontsize);
    % y velocity
    subplot(5,1,5)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, a_all(:,2*i), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'y-acceleration (m^2/s)', 'fontSize', fontsize);
    set(get(gca, 'xlabel'), 'String', 'Time (s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
end

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% plot acceleration error
figure
hLineAll=zeros(nodenum,1);
if dim==2
    % x velocity
    subplot(5,1,1)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, aDiff_all(:,2*i-1), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'x-aDiff (m^2/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    % y velocity
    subplot(5,1,2)
    hold on; box on;
    for i=1:nodenum
        hLineAll(i)=plot(time_all, aDiff_all(:,2*i), 'color', faceColorList(i,:), 'linestyle', char(linestyleList(i)), 'linewidth', 1);
    end
    set(gca, 'fontSize', fontsize)
    set(get(gca, 'ylabel'), 'String', 'y-aDiff (m^2/s)', 'fontSize', fontsize);
    set(gca, 'xlim', [0,simTime])
    set(get(gca, 'xlabel'), 'String', 'Time (s)', 'fontSize', fontsize);
    hLegend=legend([hLineAll(1),hLineAll(leaderNum+1)], 'Leader', 'Follower', 'location', 'southwest');
    set(hLegend, 'fontsize', fontsize);
end


function F = tan(F, varargin)
%TAN   Tangent of a CHEBFUN.
%   TAN(F) computes the tangent of the CHEBFUN F.
%
%   TAN(F, PREF) does the same but uses the CHEBFUNPREF object PREF when
%   computing the composition.
%
% See also ATAN, TAND.

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

% [TODO]:  Restore or change this once we have decided the proper behavior or
% isfinite() and defined that function.
% if ( ~isfinite(f) )
%     error('CHEBFUN:CHEBFUN:tan:inf',...
%         'SIN is not defined for functions which diverge to infinity');
% end

% Call the compose method:
F = compose(F, @tan, varargin{:});

end


function G = rayxgridfRCC(F, transla, val)
%------------------------------------------------------------------------------
% Multiplies gridfunction F with element of stencil given by its value
% val and its position transla.
% Excess area is filled by Cell-Centered (CC) Reflection across boundaries.
%
% Design and implementation by:
% Dr. Paul M. de Zeeuw <Paul.de.Zeeuw@cwi.nl>  http://homepages.cwi.nl/~pauldz/
% Last Revision: June 23, 2000.
% (c) 1999-2002 Stichting CWI, Amsterdam.
%------------------------------------------------------------------------------
o=[0 0];
if ~all(size(o) == size(transla))
  error(' rayxgridfRCC - unexpected dimensions of transla ')
end
G = val * moveLRRCC(moveUDRCC(F, -transla(1)), -transla(2));
%------------------------------------------------------------------------------


function gopt = illustration_options(gdefault, varargin)
%ILLUSTRATION_OPTIONS Options for illustrations of EQ partitions
%
%Syntax
% gopt = illustration_options(gdefault,options);
%
%Description
% GOPT = ILLUSTRATION_OPTIONS(GDEFAULT,options) collects illustration options,
% specified as name, value pairs, and places these into the structure GOPT.
% The structure GDEFAULT is used to define default option values.
%
% The structures gdefault and gopt may contain the following fields:
% fontsize:      numeric
% long_title:    boolean
% stereo:        boolean
% show_points:   boolean
% show_sphere:   boolean
% show_surfaces: boolean
%
% The following illustration options are available.
%
% 'fontsize':    Font size used in titles.
%      number    Assigns number to field gopt.fontsize.
%
% 'title':       Length of titles.
%     'long':    Long titles.
%                Sets gopt.show_title to true.
%                Sets gopt.long_title to true.
%     'short':   Short titles.
%                Sets gopt.show_title to true.
%                Sets gopt.long_title to false.
%     'none':    No titles.
%                Sets gopt.show_title to false.
%                Sets gopt.long_title to false.
%     'show':    Show default titles.
%                Sets gopt.show_title to true.
%     'hide':    Same as 'none'.
%
% 'proj':        Projection from the sphere to the plane R^2 or the space R^3.
%     'stereo':  Stereographic projection from the sphere to the whole space.
%                Sets gopt.stereo to true.
%     'eqarea':  Equal area projection from the sphere to the disk or ball.
%                Sets gopt.stereo to false.
%
% 'points':      Show or hide center points of regions.
%     'show':    Show center points of regions.
%                Sets gopt.show_points to true.
%     'hide':    Hide center points of regions.
%                Sets gopt.show_points to false.
%
% 'sphere':      Show or hide the sphere S^2.
%     'show':    Show sphere.
%                Sets gopt.show_sphere to true.
%     'hide':    Hide sphere.
%                Sets gopt.show_sphere to false.
%
% 'surf':        Show or hide surfaces of regions of a partition of S^3.
%     'show':    Show surfaces of regions.
%                Sets gopt.show_surfaces to true.
%     'hide':    Hide surfaces of regions.
%                Sets gopt.show_surfaces to false.
%
%Examples
% > gdefault.fontsize=14;
% > gopt=illustration_options(gdefault,'proj','stereo')
% gopt =
%     fontsize: 14
%       stereo: 1
%
% > gopt=illustration_options(gdefault,'proj','stereo','fontsize',12)
% gopt =
%    fontsize: 12
%      stereo: 1

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

gopt = gdefault;
nargs = length(varargin);
nopts = floor(nargs/2);
opt_args = {varargin{1:2:2*nopts-1}};
for k=1:nopts
    if ~ischar([opt_args{k}])
        fprintf('Option names must be character strings\n');
        option_error(varargin{:});
    end
end
opt_vals = {varargin{2:2:2*nopts}};

option_name = 'fontsize';
pos = strmatch(option_name,opt_args,'exact');
if ~isempty(pos)
    if (length(pos) == 1)
        gopt.fontsize = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
end

option_name = 'title';
pos = strmatch(option_name,opt_args,'exact');
if ~isempty(pos)
    if (length(pos) == 1)
        value = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
    switch value
    case 'long'
        gopt.show_title = true;
        gopt.long_title = true;
    case 'short'
        gopt.show_title = true;
        gopt.long_title = false;
    case 'none'
        gopt.show_title = false;
        gopt.long_title = false;
    case 'hide'
        gopt.show_title = false;
    case 'hide'
        gopt.show_title = false;
        gopt.long_title = false;
    case 'show'
        gopt.show_title = true;
    otherwise
        value_error(value,varargin{:});
    end
end

option_name = 'proj';
pos = strmatch(option_name,opt_args);
if ~isempty(pos)
    if (length(pos) == 1)
        value = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
    switch value
    case 'stereo'
        gopt.stereo = true;
    case 'eqarea'
        gopt.stereo = false;
    otherwise
        value_error(value,varargin{:});
    end
end

option_name = 'points';
pos = strmatch(option_name,opt_args,'exact');
if ~isempty(pos)
    if (length(pos) == 1)
        value = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
    switch value
    case 'show'
        gopt.show_points = true;
    case 'hide'
        gopt.show_points = false;
    otherwise
        value_error(value,varargin{:});
    end
end

option_name = 'surf';
pos = strmatch(option_name,opt_args);
if ~isempty(pos)
    if (length(pos) == 1)
        value = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
    switch value
    case 'show'
        gopt.show_surfaces = true;
    case 'hide'
        gopt.show_surfaces = false;
    otherwise
        value_error(value,varargin{:});
    end
end

option_name = 'sphere';
pos = strmatch(option_name,opt_args);
if ~isempty(pos)
    if (length(pos) == 1)
        value = opt_vals{pos};
    else
        duplicate_error(option_name,varargin{:});
    end
    switch value
    case 'show'
        gopt.show_sphere = true;
    case 'hide'
        gopt.show_sphere = false;
    otherwise
        value_error(value,varargin{:});
    end
end
%
% end function

function duplicate_error(option_name,varargin)
fprintf('Duplicate option %s\n',option_name);
option_error(varargin{:});
%
% end function

function value_error(value,varargin)
fprintf('Invalid option value ');
disp(value);
option_error(varargin{:});
%
% end function

function option_error(varargin)
fprintf('Error in options:\n');
disp(varargin);
error('Please check "help illustration_options" for options');
%
% end function


classdef maskPaintBrush < handle

    properties
        handles
        position                    %[x y radius]
        Visible = 'on';
        color = [206 82 65]./256;
        nPoints = 20;
        oldWBMF
        oldPTR
    end

    events
    end

    methods
        %Contructor
        function brush = maskPaintBrush(tool)

            %get the parent axes handle
            h = getHandles(tool);
            brush.handles.parent = h.Axes;
            brush.handles.fig = h.fig;
            brush.handles.tool=tool;

            %get the mouse location
            cp = get(brush.handles.parent,'CurrentPoint'); cp=[cp(1,1) cp(1,2)];
            position = [cp(1,1) cp(1,2) brush.handles.tool.brushsize];

            %Create the circle object
            pos = [position(1)-position(3) position(2)-position(3) 2*position(3) 2*position(3)];
            brush.handles.circle = rectangle('Position',pos,'Parent',brush.handles.parent,'EdgeColor',brush.color,'LineWidth',1.5,'Curvature',[1 1],'PickableParts','all');

            %Get the old window button motion function
            brush.oldWBMF = get(brush.handles.fig,'WindowButtonMotionFcn');

            %Get the old pointer style
            brush.oldPTR.ptr = get(brush.handles.fig,'Pointer');
            brush.oldPTR.CData = get(brush.handles.fig,'PointerShapeCData');

            %Make the pointer invisible
            %set(brush.handles.fig,'Pointer','custom','PointerShapeCData',nan(16))

            %Set the new window button motion function
            fun = @(src,evnt) ButtonMotionFunction(src,evnt,brush,'No Click',[]);
            set(brush.handles.fig,'WindowButtonMotionFcn',fun)

            %Set the mouse click function
            fun=@(hObject,eventdata) buttonDownFunction(hObject,eventdata,brush);
            set(brush.handles.circle,'ButtonDownFcn',fun)

            %set the position property of the brush
            brush.position=position;

        end

        function delete(brush)  %destructor
            try
                delete(brush.handles.circle);
                set(brush.handles.fig,'Pointer',brush.oldPTR.ptr,'PointerShapeCData',brush.oldPTR.CData,'WindowButtonMotionFcn',brush.oldWBMF);
            end
        end

        function set.position(brush,position)
            brush.position=position;
            pos = [position(1)-position(3) position(2)-position(3) 2*position(3) 2*position(3)];
            set(brush.handles.circle,'Position',pos);
        end

        function set.Visible(brush,visible)
            set(brush.handles.cirlce,'Visible',visible);
        end

        function mask = getBrushMask(brush)
            %This function creates a binary mask based on the current
            %position of the mask

            t=linspace(0,2*pi,brush.nPoints); %elliptical equation is parameterized by t
            x = brush.position(3)*cos(t)+brush.position(1);
            y= brush.position(3)*sin(t)+brush.position(2);
            S = getImageSize(brush.handles.tool);
            mask = poly2mask(x,y,S(1),S(2));

        end

        function answer = isInAxis(brush)

            xlim=get(brush.handles.parent,'Xlim');
            ylim=get(brush.handles.parent,'Ylim');

            if brush.position(1)>=xlim(1) && brush.position(1)<=xlim(2) && brush.position(2)>=ylim(1) && brush.position(2)<=ylim(2)
                answer = true;
            else
                answer = false;
            end

        end
    end

end

function buttonUpFunction(hObject,eventdata,WBMF_old,WBUF_old,brush)
set(hObject,'WindowButtonMotionFcn',WBMF_old,'WindowButtonUpFcn',WBUF_old);
notify(brush.handles.tool,'maskChanged')

end

function buttonDownFunction(hObject,eventdata,brush)

WBMF_old = get(brush.handles.fig,'WindowButtonMotionFcn');
WBUF_old = get(brush.handles.fig,'WindowButtonUpFcn');
switch get(brush.handles.fig,'SelectionType')
    case 'normal'   %left click (paint on the mask)
        fun = @(src,evnt) ButtonMotionFunction(src,evnt,brush,'Left Click',[]);
        fun2=@(src,evnt) buttonUpFunction(src,evnt,WBMF_old,WBUF_old,brush);
        set(brush.handles.fig,'WindowButtonMotionFcn',fun,'WindowButtonUpFcn',fun2)
        fun([],[]);

    case 'alt'      %right click
        fun = @(src,evnt) ButtonMotionFunction(src,evnt,brush,'Right Click',[]);
        fun2=@(src,evnt) buttonUpFunction(src,evnt,WBMF_old,WBUF_old,brush);
        set(brush.handles.fig,'WindowButtonMotionFcn',fun,'WindowButtonUpFcn',fun2)
        fun([],[]);
    case 'extend'   %center click
        data.bp=get(0,'PointerLocation');
        data.r = brush.position(3);
        fun = @(src,evnt) ButtonMotionFunction(src,evnt,brush,'Middle Click',data);
        fun2=@(src,evnt) buttonUpFunction(src,evnt,WBMF_old,WBUF_old,brush);
        set(brush.handles.fig,'WindowButtonMotionFcn',fun,'WindowButtonUpFcn',fun2)
        fun([],[]);
end

end

function ButtonMotionFunction(src,evnt,brush,tag,data)

switch tag
    case 'No Click'
        if ~isvalid(brush), return; end
        if isempty(brush.position), return; end
        brush.oldWBMF(src,evnt)

        cp = get(brush.handles.parent,'CurrentPoint'); cp=[cp(1,1) cp(1,2)];
        brush.position = [cp(1) cp(2) brush.position(3)];

        %Check if the cursor is within the axis
        if isInAxis(brush)
             set(brush.handles.fig,'Pointer','custom','PointerShapeCData',nan(16))
        else
            set(brush.handles.fig,'Pointer',brush.oldPTR.ptr,'PointerShapeCData',brush.oldPTR.CData)

        end

    case 'Left Click'
        %moves the circle
        cp = get(brush.handles.parent,'CurrentPoint'); cp=[cp(1,1) cp(1,2)];
        brush.position = [cp(1) cp(2) brush.position(3)];

        %get the mask for the new brush position
        mask = getBrushMask(brush);

        %get the current mask of the imtool3D object
        maskOld = getCurrentMaskSlice(brush.handles.tool);

        %Combine the two masks
        mask = mask | maskOld;

        %Update the mask of the tool
        setCurrentMaskSlice(brush.handles.tool,mask)

    case 'Right Click'
        %moves the circle
        cp = get(brush.handles.parent,'CurrentPoint'); cp=[cp(1,1) cp(1,2)];
        brush.position = [cp(1) cp(2) brush.position(3)];

        %get the mask for the new brush position
        mask = getBrushMask(brush);

        %get the current mask of the imtool3D object
        maskOld = getCurrentMaskSlice(brush.handles.tool);

        %Combine the two masks
        mask = maskOld   &   ~(mask & maskOld);

        %Update the mask of the tool
        setCurrentMaskSlice(brush.handles.tool,mask)

    case 'Middle Click'
        %get the current mouse position
        cp = get(0,'PointerLocation');

        %get the difference in the y direction
        d = .25*(data.bp(2)-cp(2));

        rnew = data.r+d;
        if rnew<1
            rnew=1;
        end

        brush.position(3)=rnew;
        brush.handles.tool.brushsize = rnew;

end

end


function anat = nifti2mrVistaAnat(ni)
% Take a nifti and re-orient to mrVista anatomy convention
%
%   anat = nifti2mrVistaAnat(ni)
%
%   ni: can be a matrix, a nifti struct, or a path to a nifti file.
%
% Our preferred NIFTI format is [sagittal(L:R), coronal(P:A), axial(I:S)] format.
% mrLoadRet coords are in [axial(S:I), coronal(A:P), sagittal(L:R)] format.
% This function permutes our preferred NIFTI format into our mrLoadRet format.
%
% April, 2009: JW

% Check format of input argument (Ideally, we shoudl require NIFTI and not
% allow a data array with no header. But we don't want to break things.)
if isnumeric(ni) || islogical(ni), data = ni; end
if ischar(ni), ni = niftiRead(ni); end

% Reorient to RAS
if isstruct(ni),
    ni = niftiApplyCannonicalXform(ni);
    data = niftiGet(ni, 'data');
end

% Permute
anat = permute(data, [3 2 1]);

% then flip dims 1 and 2
anat = flip(flip(anat, 1),2);

return


function ipFuncCoords = vol2ipXformCoords(gray, inplane, preserveExactValues)
% Return coords from INPLANE functional data that correspond to coords in
% mrVista Gray view
%
%  ipFuncCoords = vol2ipXformCoords(gray, inplane, preserveExactValues)
%
% We first get a 3xn matrix of gray view coordinates, then find the
% corresponding inplane anatomical coordinates, and finally find the
% corresponding inplane functional coordinates. We use this transform when
% we want to convert functional data (e.g., a parameter map, coranal, or
% time series) from the inplane view to the gray view.
%
% INPUTS
%   gray: mrVista view structure (must be a gray view)
%   inplane: mrVista view structure (must be an inplane view)
%   preserveExactValues: boolean. If false, return integer coordinates. If
%                   true, return the calculated (non-integer values). If
%                   non-integer values are returned, then the parent
%                   function will have to deal with these, e.g., via
%                   interpolation.
% OUTPUTS
%   ipFuncCoords: 3xn matrix of coordinates in inplane functional space
%                   corresponding to 3xn matrix of gray view coords
%
% Example:
%   ipFuncCoords = vol2ipXformCoords(gray, inplane)
%
% This code was duplicated in many functions, including ip2volTSeries,
% ip2volParMap, and ip2VolCorAnal. It has now been cropped out of those
% functions and placed in a single routine. This is that routine.
%
% JW 7/2012

% check inputs
if ~exist('preserveExactValues', 'var'), preserveExactValues = false; end

% we need mrSESSION for the alignment matrix
mrGlobals;

% The gray coords are the integer-valued (y,x,z) volume
% coordinates that correspond to the inplanes.  Convert to
% homogeneous form by adding a row of ones.
coords  = viewGet(gray, 'coords');
nVoxels = size(coords, 2);
coords  = double([coords; ones(1,nVoxels)]);

% vol2InplaneXform is the 4x4 homogeneous transform matrix that
% takes volume (y',x',z',1) coordinates into inplane (y,x,z,1)
% coordinates.
vol2InplaneXform = inv(sessionGet(mrSESSION,'alignment'));

% We don't care about the last coordinate in (y,x,z,1), so we
% toss the fourth row of Xform.  Then our outputs will be (y,x,z).
%
vol2InplaneXform = vol2InplaneXform(1:3,:);

% Transform coord positions to the inplanes.  Hence, ipAnatomicalCoords
% contains the inplane position of each of the gray matter voxels.  These
% will generally not fall on integer-valued coordinates, rather they will
% fall between voxels.  Other functions that rely on the output of this
% function will require interpolation to get the data at these
% between-voxel positions.
%
ipAnatomicalCoords = vol2InplaneXform*coords;

% Convert coords from inplane anatomical space to inplane functional space.
% We do this because the anatomical inplane is often higher resolution than
% the functional data.  We preserve the number of coords so that the number
% of output functional voxels is identical to the number of gray or volume
% voxels. If requested, we preserve the exact (non-integer) values, which
% means that the functional coordinates will lie in locations between the
% actual functional data points.
preserveCoords = true;
ipFuncCoords   = ip2functionalCoords(inplane, ipAnatomicalCoords, ...
    [], preserveCoords, preserveExactValues);

% Some confusion about zeros in the output coordinates. It seems best to
% leave the calculations as they are unless there is a problem that someone
% understands. See below.

% HH, 6/16/2012: If we use the code below, we elimintate some voxels
% and then nVoxels is different from the size of ipCoords, leading to a
% mismatch in the size of the expected time series (tSeries) and the
% size of interpolated tSeries, causing an error in  the line,
%  tSeries(frame,:) = interp3(subData, ...
%                                   ipFuncCoords(2,:), ...
%                                   ipFuncCoords(1,:), ...
%                                   ipFuncCoords(3,:), ...
%                                   method);
%
% Hence we comment out the lines below. Leaving in the values with 0
% did not produce an error, at least for the function we tested it on,
% ip2volTSeries.
%
% % ras 12/20/04:
% % occasionally the xformed grayCoords will include a 0
% % coordinate. While it seems this should not happen,
% % I'm applying this band-aid for the time being:
% [badRows badCols] = find(ipFuncCoords==0); %#ok<ASGLU>
% goodCols = setdiff(1:nVoxels, badCols);
% ipFuncCoords = ipFuncCoords(:,goodCols);
% if length(badCols)>1
%     fprintf('%i voxels mapped to slice 0...\n',length(badCols));
% end

return