% [INPUT]
% ds = A structure representing the dataset.
% sn = A string representing the serial number of the result file.
% temp = A string representing the full path to the Excel spreadsheet used as template for the result file.
% out = A string representing the full path to the Excel spreadsheet to which the results are written, eventually replacing the previous ones.
% cvm = A string representing the method for calculating the critical values (optional, default='WB'):
%   - 'FS' for finite sample critical values;
%   - 'WB' for wild bootstrap.
% cvq = A float [0.90,0.99] representing the quantile of the critical values (optional, default=0.95).
% lag_max = An integer [0,10] representing the maximum lag order to be evaluated for the Augmented Dickey-Fuller test (optional, default=0).
% lag_sel = A string representing the lag order selection criteria for the Augmented Dickey-Fuller test (optional, default='FIX'):
%   - 'AIC' for Akaike's Information Criterion;
%   - 'BIC' for Bayesian Information Criterion;
%   - 'FIX' to use a fixed lag order;
%   - 'FPE' for Final Prediction Error;
%   - 'HQIC' for Hannan-Quinn Information Criterion.
% mbd = An integer [3,Inf) representing the minimum duration of a bubble in days (optional, default=NaN).
%   If NaN is provided, then an optimal value based on the number of observations is used.
% analyze = A boolean that indicates whether to analyse the results and display plots (optional, default=false).
%
% [OUTPUT]
% result = A structure representing the original dataset inclusive of intermediate and final calculations.
% stopped = A boolean that indicates whether the process has been stopped through user input.

function [result,stopped] = run_bubbles_detection(varargin)

    persistent ip;

    if (isempty(ip))
        ip = inputParser();
        ip.addRequired('ds',@(x)validateattributes(x,{'struct'},{'nonempty'}));
        ip.addRequired('sn',@(x)validateattributes(x,{'char'},{'nonempty' 'size' [1 NaN]}));
        ip.addRequired('temp',@(x)validateattributes(x,{'char'},{'nonempty' 'size' [1 NaN]}));
        ip.addRequired('out',@(x)validateattributes(x,{'char'},{'nonempty' 'size' [1 NaN]}));
        ip.addOptional('cvm','WB',@(x)any(validatestring(x,{'FS' 'WB'})));
        ip.addOptional('cvq',0.95,@(x)validateattributes(x,{'double'},{'real' 'finite' '>=' 0.90 '<=' 0.99 'scalar'}));
        ip.addOptional('lag_max',0,@(x)validateattributes(x,{'double'},{'real' 'finite' 'integer' '>=' 0 '<=' 10 'scalar'}));
        ip.addOptional('lag_sel','FIX',@(x)any(validatestring(x,{'AIC' 'BIC' 'FIX' 'FPE' 'HQIC'})));
        ip.addOptional('mbd',NaN,@(x)validateattributes(x,{'double'},{'real' 'scalar'}));
        ip.addOptional('analyze',false,@(x)validateattributes(x,{'logical'},{'scalar'}));
    end

    ip.parse(varargin{:});

    ipr = ip.Results;
    ds = validate_dataset(ipr.ds,'BubblesDetection');
    sn = ipr.sn;
    temp = validate_template(ipr.temp);
    out = validate_output(ipr.out);
    cvm = ipr.cvm;
    cvq = ipr.cvq;
    lag_max = ipr.lag_max;
    lag_sel = ipr.lag_sel;
    mbd = validate_mbd(ipr.mbd,ds.T);
    analyze = ipr.analyze;

    nargoutchk(1,2);

    [result,stopped] = run_bubbles_detection_internal(ds,sn,temp,out,cvm,cvq,lag_max,lag_sel,mbd,analyze);

end

function [result,stopped] = run_bubbles_detection_internal(ds,sn,temp,out,cvm,cvq,lag_max,lag_sel,mbd,analyze)

    result = [];
    stopped = false;
    e = [];

    ds = initialize(ds,sn,cvm,cvq,lag_max,lag_sel,mbd);
    n = ds.N;
    t = ds.T;

    bar = waitbar(0,'Initializing bubbles detection measures...','CreateCancelBtn',@(src,event)setappdata(gcbf(),'Stop', true));
    setappdata(bar,'Stop',false);
    cleanup = onCleanup(@()delete(bar));

    pause(1);
    waitbar(0,bar,'Calculating bubbles detection measures...');
    pause(1);

    try

        p = ds.Prices;

        for i = 1:n
            waitbar((i - 1) / n,bar,['Calculating bubbles detection measures for ' ds.FirmNames{i} '...']);

            if (getappdata(bar,'Stop'))
                stopped = true;
                break;
            end

            offset = min(ds.Defaults(i) - 1,t);
            p_i = p(1:offset,i);

            [bsadfs,cvs,detection,breakdown] = psy_bubbles_detection(p_i,ds.CVM,ds.CVQ,ds.LagMax,ds.LagSel,ds.MBD);
            ds.BSADFS(1:offset,i) = bsadfs;
            ds.CVS(1:offset,i) = cvs;
            ds.BUB(1:offset,i) = detection(:,1);
            ds.BMPH(1:offset,i) = detection(:,2);
            ds.BRPH(1:offset,i) = detection(:,3);
            ds.Breakdowns{i} = breakdown;

            if (getappdata(bar,'Stop'))
                stopped = true;
                break;
            end

            waitbar(i / n,bar);
        end

    catch e
    end

    if (~isempty(e))
        delete(bar);
        rethrow(e);
    end

    if (stopped)
        delete(bar);
        return;
    end

    pause(1);
    waitbar(1,bar,'Finalizing cross-sectional measures...');
    pause(1);

    try
        ds = finalize(ds);
    catch e
        delete(bar);
        rethrow(e);
    end

    pause(1);
    waitbar(1,bar,'Writing bubbles detection measures...');
    pause(1);

    try
        write_results(ds,temp,out);
        delete(bar);
    catch e
        delete(bar);
        rethrow(e);
    end

    if (analyze)
        analyze_result(ds);
    end

    result = ds;

end

%% PROCESS

function ds = initialize(ds,sn,cvm,cvq,lag_max,lag_sel,mbd)

    n = ds.N;
    t = ds.T;

    ds.Result = 'BubblesDetection';
    ds.ResultDate = now(); %#ok<TNOW1>
    ds.ResultAnalysis = @(ds)analyze_result(ds);
    ds.ResultSerial = sn;

    ds.CVM = cvm;
    ds.CVQ = cvq;
    ds.LagMax = lag_max;
    ds.LagSel = lag_sel;
    ds.MBD = mbd;

    if (strcmp(ds.LagSel,'FIX'))
        label = [' (CVM= ' ds.CVM ', CVQ=' num2str(ds.CVQ * 100) '%, L=' num2str(ds.LagMax) ')'];
    else
        label = [' (CVM= ' ds.CVM ', CVQ=' num2str(ds.CVQ * 100) '%, LM=' num2str(ds.LagMax) ', LS=' ds.LagSel ')'];
    end

    ds.LabelsMeasuresSimple = {'BUB' 'BMPH' 'BRPH' 'Breakdowns'};
    ds.LabelsMeasures = [strcat(ds.LabelsMeasuresSimple(1:3),{label}) ds.LabelsMeasuresSimple(4)];

    ds.LabelsIndicatorsSimple = {'BC' 'BCP'};
    ds.LabelsIndicators = {['BC' label] ['BCP' label]};

    ds.LabelsSheetsSimple = [ds.LabelsMeasuresSimple {'Indicators'}];
    ds.LabelsSheets = [ds.LabelsMeasures {'Indicators'}];

    ds.BSADFS = NaN(t,n);
    ds.CVS = NaN(t,n);
    ds.BUB = NaN(t,n);
    ds.BMPH = NaN(t,n);
    ds.BRPH = NaN(t,n);
    ds.Breakdowns = cell(1,n);

    ds.Indicators = NaN(t,numel(ds.LabelsIndicators));

    ds.ComparisonReferences = {'Indicators' 1 strcat({'BD-'},ds.LabelsIndicatorsSimple{1})};

end

function ds = finalize(ds)

    bc = sum(ds.BUB .* ds.Capitalizations,2,'omitnan');
    bcp = bc ./ sum(ds.Capitalizations,2,'omitnan');

    ds.Indicators = [bc bcp];

end

function write_results(ds,temp,out)

    [out_path,~,~] = fileparts(out);

    try
        if (exist(out_path,'dir') ~= 7)
            mkdir(out_path);
        end

        if (exist(out,'file') == 2)
            delete(out);
        end
    catch
        error('A system I/O error occurred while writing the results.');
    end

    copy_result = copyfile(temp,out,'f');

    if (copy_result == 0)
        error('The output file could not be created from the template file.');
    end

    lc = numel(ds.LabelsSheetsSimple);

    dates_str = cell2table(ds.DatesStr,'VariableNames',{'Date'});

    for i = 1:(lc - 2)
        sheet = ds.LabelsSheetsSimple{i};
        measure = strrep(sheet,' ','');

        tab = [dates_str array2table(ds.(measure),'VariableNames',ds.FirmNames)];
        writetable(tab,out,'FileType','spreadsheet','Sheet',sheet,'WriteRowNames',true);
    end

    breakdowns_count = cellfun(@(x)size(x,1),ds.Breakdowns);
    breakdowns_firms = arrayfun(@(x)repelem(ds.FirmNames(x),breakdowns_count(x),1),1:ds.N,'UniformOutput',false);
    breakdowns_firms = vertcat(breakdowns_firms{:});
    breakdowns_firms = cell2table(breakdowns_firms,'VariableNames',{'Firm'});

    tab = [breakdowns_firms array2table(cell2mat(ds.Breakdowns.'),'VariableNames',{'Start' 'Peak' 'End' 'Duration', 'Boom Phase' 'Burst Phase'})];
    writetable(tab,out,'FileType','spreadsheet','Sheet',ds.LabelsSheetsSimple{lc - 1},'WriteRowNames',true);

    tab = [dates_str array2table(ds.Indicators,'VariableNames',ds.LabelsIndicatorsSimple)];
    writetable(tab,out,'FileType','spreadsheet','Sheet',ds.LabelsSheetsSimple{lc},'WriteRowNames',true);

    worksheets_batch(out,ds.LabelsSheetsSimple,ds.LabelsSheets);

end

%% PLOTTING

function analyze_result(ds)

    safe_plot(@(id)plot_sequence(ds,id));
    safe_plot(@(id)plot_indicators(ds,id));

end

function plot_indicators(ds,id)

    bc = ds.Indicators(:,1);
    bcp = ds.Indicators(:,2);

    y_limits_bc = plot_limits(bc,0.1,0);
    y_limits_bcp = [0 100];

    f = figure('Name','Bubbles Detection Measures > Indicators','Units','normalized','Position',[100 100 0.85 0.85],'Tag',id);

    sub_1 = subplot(2,1,1);
    plot(sub_1,ds.DatesNum,smooth_data(bc),'Color',[0.000 0.447 0.741]);
    set(sub_1,'YLim',y_limits_bc);
    t1 = title(sub_1,ds.LabelsIndicators{1});
    set(t1,'Units','normalized');
    t1_position = get(t1,'Position');
    set(t1,'Position',[0.4783 t1_position(2) t1_position(3)]);

    sub_2 = subplot(2,1,2);
    area(sub_2,ds.DatesNum,smooth_data(bcp),'EdgeColor',[0.000 0.447 0.741],'FaceAlpha',0.5,'FaceColor',[0.749 0.862 0.933]);
    set(sub_2,'YLim',y_limits_bcp);
    t2 = title(sub_2,ds.LabelsIndicators{2});
    set(t2,'Units','normalized');
    t2_position = get(t2,'Position');
    set(t2,'Position',[0.4783 t2_position(2) t2_position(3)]);

    set([sub_1 sub_2],'XLim',[ds.DatesNum(1) ds.DatesNum(end)],'XTickLabelRotation',45);
    set([sub_1 sub_2],'XGrid','on','YGrid','on');

    if (ds.MonthlyTicks)
        date_ticks([sub_1 sub_2],'x','mm/yyyy','KeepLimits','KeepTicks');
    else
        date_ticks([sub_1 sub_2],'x','yyyy','KeepLimits');
    end

    figure_title(f,'Indicators');

    maximize_figure(f);

end

function plot_sequence(ds,id)

    n = ds.N;
    t = ds.T;
    dn = ds.DatesNum;
    mt = ds.MonthlyTicks;

    bmph = ds.BMPH;
    brph = ds.BRPH;

    data_bsadfs = ds.BSADFS;
    data_cvs = ds.CVS;
    data_ps = smooth_data(ds.Prices);
    data_ps_bm = data_ps .* bmph;
    data_ps_br = data_ps .* brph;
    data_ps_ot = NaN(t,n);

    data_bds = cell(1,n);

    for i = 1:n
        offset = min(ds.Defaults(i) - 1,t);

        bsadfs_i = data_bsadfs(1:offset,i);
        idx = find(bsadfs_i ~= 0,1,'first');
        data_bsadfs(1:idx,i) = bsadfs_i(idx + 1);
        data_bsadfs(1:offset,i) = smooth_data(data_bsadfs(1:offset,i));

        cvs_i = data_cvs(1:offset,i);
        idx = find(isnan(cvs_i),1,'last');
        data_cvs(1:idx,i) = cvs_i(idx + 1);
        data_cvs(1:offset,i) = smooth_data(data_cvs(1:offset,i));

        data_ps_ot(1:offset,i) = data_ps(1:offset,i) .* ~(bmph(1:offset,i) | bmph(1:offset,i));

        bd_i = ds.Breakdowns{i};

        bm_count = sum(bd_i(:,5));
        br_count = sum(bd_i(:,6));
        ot_count = t - (bm_count + br_count);
        data_bds{i} = [ot_count bm_count br_count];
    end

    data_ones = ones(1,n);
    data = [repmat({dn},1,n); mat2cell(data_bsadfs,t,data_ones); mat2cell(data_cvs,t,data_ones); mat2cell(data_ps,t,data_ones); mat2cell(data_ps_bm,t,data_ones); mat2cell(data_ps_br,t,data_ones); mat2cell(data_ps_ot,t,data_ones); data_bds];

    plots_title = [repmat({'Bubbles'},1,n); repmat({'Model'},1,n); repmat({'Breakdown - Percentage'},1,n); repmat({'Breakdown - Count'},1,n)];

    x_limits = [dn(1) dn(end)];

    core = struct();

    core.N = n;
    core.Data = data;
    core.Function = @(subs,data)plot_function(subs,data);

    core.OuterTitle = 'Bubbles Detection Measures > Time Series';
    core.InnerTitle = 'Time Series';
    core.SequenceTitles = ds.FirmNames;

    core.PlotsAllocation = [7 4];
    core.PlotsSpan = {[1:3 5:7 9:11 13:15] [21:23 25:27] [4 8 12] [20 24 28]};
    core.PlotsTitle = plots_title;

    core.XDates = {mt mt [] []};
    core.XGrid = {true true false false};
    core.XLabel = {[] [] [] []};
    core.XLimits = {x_limits x_limits [] []};
    core.XRotation = {45 45 [] []};
    core.XTick = {[] [] [] []};
    core.XTickLabels = {[] [] [] []};

    core.YGrid = {true true false true};
    core.YLabel = {[] [] [] []};
    core.YLimits = {[] [] [] []};
    core.YRotation = {[] [] [] []};
    core.YTick = {[] [] [] []};
    core.YTickLabels = {[] [] [] []};

    sequential_plot(core,id);

    function plot_function(subs,data)

        x = data{1};
        bsadfs = data{2};
        cvs = data{3};
        ps = data{4};
        ps_bm = data{5};
        ps_br = data{6};
        ps_ot = data{7};
        bd = data{8};

        d = find(isnan(ps),1,'first');

        if (isempty(d))
            xd = [];
        else
            xd = x(d) - 1;
        end

        sub_1 = subs(1);
        a1 = area(sub_1,x,ps_ot,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[0.749 0.862 0.933]);
        hold(sub_1,'on');
            a2 = area(sub_1,x,ps_bm,'EdgeColor','none','FaceColor',[0.200 0.627, 0.173]);
            a3 = area(sub_1,x,ps_br,'EdgeColor','none','FaceColor',[0.984 0.502 0.447]);
            plot(sub_1,x,ps,'Color',[0.000 0.000 0.000])
        hold(sub_1,'off');

        if (~isempty(xd))
            hold(sub_1,'on');
                plot(sub_1,[xd xd],get(sub_1,'YLim'),'Color',[1.000 0.400 0.400]);
            hold(sub_1,'off');
        end

        l = legend(sub_1,[a1 a2 a3],'None','Boom Phase','Burst Phase','Location','south','Orientation','horizontal');
        set(l,'Units','normalized');
        l_position = get(l,'Position');
        set(l,'Position',[l_position(1) 0.3645 l_position(3) l_position(4)]);

        sub_2 = subs(2);
        p1 = plot(sub_2,x,bsadfs,'Color',[0.000 0.447 0.741]);
        hold(sub_2,'on');
            p2 = plot(sub_2,x,cvs,'Color',[0.000 0.000 0.000],'LineStyle','--');
        hold(sub_2,'off');

        if (~isempty(xd))
            hold(sub_2,'on');
                plot(sub_2,[xd xd],get(sub_2,'YLim'),'Color',[1.000 0.400 0.400]);
            hold(sub_2,'off');
        end

        legend(sub_2,[p1 p2],'BSADF','Critical Values','Location','northwest');

        sub_3 = subs(3);
        pc1 = pie(sub_3,bd);
        hpc1 = findobj(pc1,'Type','patch');
        set(hpc1(1),'FaceAlpha',0.5,'FaceColor',[0.749 0.862 0.933]);
        set(hpc1(2),'FaceColor',[0.200 0.627, 0.173]);
        set(hpc1(3),'FaceColor',[0.984 0.502 0.447]);

        sub_4 = subs(4);
        b1 = bar(sub_4,1,bd(1));
        set(b1,'FaceAlpha',0.5,'FaceColor',[0.749 0.862 0.933]);
        hold(sub_4,'on');
            b2 = bar(sub_4,2,bd(2));
            set(b2,'FaceColor',[0.200 0.627, 0.173]);
            b3 = bar(sub_4,3,bd(3));
            set(b3,'FaceColor',[0.984 0.502 0.447]);
        hold(sub_4,'off');

    end

end

%% VALIDATION

function mbd = validate_mbd(mbd,t)

    if (~isnan(mbd))
        if (~isfinite(mbd))
            error('The value of ''mbd'' is invalid. Expected input to be finite.');
        end

        if (floor(mbd) ~= mbd)
            error('The value of ''mbd'' is invalid. Expected input to be an integer.');
        end

        b = ceil(0.2 * t);

        if ((mbd < 3) || (mbd > b))
            error(['The value of ''mbd'' is invalid. Expected input to have a value >= 5 and <= ' num2str(b) '.']);
        end
    end

end

function out = validate_output(out)

    [path,name,extension] = fileparts(out);

    if (~strcmpi(extension,'.xlsx'))
        out = fullfile(path,[name extension '.xlsx']);
    end

end

function temp = validate_template(temp)

    sheets = {'BUB' 'BMPH' 'BRPH' 'Breakdowns' 'Indicators'};
    file_sheets = validate_xls(temp,'T');

    if (~all(ismember(sheets,file_sheets)))
        error(['The template must contain the following sheets: ' sheets{1} sprintf(', %s',sheets{2:end}) '.']);
    end

    worksheets_batch(temp,sheets);

end


%LUT  Performs a look-up table transform of an array
%
%     dst = cv.LUT(src, lut)
%
% ## Input
% * __src__ input array of 8-bit elements (`uint8` or `int8`).
% * __lut__ look-up table of 256 elements; in case of multi-channel input
%   array `src`, the table should either have a single channel (in this case
%   the same table is used for all channels) or the same number of channels as
%   in the input array.
%
% ## Output
% * __dst__ output array of the same size and number of channels as `src`, and
%   the same depth as `lut`.
%
% The function cv.LUT fills the output array with values from the look-up
% table. Indices of the entries are taken from the input array. That is, the
% function processes each element of src as follows:
%
%     dst(I) = lut(src(I) + d)
%
% where:
%
%     d = { 0   if src has uint8 depth
%         { 128 if src has  int8 depth
%
% See also: cv.convertScaleAbs, cv.convertTo, cv.applyColorMap, intlut
%


function scl = scale( disc, uFun )
% SCALE   Estimate the vertical scale from a vector of values.
%
%   SCL = SCALE( DISC, UFUN ) returns an estimate for the vertical scale
%   of UFUN. VALSDISCRETIZATION expects UFUN to be a cell array of sample data.

scl = max( cellfun(@(v) max(abs(v)), uFun) );

end


function readJV(file)
[nv,nf]=nnu(file);
fprintf('number of point:%d\n',nv);
fprintf('number of face:%d\n',nf);
fid=fopen(file);
fid2=fopen('point.off','w');
while 1
    tline = fgetl(fid);
    if ~ischar(tline),   break,   end
    %disp(tline)
    n=length(tline);
    if n > 0
        header=findstr(tline,'#JV');
        J=isempty(header);
        if J==1
        disp(tline)
        fprintf(fid2,'%s \n',tline);
        end
    end
end
fclose(fid);
fclose(fid2);
function [nv,nf]=nnu(file)
fid = fopen(file);
C=0;
while 1
    tline = fgetl(fid);
    C=C+1;
    if ~ischar(tline),   break,   end
    if C==3
        CC = textscan(tline, '%f %f %f');
        break;
    end
    %disp(tline)
end
fclose(fid);
nv=CC{1,1};
nf=CC{1,2};


function idx = getDealiasingIndexes(~, N, nVars)
%GETGDEALIASINGINDEXES  % Returns indexes for dealiasing procedure (2/3-rule).
%
% See also SPINOPSPHERE.

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

toOne = floor(N/2) + 1 - ceil(N/6):floor(N/2) + ceil(N/6);
idx = false(N, N);
idx(toOne, toOne) = 1;
idx = repmat(idx, nVars, 1);

end


function varargout = prtUtilSubplotTitle(varargin)
%   prtUtilSubplotTitle add titles to subplots
%
%   prtUtilSubplotTitle(STRING) makes string STRING the title*(see note) across all
%   available sub-plots in the current figure.
%
%   prtUtilSubplotTitle(AXESLIST,STRING) place the title STRING over only the
%   axes specified in AXESLIST (a list of axes handles as generated by
%   subplot or equivalent).
%
%   For example:
%
%       clear all; close all;
%       a1 = subplot(3,3,1); plot(1:10);
%       a1_2 = subplot(3,3,2); plot(sin(linspace(0,2*pi)*5));
%       a1_3 = subplot(3,3,3); plot(cos(linspace(0,2*pi)*5));
%       a2 = subplot(3,3,[4,7]); h = surf(peaks); set(h,'EdgeAlpha',0);
%       a3 = subplot(3,3,[5,8]); h = surf(-peaks); set(h,'EdgeAlpha',0);
%       a4 = subplot(3,3,[6,9]); mesh(randn(10));
%
%       th1 = subplot_title(a1,'Plot of 1-10');
%       th2 = subplot_title([a1_2,a1_3],'Plot of Sinusoids');
%       th3 = subplot_title([a2 a3],'SURF Pics');
%       th4 = subplot_title([a4],'Mesh');
%
%   *Note that subplot_title creates invisible axes to make these new
%   titles, the handles to which are lost after subplot_title exits.  As a
%   result, multiple calls to subplot_title in a row over the same set of
%   axes will result in multiple overlaying titles.  This is undesirable.
%   To mediate these effects, use title_handle to erase current titles
%   prior to calling subplot_title multiple times.

% Originally written as subplot_title, part of FROI:
%   This function is part of froi, available from http://froi.sourceforge.net,
%   and is governed under the terms of the Artistic License.

%Mod History:
ax = gca;
cfig = gcf;

if nargin == 1
    title_string = varargin{1};
    relevantAxes = findobj(gcf, 'Type', 'axes', 'Box', 'on');
elseif nargin == 2
    relevantAxes = varargin{1};
    title_string = varargin{2};
elseif nargin > 2
    if ischar(varargin{1}) || iscell(varargin{1})
        title_string = varargin{1};
        relevantAxes = findobj(gcf, 'Type', 'axes', 'Box', 'on');
    else
        relevantAxes = varargin{1};
        title_string = varargin{2};
    end
end

if isempty(relevantAxes);
    error('No current axes available for titling');
end

for i = 1:length(relevantAxes);
    P(i,:) = get(relevantAxes(i),'Position');
end

minX = min(P(:,1));
maxX = max(P(:,3) + P(:,1));
minY = min(P(:,2));
maxY = max(P(:,4) + P(:,2));

axes('position',[minX minY maxX-minX maxY-minY],'Box','off','Visible','off');

if nargin > 2
    if ~any(ishandle(varargin{1}))
        title_handle = title(title_string,varargin{2:end});
    else
        title_handle = title(title_string,varargin{3:end});
    end
else
    title_handle = title(title_string);
end

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

children = get(gcf,'Children');
set(gcf,'Children',[children(2:end); children(1)])

figure(cfig);

if nargout>0
    varargout{1} = title_handle;
end


% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
classdef Rz < ETS2

    methods
        function obj = Rz(varargin)
            obj@ETS2('Rz', varargin{:});
        end
    end
end


function mr = mrReadOldParamMap(pth);
%
%  mr = mrReadOldParamMap(pth);
%
% Reads in a mrVista 1.0 Parameter map file
% as a mrVista 2.0 mr object. Tries to extract as
% much information as possible from the mrSESSION
% file, returning the rest in the mr.hdr field.
%
% For now, this only works on Original, Inplane TSeries (or
% TSeries files whose params aren't significantly
% changed from the Original tSeries). The tSeries files
% must be in a directory named 'Scan[#]'.
%
% ras, 07/08/05.
% ras, 03/01/07: reads in data units for newer param maps.

[p f ext] = fileparts(pth);

% init mr struct
mr = mrCreateEmpty;
mr.path = pth;
mr.format = '1.0map';
mr.dimUnits = {'mm' 'mm' 'mm' 'scan'};

% read in header info from mrSESSION:
% if we can't do this, we can't read the data
mrSessPath = fullfile(p,'..','..','mrSESSION.mat');
if exist(mrSessPath,'file')
    load(mrSessPath,'mrSESSION','dataTYPES');
else
    % dialog to get file
    error('No mrSESSION file found!')
end

% load the param map file
M = load(pth);
if ~isfield(M, 'map') | ~isfield(M, 'mapName')
	error( sprintf('%s needs ''map'' and ''mapName'' variables.', pth) );
end

mr.name = M.mapName;
map = M.map;  M.map =[]; % quick hack for back-compatibility

% check for an empty map
if isempty(cellfind(map))
    myErrorDlg('Map File is empty!');
end

% since most contrast maps are named w/ the format
% '[active]V[control]', and no other common param
% map has a V in it, make an educated guess about
% units:
if isfield(M, 'units'),				mr.dataUnits = M.units;
elseif findstr(M.mapName,'V'),		mr.dataUnits = '-log_{10}(p)';
else,								mr.dataUnits = M.mapName;
end

% assign each volume that is nonempty to a new time point:
for i = 1:length(map), ind(i) = ~isempty(map{i}); end
ind = find(ind);
for t = 1:length(ind)
    mr.data(:,:,:,t) = map{ind(t)};
	mr.info.scans(t) = ind(t);
end

% get other header info, using first assigned scan as index
% (first, we see if this map reflects data from the Original data type:
%  if so, we can use the scan index as an index into the functional
%  headers. Otherwise, we guess the first scan header is appropriate.)
[p2 f2] = fileparts(p);
if isequal(f2, 'Original')
	nScan = ind(1);
else
	nScan = 1; % guess the 1st scan
end
mr.hdr = mrSESSION.functionals(nScan);
mr.hdr.comments = sprintf('Computed for scans: %s',num2str(ind));
if (~isfield(mr.hdr,'voxelSize')) && (isfield(mr.hdr,'effectiveResolution'))
    mr.hdr.voxelSize=mr.hdr.effectiveResolution;
end

mr.voxelSize = [mr.hdr.voxelSize];
mr.dims = [mr.hdr.cropSize length(mr.hdr.slices)];
mr.extent = mr.dims .* mr.voxelSize;

if isfield(mrSESSION,'alignment')
    mr.spaces(1).name = 'I|P|R';
    mr.spaces(1).xform = mrSESSION.alignment;
    mr.spaces(1).dirLabels =  {'S <--> I' 'A <--> P' 'L <--> R'};
    mr.spaces(1).sliceLabels =  {'Axial' 'Coronal' 'Sagittal'};
    mr.spaces(1).units = 'mm';
    mr.spaces(1).coords = [];
    mr.spaces(1).indices = [];

    % account for differences between inplane / functional resolutions
    % for the alignment:
    % the mrVista 1.0 alignments mapped from inplane coords to volume
    % coords, rather than the map / tSeries:
    szRatio = mr.voxelSize ./ mrSESSION.inplanes.voxelSize;
    [trans rot scale] = affineDecompose(mr.spaces(1).xform);
    mr.spaces(1).xform = affineBuild(trans,rot,scale.*szRatio);

    mr.spaces(2).name = 'R|A|S';
    mr.spaces(2).xform = ipr2ras(mr.spaces(1).xform,mr.dims);
    mr.spaces(2).dirLabels =  {'L <--> R' 'P <--> A' 'I <--> S'};
    mr.spaces(2).sliceLabels =  {'Sagittal' 'Coronal' 'Axial'};
    mr.spaces(2).units = 'mm';
    mr.spaces(2).coords = [];
    mr.spaces(2).indices = [];
end

% pre-pend standard space definitions
mr.spaces = [mrStandardSpaces(mr) mr.spaces];

return


function payload_removed_zeros = removeZeros(payload)
    for j = 1:size(payload, 2)
        if ~any(all(payload(:, j), 2))
            payload = payload(:, 1:j-1);
            break;
        end
    end
    payload_removed_zeros = payload;
end


function idx = getDealiasingIndexes(~, N, nVars)
%GETGDEALIASINGINDEXES  % Returns indexes for dealiasing procedure (2/3-rule).
%
% See also SPINOP2.

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

toOne = floor(N/2) + 1 - ceil(N/6):floor(N/2) + ceil(N/6);
idx = false(N, N);
idx(toOne, toOne) = 1;
idx = repmat(idx, nVars, 1);

end


function test_issue2193

% WALLTIME 00:10:00
% MEM 3gb
% DEPENDENCY ft_apply_montage ft_prepare_montage

load(dccnpath('/home/common/matlab/fieldtrip/data/test/issue2193.mat'));
data = ft_preprocessing(cfg, data_segmented);


function val = lval(fun)
%LVAL  Obtain the value of a FUN at its left endpoint.
%   LVAL(F) returns the value of F at F.domain(1).

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

% Call LVAL() of the ONEFUN:
val = lval(fun.onefun);

end


function [] = plot_skeleton(pts, A, options)

if nargin<3
    options.sizep=400;
end
sizep = getoptions(options, 'sizep', 400);
sizee = getoptions(options, 'sizee', 2);
colorp = getoptions(options, 'colorp', [1, .8, .8]);
colore = getoptions(options, 'colore', [1, .0, .0]);

scatter3(pts(:,1),pts(:,2),pts(:,3),sizep,'.','MarkerEdgeColor', colorp);  hold on;
plot_connectivity(pts, A, sizee, colore);


function y = subsref( x, varargin )
y = cvxtuple( subsref( x.value_, varargin{:} ) );

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


classdef chebguiExporterIVP < chebguiExporter
%CHEBGUIEXPORTERIVP   Export an IVP from CHEBGUI.
%   This is a an concrete implementation of the class CHEBGUIEXPORTER, which
%   exports IVPs from CHEBGUI to .m-files, to the workspace, or to a .chebgui
%   file. It is not intended to be called directly by the end user.
%
% See also CHEBGUI, CHEBGUIEXPORTER.

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

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS PROPERTIES:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    properties

        % The default file name when exporting to an .m-file:
        defaultFileName = 'chebivp.m';

        % Description for printing to .m files:
        description = 'an initial-value problem';

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS CONSTRUCTOR:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function A = chebguiExporterIVP(varargin)
            % Do nothing!
        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = true )

        % Extract information from the CHEBGUI object to a struct
        expInfo = exportInfo(guifile)

        % Print problem description:
        printDescription(fid, expInfo)

        % Print options for solving the problem:
        printOptions(fid, expInfo)

        % Print lines for setting up the problem:
        printSetup(fid, expInfo, guifile)

        % Print the actual lines for calling the solver method:
        printSolver(fid, expInfo)

        % Print steps taken after the solver finishes:
        printPostSolver(fid, expInfo)

        function toWorkspaceSolutionOnly(handles)
        %TOWORKSPACESOLUTIONONLY   Export the solution to the workspace
        %
        % Note: this method exports fewer objects to the workspace than the
        % toWorkspace() method.

            % Obtain the variable names:
            varnames = handles.varnames;
            nv = numel(varnames);

            % Obtain the latest solution:
            sol = handles.latest.solution;

            % Export to the workspace!
            for k = 1:nv
                assignin('base', varnames{k}, sol(:,k));
                evalin('base', varnames{k});
            end
        end

        function toMat(handles)
        %TOMAT   Export from the CHEBGUI figure to a .mat-file.

            % Obtain the variable names involved in the problem.
            varnames = handles.varnames;
            for k = 1:numel(varnames);
                eval([varnames{k} ' = handles.latest.solution(:,k);']);
            end

            % Extract the norm of the updates, the CHEBOP and all options.
            N = handles.latest.chebop;  %#ok<NASGU>
            options = handles.latest.options;  %#ok<NASGU>

            % Show the user a figure for selecting where to save.
            uisave([varnames', 'N', 'options'], 'ivp');
        end

        function toWorkspace(handles)
        %TOWORKSPACE   Export from the CHEBGUI figure to the workspace.

            % Setup dialog for asking the user for variable names to be used.
            numlines = 1;
            options.Resize ='on';
            options.WindowStyle ='modal';

            % Need slightly different dialogs depending on whether we were
            % solving scalar problem or a coupled system.
            varnames = handles.varnames;
            nv = numel(varnames);
            if ( nv == 1 )
                prompt = {'Differential operator', 'Solution:', 'Options'};
            else
                prompt = ['Differential operator', varnames.', 'Options'];
            end

            name = 'Export to workspace';

            defaultAnswer = ['N', varnames', 'options'];

            % Show the user a dialog.
            answer = inputdlg(prompt, name, numlines, defaultAnswer, options);

            % Obtain the latest solution:
            sol = handles.latest.solution;

            % Export to the workspace!
            if ( ~isempty(answer) )
                assignin('base', answer{1}, handles.latest.chebop);
                for k = 1:nv
                    assignin('base', answer{k+1}, sol(:,k));
                end
                assignin('base', answer{nv+2}, handles.latest.options);
            end
        end

    end

end


function jed = epoch_to_jed_bahai ( )

%*****************************************************************************80
%
%% EPOCH_TO_JED_BAHAI returns the epoch of the Bahai calendar as a JED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real JED, the Julian Ephemeris Date of the epoch.
%
  jed = 2394646.5;

  return
end


function isBelow = isVersionBelow(versionA, versionB)
% Checks if versionA is smaller than versionB
    vA         = versionArray(versionA);
    vB         = versionArray(versionB);
    n          = min(length(vA), length(vB));
    deltaAB    = vA(1:n) - vB(1:n);
    difference = find(deltaAB, 1, 'first');
    if isempty(difference)
        isBelow = false; % equal versions
    else
        isBelow = (deltaAB(difference) < 0);
    end
end


classdef My_util_dagnn

properties

end

methods(Static)

% -------------------------------------------------------------------------
    function layers = simpleFindLayersOfType(net, type)
    % -------------------------------------------------------------------------
    layers = find(cellfun(@(x)strcmp(x.type, type), net.layers)) ;
    end

    % -------------------------------------------------------------------------
    function net = simpleRemoveLayersOfType(net, type)
    % -------------------------------------------------------------------------
    layers = simpleFindLayersOfType(net, type) ;
    net.layers(layers) = [] ;
    end

    % -------------------------------------------------------------------------
    function layers = dagFindLayersWithOutput(net, outVarName)
    % -------------------------------------------------------------------------
    layers = {} ;
    for l = 1:numel(net.layers)
      if any(strcmp(net.layers(l).outputs, outVarName))
        layers{1,end+1} = net.layers(l);
      end
    end

    end

    % -------------------------------------------------------------------------
    function layers = dagFindLayersOfType(net, type)
    % -------------------------------------------------------------------------
    layers = [] ;
    for l = 1:numel(net.layers)
      if isa(net.layers(l).block, type)
        layers{1,end+1} = net.layers(l).name ;
      end
    end

    end

    % -------------------------------------------------------------------------
    function dagRemoveLayersOfType(net, type)
    % -------------------------------------------------------------------------
    names = dagFindLayersOfType(net, type) ;
    for i = 1:numel(names)
      layer = net.layers(net.getLayerIndex(names{i})) ;
      net.removeLayer(names{i}) ;
      net.renameVar(layer.outputs{1}, layer.inputs{1}, 'quiet', true) ;
    end

    end

    % -------------------------------------------------------------------------
    function [layers, layer_idxes] = dagFindLayersWithInput(net, varName)
    % -------------------------------------------------------------------------
    layers = {} ;
    layer_idxes=[];
    for l = 1:numel(net.layers)
      if any(strcmp(net.layers(l).inputs, varName))
        layers{1,end+1} = net.layers(l) ;
        layer_idxes(1, end+1)=l;
      end
    end

    end

    function f = bilinear_u(k, numGroups, numClasses)
    %BILINEAR_U  Create bilinear interpolation filters
    %   BILINEAR_U(K, NUMGROUPS, NUMCLASSES) compute a square bilinear filter
    %   of size k for deconv layer of depth numClasses and number of groups
    %   numGroups

    factor = floor((k+1)/2) ;
    if rem(k,2)==1
      center = factor ;
    else
      center = factor + 0.5 ;
    end
    C = 1:k ;
    if numGroups ~= numClasses
      f = zeros(k,k,numGroups,numClasses) ;
    else
      f = zeros(k,k,1,numClasses) ;
    end

    for i =1:numClasses
      if numGroups ~= numClasses
        index = i ;
      else
        index = 1 ;
      end
      f(:,:,index,i) = (ones(1,k) - abs(C-center)./factor)'*(ones(1,k) - abs(C-center)./(factor));
    end
    end

end

end


% MLTOOLSTOOLBOXES Load in the relevant toolboxes for the MLTOOLS.

importLatest('datasets');
importLatest('optimi');
importLatest('ndlutil');
importLatest('netlab');
importLatest('mvu');
importLatest('lmvu');
importLatest('lle');
importLatest('jdqr');
importLatest('isomap');
importLatest('sedumi');


function makeGifAndJpg(fig_num)

    saveas(figure(4), 'postion','jpg');
    pause(0.1);
    saveas(figure(5), 'velocity','jpg');
    pause(0.1);
    filename = 'testAnimated6.gif';

    h = figure(fig_num);
    for i = 1:90
        view(4*i+15, 15);
        drawnow

        % Capture the plot as an image
        frame = getframe(h);
        im = frame2im(frame);
        [imind,cm] = rgb2ind(im,256);

        % Write to the GIF File
        if i == 1
          imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
        else
          imwrite(imind,cm,filename,'gif','WriteMode','append');
        end
    end

end


function [segmentation] = ft_datatype_segmentation(segmentation, varargin)

% FT_DATATYPE_SEGMENTATION describes the FieldTrip MATLAB structure for segmented
% voxel-based data and atlasses. A segmentation can either be indexed or probabilistic
% (see below).
%
% A segmentation is a volumetric description which is usually derived from an anatomical
% MRI, which describes for each voxel the tissue type. It for example distinguishes
% between white matter, grey matter, csf, skull and skin. It is mainly used for masking
% in visualization, construction of volume conduction models and for construction of
% cortical sheets. An volume-based atlas is basically a very detailed segmentation with
% an anatomical label for each voxel.
%
% For example, the AFNI TTatlas+tlrc segmented brain atlas (which can be created
% with FT_READ_ATLAS) looks like this
%
%              dim: [161 191 141]        the size of the 3D volume in voxels
%        transform: [4x4 double]         affine transformation matrix for mapping the voxel coordinates to head coordinate system
%         coordsys: 'tal'                the transformation matrix maps the voxels into this (head) coordinate system
%             unit: 'mm'                 the units in which the coordinate system is expressed
%           brick0: [161x191x141 uint8]  integer values from 1 to N, the value 0 means unknown
%           brick1: [161x191x141 uint8]  integer values from 1 to M, the value 0 means unknown
%      brick0label: {Nx1 cell}
%      brick1label: {Mx1 cell}
%
%
% An example segmentation with binary values that can be used for construction of a
% BEM volume conduction model of the head looks like this
%
%           dim: [256 256 256]         the dimensionality of the 3D volume
%     transform: [4x4 double]          affine transformation matrix for mapping the voxel coordinates to head coordinate system
%      coordsys: 'ctf'                 the transformation matrix maps the voxels into this (head) coordinate system
%          unit: 'mm'                  the units in which the coordinate system is expressed
%         brain: [256x256x256 logical] binary map representing the voxels which belong to the brain
%         scalp: [256x256x256 logical] binary map representing the voxels which belong to the scalp
%         skull: [256x256x256 logical] binary map representing the voxels which belong to the skull
%
% An example of a whole-brain anatomical MRI that was segmented using FT_VOLUMESEGMENT
% looks like this
%
%         dim: [256 256 256]         the size of the 3D volume in voxels
%   transform: [4x4 double]          affine transformation matrix for mapping the voxel coordinates to head coordinate system
%    coordsys: 'ctf'                 the transformation matrix maps the voxels into this (head) coordinate system
%        unit: 'mm'                  the units in which the coordinate system is expressed
%        gray: [256x256x256 double]  probabilistic map of the gray matter
%       white: [256x256x256 double]  probabilistic map of the white matter
%         csf: [256x256x256 double]  probabilistic map of the cerebrospinal fluid
%
% The examples above demonstrate that a segmentation can be indexed, i.e. consisting of
% subsequent integer numbers (1, 2, ...) or probabilistic, consisting of real numbers
% ranging from 0 to 1 that represent probabilities between 0% and 100%. An extreme case
% is one where the probability is either 0 or 1, in which case the probability can be
% represented as a binary or logical array.
%
% The only difference to the volume data representation is that the segmentation
% structure contains the additional fields xxx and xxxlabel. See FT_DATATYPE_VOLUME for
% further details.
%
% Required fields:
%   - dim, transform
%
% Optional fields:
%   - coordsys, unit
%
% Deprecated fields:
%   - none
%
% Obsoleted fields:
%   - none
%
% Revision history:
% (2012/latest) The explicit distunction between the indexed and probabilistic
% representation was made. For the indexed representation the additional
% xxxlabel cell-array was introduced.
%
% (2005) The initial version was defined.
%
% See also FT_DATATYPE, FT_DATATYPE_VOLUME, FT_DATATYPE_PARCELLATION

% Copyright (C) 2012, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip 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 FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% get the optional input arguments, which should be specified as key-value pairs
version           = ft_getopt(varargin, 'version', 'latest');
segmentationstyle = ft_getopt(varargin, 'segmentationstyle');  % can be indexed or probabilistic
hasbrain          = ft_getopt(varargin, 'hasbrain', 'no');     % no means that it is not required, if present it won't be removed

% convert from string into boolean
hasbrain = istrue(hasbrain);

if strcmp(version, 'latest')
  segversion = '2012';
  volversion = 'latest';
  clear version
else
  segversion = version;
  volversion = version;
  clear version
end

if isempty(segmentation)
  return;
end

switch segversion
  case '2012'
    % determine whether the style of the input fields is probabilistic or indexed
    fn = fieldnames(segmentation);
    %fn = setdiff(fn, 'inside'); % exclude the inside field from any conversions
    fn(strcmp(fn, 'inside')) = [];
    [indexed, probabilistic] = determine_segmentationstyle(segmentation, fn, segmentation.dim);

    % ignore the fields that do not contain a segmentation
    sel = indexed | probabilistic;
    fn            = fn(sel);
    indexed       = indexed(sel);
    probabilistic = probabilistic(sel);

    % convert from an exclusive to cumulative representation
    % this is only only for demonstration purposes
    % for i=1:length(sel)
    %   segmentation.(fn{sel(i)}) = volumefillholes(segmentation.(fn{sel(i)}));
    % end

    [dum, i] = intersect(fn, {'scalp', 'skull', 'brain'});
    if numel(i)==3
      % put them in the preferred order
      fn(i) = {'scalp', 'skull', 'brain'};
    end
    [dum, i] = intersect(fn, {'skin', 'skull', 'brain'}); % this is not likely
    if numel(i)==3
      % put them in the preferred order
      fn(i) = {'skin', 'skull', 'brain'};
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % ensure that the segmentation is internally consistent
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if any(probabilistic)
      segmentation = fixsegmentation(segmentation, fn(probabilistic), 'probabilistic');
    end
    if any(indexed)
      segmentation = fixsegmentation(segmentation, fn(indexed), 'indexed');
    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % convert the segmentation to the desired style
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if isempty(segmentationstyle)
      % keep it as it is
    elseif strcmp(segmentationstyle, 'indexed') && any(probabilistic)
      segmentation  = convert_segmentationstyle(segmentation, fn(probabilistic), segmentation.dim, 'indexed');
      indexed(probabilistic)       = true;  % these are now indexed
      probabilistic(probabilistic) = false; % these are now indexed
    elseif strcmp(segmentationstyle, 'probabilistic') && any(indexed)
      segmentation  = convert_segmentationstyle(segmentation, fn(indexed), segmentation.dim, 'probabilistic');
      probabilistic(indexed) = true;  % these are now probabilistic
      indexed(indexed)       = false; % these are now probabilistic
    end % converting between probabilistic and indexed

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % add the brain if requested
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    if hasbrain
      if all(indexed)
        fn = fieldnames(segmentation);
        sel = false(size(fn));
        for i=1:numel(fn)
          sel(i) = any(strcmp(fn, [fn{i} 'label']));
        end
        fn = fn(sel);

        if numel(fn)>1
          ft_error('cannot construct a brain mask on the fly; this requires a single indexed representation');
        else
          seg      = segmentation.(fn{1});
          seglabel = segmentation.([fn{1} 'label']);
          if ~any(strcmp(seglabel, 'brain'))
            threshold = 0.5;
            smooth    = 5;
            % ensure that the segmentation contains the brain mask, if not then construct it from gray+white+csf
            if length(intersect(seglabel, {'gray' 'white' 'csf'}))~=3
              ft_error('cannot construct a brain mask on the fly; this requires gray, white and csf');
            end
            gray  = seg==find(strcmp(seglabel, 'gray'));
            white = seg==find(strcmp(seglabel, 'white'));
            csf   = seg==find(strcmp(seglabel, 'csf'));
            brain = gray + white + csf;
            clear gray white csf seg
            brain = volumesmooth(brain,    smooth,    'brain');
            brain = volumethreshold(brain, threshold, 'brain');
            % store it in the output
            segmentation.brain = brain;
          end % try to construct the brain
        end

      elseif all(probabilistic)
        if ~isfield(segmentation, 'brain')
          if ~all(isfield(segmentation, {'gray' 'white' 'csf'}))
            ft_error('cannot construct a brain mask on the fly; this requires gray, white and csf');
          end
          threshold = 0.5;
          smooth    = 5;
          % ensure that the segmentation contains the brain mask, if not then construct it from gray+white+csf tissue probability maps
          gray  = segmentation.gray;
          white = segmentation.white;
          csf   = segmentation.csf;
          brain = gray + white + csf;
          clear gray white csf
          brain = volumesmooth(brain,    smooth,    'brain');
          brain = volumethreshold(brain, threshold, 'brain');
          % store it in the output
          segmentation.brain = brain;
        end
      else
        ft_error('cannot construct a brain mask on the fly; this requires a uniquely indexed or a uniquely probabilitic representation');
      end
    end % if hasbrain

  case '2005'
    % the only difference is that the indexed representation for xxx did not have the xxxlabel field prior to the 2012 version
    fn = fieldnames(segmentation);
    sel = ~cellfun(@isempty, regexp(fn, 'label$'));
    segmentation = rmfield(segmentation, fn(sel));
    % furthermore it corresponds to the oldest version of the volume representation
    volversion = '2003';

  otherwise
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    ft_error('unsupported version "%s" for segmentation datatype', segversion);
end

% the segmentation is a speciat type of volume structure, so ensure that it also fulfills the requirements for that
segmentation = ft_datatype_volume(segmentation, 'version', volversion);

% For the pass through ft_datatype_volume it is perhaps necessary to remove
% the fields that are specific for the segmentation and add them later again.
% At this moment ft_datatype_volume nicely passes all fields, so there is no
% special handling of the segmentation fields needed.


function start_num = p01_start_num ( )

%*****************************************************************************80
%
%% P01_START_NUM returns the number of starting points for problem 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer START_NUM, the number of starting points.
%
  start_num = 2;

  return
end


function region = p10_region ( )

%*****************************************************************************80
%
%% P10_REGION returns the name of the integration region for problem 10.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string REGION, the name of the integration region.
%
  region = 'box';

  return
end


function [d,si]=abfload(fn,varargin)
% ** function [d,si]=abfload(fn,varargin)
% loads and returns data in the Axon abf format PRIOR TO VERSION 2.0.
% Data may have been acquired in the following modes:
% (1) event-driven variable-length
% (2) event-driven fixed-length
% (3) gap-free
% Information about scaling, the time base and the number of channels and
% episodes is extracted from the header of the abf file (see also abfinfo.m).
% All optional input parameters listed below (= all except the file name)
% must be specified as parameter/value pairs, e.g. as in
%          d=abfload('d:\data01.abf','start',100,'stop','e');
%
%                    >>> INPUT VARIABLES >>>
%
% NAME        TYPE, DEFAULT      DESCRIPTION
% fn          char array         abf data file name
% start       scalar, 0          only gap-free-data: start of cutout to be read (unit: sec)
% stop        scalar or char,    only gap-free-data: end of cutout to be read (unit: sec).
%             'e'                 May be set to 'e' (end of file).
% sweeps      1d-array or char,  only episodic data: sweep numbers to be read. By default,
%             'a'                 all sweeps will be read ('a')
% channels    cell array         names of channels to be read, like {'IN 0','IN 8'};
%              or char, 'a'       ** make sure spelling is 100% correct (including blanks) **
%                                 if set to 'a', all channels will be read
% chunk       scalar, 0.05       only gap-free-data: the elementary chunk size (Megabytes)
%                                 to be used for the 'discontinuous' mode of reading data
%                                 (when less channels shall be read than exist in file)
% machineF    char array,        the 'machineformat' input parameter of the
%              'ieee-le'          matlab fopen function. 'ieee-le' is the correct
%                                 option for windows; depending on the
%                                 platform the data were recorded/shall be read
%                                 by abfload 'ieee-be' is the alternative.
%
%                    <<< OUTPUT VARIABLES <<<
%
% NAME        TYPE            DESCRIPTION
% d                           the data read, the format depending on the recording mode
%             1. GAP-FREE:
%             2d array        2d array of size
%                              '<data pts>' by '<number of chans>'
%                              Examples of access:
%                              d(:,2)       data from channel 2 at full length
%                              d(1:100,:)   first 100 data points from all channels
%             2. EPISODIC FIXED-LENGTH:
%             3d array        3d array of size
%                              '<data pts per sweep>' by '<number of chans>' by '<number of sweeps>'
%                              Examples of access:
%                              d(:,2,:)            is a matrix which contains all events (at full length)
%                                                  of channel 2 in its columns
%                              d(1:200,:,[1 11])   contains first 200 data points of events #1
%                                                  and #11 of all channels
%             3. EPISODIC VARIABLE-LENGTH:
%             cell array      cell array whose elements correspond to single sweeps. Each element is
%                              a (regular) array of size
%                              '<data pts per sweep>' by '<number of chans>'
%                              Examples of access:
%                              d{1}                 a 2d-array which contains sweep #1 (all of it, all channels)
%                              d{2}(1:100,2)        a 1d-array containing first 100 data points of of channel 2 in sweep #1
%
% si          scalar          the sampling interval in usec
%
% Date of this version: June 17, 2011

% future improvements:
% - handle expansion of header in transition to file version 1.65 better

% --- defaults
% gap-free
start=0.0;
stop='e';
% episodic
sweeps='a';
% general
channels='a';
% the size of data chunks (see above) in Mb. 0.05 Mb is an empirical value
% which works well for abf with 6-16 channels and recording durations of
% 5-30 min
chunk=0.05;
machineF='ieee-le';
verbose=1;

% assign values of optional input parameters, if any were given
pvpmod(varargin);

if verbose, disp(['** ' mfilename]); end
d=[];
si=[];
if ischar(stop)
  if ~strcmpi(stop,'e')
    error('input parameter ''stop'' must be specified as ''e'' (=end of recording) or as a scalar');
  end
end

% --- obtain vital header parameters and initialize them with -1
% temporary initializing var
tmp=repmat(-1,1,16);
% for the sake of typing economy set up a cell array (and convert it to a struct below)
% column order is
%        name, position in header in bytes, type, value)
headPar={
  'fFileVersionNumber',4,'float',-1;
  'nOperationMode',8,'int16',-1;
  'lActualAcqLength',10,'int32',-1;
  'nNumPointsIgnored',14,'int16',-1;
  'lActualEpisodes',16,'int32',-1;
  'lFileStartTime',24,'int32',-1;
  'lDataSectionPtr',40,'int32',-1;
  'lSynchArrayPtr',92,'int32',-1;
  'lSynchArraySize',96,'int32',-1;
  'nDataFormat',100,'int16',-1;
  'nADCNumChannels', 120, 'int16', -1;
  'fADCSampleInterval',122,'float', -1;
  'fSynchTimeUnit',130,'float',-1;
  'lNumSamplesPerEpisode',138,'int32',-1;
  'lPreTriggerSamples',142,'int32',-1;
  'lEpisodesPerRun',146,'int32',-1;
  'fADCRange', 244, 'float', -1;
  'lADCResolution', 252, 'int32', -1;
  'nFileStartMillisecs', 366, 'int16', -1;
  'nADCPtoLChannelMap', 378, 'int16', tmp;
  'nADCSamplingSeq', 410, 'int16',  tmp;
  'sADCChannelName',442, 'uchar', repmat(tmp,1,10);
  'fADCProgrammableGain', 730, 'float', tmp;
  'fInstrumentScaleFactor', 922, 'float', tmp;
  'fInstrumentOffset', 986, 'float', tmp;
  'fSignalGain', 1050, 'float', tmp;
  'fSignalOffset', 1114, 'float', tmp;
  'nTelegraphEnable',4512,'int16',tmp;
  'fTelegraphAdditGain',4576,'float',tmp
};

fields={'name','offs','numType','value'};
s=cell2struct(headPar,fields,2);
numOfParams=size(s,1);
clear tmp headPar;

if ~exist(fn,'file'), error(['could not find file ' fn]); end
if verbose, disp(['opening ' fn '..']); end
[fid,messg]=fopen(fn,'r',machineF);

if fid == -1,error(messg);end;
% determine absolute file size
fseek(fid,0,'eof');
fileSz=ftell(fid);
fseek(fid,0,'bof');

% read all vital information in header
% convert names in structure to variables and read value from header
for g=1:numOfParams,
  if fseek(fid, s(g).offs,'bof')~=0,
    fclose(fid);
    error(['something went wrong locating ' s(g).name]);
  end;
  sz=length(s(g).value);
  eval(['[' s(g).name ',n]=fread(fid,sz,''' s(g).numType ''');']);
  if n~=sz,
    fclose(fid);
    error(['something went wrong reading value(s) for ' s(g).name]);
  end;
end;

if lActualAcqLength<nADCNumChannels,
  fclose(fid);
  error('less data points than sampled channels in file');
end
% the numerical value of all recorded channels (numbers 0..15)
recChIdx=nADCSamplingSeq(1:nADCNumChannels);
% the corresponding indices into loaded data d
recChInd=1:length(recChIdx);
% the channel names, e.g. 'IN 8'
recChNames=(reshape(char(sADCChannelName),10,16))';
recChNames=recChNames(recChIdx+1,:);

chInd=[];
eflag=0;
if ischar(channels)
  if strcmp(channels,'a')
    chInd=recChInd;
  else
    fclose(fid);
    error('input parameter ''channels'' must either be a cell array holding channel names or the single character ''a'' (=all channels)');
  end
else
  for i=1:length(channels)
    tmpChInd=strmatch(channels{i},recChNames,'exact');
    if ~isempty(tmpChInd)
      chInd=[chInd tmpChInd];
    else
      % set error flag to 1
      eflag=1;
    end
  end;
end
if eflag
  fclose(fid);
  disp('**** available channels:');
  disp(recChNames);
  disp(' ');
  disp('**** requested channels:');
  disp(strvcat(channels));
  error('at least one of the requested channels does not exist in data file (see above)');
end

% fFileVersionNumber needs a fix - for whatever reason its value is sometimes
% a little less than what it should be (e.g. 1.6499999xxxx instead of 1.65)
fFileVersionNumber=.001*round(fFileVersionNumber*1000);

% gain of telegraphed instruments, if any
if fFileVersionNumber>=1.65
  addGain=nTelegraphEnable.*fTelegraphAdditGain;
  addGain(addGain==0)=1;
else
  addGain=ones(size(fTelegraphAdditGain));
end

% tell me where the data start
blockSz=512;
switch nDataFormat
  case 0
    dataSz=2;  % bytes/point
    precision='int16';
  case 1
    dataSz=4;  % bytes/point
    precision='float32';
  otherwise
    fclose(fid);
    error('invalid number format');
end;
headOffset=lDataSectionPtr*blockSz+nNumPointsIgnored*dataSz;
% fADCSampleInterval is the TOTAL sampling interval
si=fADCSampleInterval*nADCNumChannels;

if ischar(sweeps) && sweeps=='a'
  nSweeps=lActualEpisodes;
  sweeps=1:lActualEpisodes;
else
  nSweeps=length(sweeps);
end;

switch nOperationMode
  case 1
    if verbose,
      disp('data were acquired in event-driven variable-length mode');
    end
    warndlg('function abfload has not yet been thorougly tested for data in event-driven variable-length mode - please double-check that the data loaded is correct','Just a second, please');
    if (lSynchArrayPtr<=0 || lSynchArraySize<=0),
      fclose(fid);
      error('internal variables ''lSynchArraynnn'' are zero or negative');
    end
    switch fSynchTimeUnit
      case 0  % time information in synch array section is in terms of ticks
        synchArrTimeBase=1;
      otherwise % time information in synch array section is in terms of usec
        synchArrTimeBase=fSynchTimeUnit;
    end;
    % the byte offset at which the SynchArraySection starts
    lSynchArrayPtrByte=blockSz*lSynchArrayPtr;
    % before reading Synch Arr parameters check if file is big enough to hold them
    % 4 bytes/long, 2 values per episode (start and length)
    if lSynchArrayPtrByte+2*4*lSynchArraySize<fileSz,
      fclose(fid);
      error('file seems not to contain complete Synch Array Section');
    end
    if fseek(fid,lSynchArrayPtrByte,'bof')~=0,
      fclose(fid);
      error('something went wrong positioning file pointer to Synch Array Section');
    end
    [synchArr,n]=fread(fid,lSynchArraySize*2,'int32');
    if n~=lSynchArraySize*2,
      fclose(fid);
      error('something went wrong reading synch array section');
    end
    % make synchArr a lSynchArraySize x 2 matrix
    synchArr=permute(reshape(synchArr',2,lSynchArraySize),[2 1]);
    % the length of episodes in sample points
    segLengthInPts=synchArr(:,2)/synchArrTimeBase;
    % the starting ticks of episodes in sample points WITHIN THE DATA FILE
    segStartInPts=cumsum([0 (segLengthInPts(1:end-1))']*dataSz)+headOffset;
    % start time (synchArr(:,1)) has to be divided by nADCNumChannels to get true value
    % go to data portion
    if fseek(fid,headOffset,'bof')~=0,
      fclose(fid);
      error('something went wrong positioning file pointer (too few data points ?)');
    end
    for i=1:nSweeps,
      % if selected sweeps are to be read, seek correct position
      if ~isequal(nSweeps,lActualEpisodes),
        fseek(fid,segStartInPts(sweeps(i)),'bof');
      end;
      [tmpd,n]=fread(fid,segLengthInPts(sweeps(i)),precision);
      if n~=segLengthInPts(sweeps(i)),
        warning(['something went wrong reading episode ' int2str(sweeps(i)) ': ' segLengthInPts(sweeps(i)) ' points should have been read, ' int2str(n) ' points actually read']);
      end;
      dataPtsPerChan=n/nADCNumChannels;
      if rem(n,nADCNumChannels)>0,
        fclose(fid);
        error('number of data points in episode not OK');
      end
      % separate channels..
      tmpd=reshape(tmpd,nADCNumChannels,dataPtsPerChan);
      % retain only requested channels
      tmpd=tmpd(chInd,:);
      tmpd=tmpd';
      % if data format is integer, scale appropriately; if it's float, tmpd is fine
      if ~nDataFormat
        for j=1:length(chInd),
          ch=recChIdx(chInd(j))+1;
          tmpd(:,j)=tmpd(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
            *fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
        end;
      end
      % now place in cell array, an element consisting of one sweep with channels in columns
      d{i}=tmpd;
    end;
  case {2,5}
    if nOperationMode==2
      if verbose
        disp('data were acquired in event-driven fixed-length mode');
      end
    else
      if verbose
        disp('data were acquired in waveform fixed-length mode (clampex only)');
      end
    end
    % determine first point and number of points to be read
    startPt=0;
    dataPts=lActualAcqLength;
    dataPtsPerChan=dataPts/nADCNumChannels;
    if rem(dataPts,nADCNumChannels)>0,
      fclose(fid);
      error('number of data points not OK');
    end
    dataPtsPerChanPerSweep=dataPtsPerChan/lActualEpisodes;
    if rem(dataPtsPerChan,lActualEpisodes)>0
      fclose(fid);
      error('number of data points not OK');
    end
    dataPtsPerSweep=dataPtsPerChanPerSweep*nADCNumChannels;
    if fseek(fid,startPt*dataSz+headOffset,'bof')~=0
      fclose(fid);
      error('something went wrong positioning file pointer (too few data points ?)');
    end
    d=zeros(dataPtsPerChanPerSweep,length(chInd),nSweeps);
    % the starting ticks of episodes in sample points WITHIN THE DATA FILE
    selectedSegStartInPts=((sweeps-1)*dataPtsPerSweep)*dataSz+headOffset;
    for i=1:nSweeps,
      fseek(fid,selectedSegStartInPts(i),'bof');
      [tmpd,n]=fread(fid,dataPtsPerSweep,precision);
      if n~=dataPtsPerSweep,
        fclose(fid);
        error(['something went wrong reading episode ' int2str(sweeps(i)) ': ' dataPtsPerSweep ' points should have been read, ' int2str(n) ' points actually read']);
      end;
      dataPtsPerChan=n/nADCNumChannels;
      if rem(n,nADCNumChannels)>0
        fclose(fid);
        error('number of data points in episode not OK');
      end;
      % separate channels..
      tmpd=reshape(tmpd,nADCNumChannels,dataPtsPerChan);
      % retain only requested channels
      tmpd=tmpd(chInd,:);
      tmpd=tmpd';
      % if data format is integer, scale appropriately; if it's float, d is fine
      if ~nDataFormat
        for j=1:length(chInd),
          ch=recChIdx(chInd(j))+1;
          tmpd(:,j)=tmpd(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
            *fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
        end;
      end
      % now fill 3d array
      d(:,:,i)=tmpd;
    end;

  case 3
    if verbose, disp('data were acquired in gap-free mode'); end
    % from start, stop, headOffset and fADCSampleInterval calculate first point to be read
    %  and - unless stop is given as 'e' - number of points
    startPt=floor(1e6*start*(1/fADCSampleInterval));
    % this corrects undesired shifts in the reading frame due to rounding errors in the previous calculation
    startPt=floor(startPt/nADCNumChannels)*nADCNumChannels;
    % if stop is a char array, it can only be 'e' at this point (other values would have
    % been caught above)
    if ischar(stop),
      dataPtsPerChan=lActualAcqLength/nADCNumChannels-floor(1e6*start/si);
      dataPts=dataPtsPerChan*nADCNumChannels;
    else
      dataPtsPerChan=floor(1e6*(stop-start)*(1/si));
      dataPts=dataPtsPerChan*nADCNumChannels;
      if dataPts<=0
        fclose(fid);
        error('start is larger than or equal to stop');
      end
    end
    if rem(dataPts,nADCNumChannels)>0
      fclose(fid);
      error('number of data points not OK');
    end
    if fseek(fid,startPt*dataSz+headOffset,'bof')~=0,
      fclose(fid);
      error('something went wrong positioning file pointer (too few data points ?)');
    end
    % *** decide on the most efficient way to read data:
    % (i) all (of one or several) channels requested: read, done
    % (ii) one (of several) channels requested: use the 'skip' feature of
    % fread
    % (iii) more than one but not all (of several) channels requested:
    % 'discontinuous' mode of reading data. Read a reasonable chunk of data
    % (all channels), separate channels, discard non-requested ones (if
    % any), place data in preallocated array, repeat until done. This is
    % faster than reading the data in one big lump, separating channels and
    % discarding the ones not requested
    if length(chInd)==1 && nADCNumChannels>1
      % --- situation (ii)
      % jump to proper reading frame position in file
      if fseek(fid,(chInd-1)*dataSz,'cof')~=0
        fclose(fid);
        error('something went wrong positioning file pointer (too few data points ?)');
      end
      % read, skipping nADCNumChannels-1 data points after each read
      dataPtsPerChan=dataPts/nADCNumChannels;
      [d,n]=fread(fid,dataPtsPerChan,precision,dataSz*(nADCNumChannels-1));
      if n~=dataPtsPerChan,
        fclose(fid);
        error(['something went wrong reading file (' int2str(dataPtsPerChan) ' points should have been read, ' int2str(n) ' points actually read']);
      end
    elseif length(chInd)/nADCNumChannels<1
      % --- situation (iii)
      % prepare chunkwise upload:
      % preallocate d
      d=repmat(nan,dataPtsPerChan,length(chInd));
      % the number of data points corresponding to the maximal chunk size,
      % rounded off such that from each channel the same number of points is
      % read (do not forget that each data point will by default be made a
      % double of 8 bytes, no matter what the original data format is)
      chunkPtsPerChan=floor(chunk*2^20/8/nADCNumChannels);
      chunkPts=chunkPtsPerChan*nADCNumChannels;
      % the number of those chunks..
      nChunk=floor(dataPts/chunkPts);
      % ..and the remainder
      restPts=dataPts-nChunk*chunkPts;
      restPtsPerChan=restPts/nADCNumChannels;
      % chunkwise row indices into d
      dix=(1:chunkPtsPerChan:dataPtsPerChan)';
      dix(:,2)=dix(:,1)+chunkPtsPerChan-1;
      dix(end,2)=dataPtsPerChan;
      if verbose && nChunk
        disp(['reading file in ' int2str(nChunk) ' chunks of ~' num2str(chunk) ' Mb']);
      end
      % do it: if no remainder exists loop through all rows of dix,
      % otherwise spare last row for the lines below (starting with
      % 'if restPts')
      for ci=1:size(dix,1)-(restPts>0)
        [tmpd,n]=fread(fid,chunkPts,precision);
        if n~=chunkPts
          fclose(fid);
          error(['something went wrong reading chunk #' int2str(ci) ' (' ...
            int2str(chunkPts) ' points should have been read, ' int2str(n) ' points actually read']);
        end
        % separate channels..
        tmpd=reshape(tmpd,nADCNumChannels,chunkPtsPerChan);
        d(dix(ci,1):dix(ci,2),:)=tmpd(chInd,:)';
      end
      % collect the rest
      [tmpd,n]=fread(fid,restPts,precision);
      if n~=restPts
        fclose(fid);
        error(['something went wrong reading last chunk (' ...
          int2str(restPts) ' points should have been read, ' int2str(n) ' points actually read']);
      end
      % separate channels..
      tmpd=reshape(tmpd,nADCNumChannels,restPtsPerChan);
      d(dix(end,1):dix(end,2),:)=tmpd(chInd,:)';
    else
      % --- situation (i)
      [d,n]=fread(fid,dataPts,precision);
      if n~=dataPts,
        fclose(fid);
        error(['something went wrong reading file (' int2str(dataPts) ' points should have been read, ' int2str(n) ' points actually read']);
      end;
      % separate channels..
      d=reshape(d,nADCNumChannels,dataPtsPerChan);
      d=d';
    end
    % if data format is integer, scale appropriately; if it's float, d is fine
    if ~nDataFormat
      for j=1:length(chInd),
        ch=recChIdx(chInd(j))+1;
        d(:,j)=d(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
          *fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
      end;
    end
  otherwise
    disp('recording mode of data must be event-driven variable-length (1), event-driven fixed-length (2) or gap-free (3) -- returning empty matrix');
    d=[];
    si=[];
end;

fclose(fid);


function file_name_new = file_name_ext_swap ( file_name, ext )

%*****************************************************************************80
%
%% FILE_NAME_EXT_SWAP replaces the current "extension" of a file name.
%
%  Discussion:
%
%    The "extension" of a filename is the string of characters
%    that appears after the LAST period in the name.  A file
%    with no period, or with a period as the last character
%    in the name, has a "null" extension.
%
%  Example:
%
%          Input           Output
%    ================     =============
%    FILE_NAME    EXT     FILE_NAME_NEW
%
%    bob.for      obj     bob.obj
%    bob.bob.bob  txt     bob.bob.txt
%    bob          yak     bob.yak
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 August 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character FILE_NAME(*), a file name.
%    On output, the extension of the file has been changed.
%
%    Input, character EXT(*), the extension to be used on the output
%    copy of FILE_NAME, replacing the current extension if any.
%
%    Output, character FILE_NAME_NEW(*), a copy of the input file name,
%    with the new extension.
%
  file_name_len = length ( file_name );

  ext_len = length ( ext );

  period = file_name_len + 1;

  for i = file_name_len : -1 : 1
    if ( file_name(i:i) == '.' )
      period = i;
      break
    end
  end

  file_name_new(1:period-1) = file_name(1:period-1);
  file_name_new(period) = '.';
  file_name_new(period+1:period+ext_len) = ext(1:ext_len);

  return
end


classdef test_ChanDetails < matlab.unittest.TestCase
   %UNTITLED Summary of this class goes here
   %   Detailed explanation goes here

   properties
   end

   methods(Test)
      function TestRetrieve(testCase)
         ANMO = 'IU.ANMO.00.BHZ';
         ANTO = 'IU.ANTO.00.BHZ';
         % * test retrieve with default source *
         cdKey = ChannelDetails.retrieve([], 'station','ANMO',...
            'channel','BHZ','location','00','network','IU',...
            'starttime','2015-10-21');
         % make sure the first one works, so we can trust use it to
         % evaluate the other ones
         testCase.assertLength(cdKey, 1);
         testCase.assertEqual(cdKey.channelinfo,ChannelTag(ANMO));
         testCase.assertEqual(cdKey.samplerate, 20);
         testCase.assertEqual(cdKey.elevation, 1671);
         testCase.assertEqual(cdKey.latitude, 34.9459, 'absTol', 0.0001);
         testCase.assertEqual(cdKey.depth, 145);
         testCase.assertEqual(cdKey.azimuth, 0);
         testCase.assertEqual(cdKey.dip, -90);
         testCase.assertEqual(cdKey.sensordescription,'Geotech KS-54000 Borehole Seismometer');
         testCase.assertEqual(cdKey.scalefreq,0.0200);
         testCase.assertEqual(cdKey.scaleunits,'M/S');
         testCase.assertEqual(datestr(cdKey.starttime),'17-Dec-2014 18:40:00');
         testCase.assertGreaterThan(cdKey.endtime, cdKey.starttime);

         % test retrieve with a single N.S.L.C string
         chd = ChannelDetails.retrieve([], ANMO);
         testCase.verifyEqual(chd(end),cdKey);
         % test retrieve with ChannelTag
         chaninfo = ChannelTag(ANMO);
         chd = ChannelDetails.retrieve([], chaninfo);
         testCase.verifyEqual(chd(end),cdKey);
         % test retrieve with multiple channeltags
         chansinfo = ChannelTag({ANMO, ANTO});
         chd = ChannelDetails.retrieve([], [chansinfo; chansinfo]);
         testCase.verifySize(chd, [2 2], 'Wrong size returned for multiple Traces');
         % test retrieve with SeismicTrace
         T = SeismicTrace; T.name = ANMO;T.start = datenum('2015-10-21');
         chd = ChannelDetails.retrieve([],T);
         testCase.verifyEqual(chd,cdKey);
         % test retrieve with multiple Traces
         chd = ChannelDetails.retrieve([], [T T; T T]);
         testCase.verifySize(chd, [2, 2], 'Wrong size returned for multiple Traces');
      end
   end

end


function H=tricontour(tri,x,y,z,v,levels,color)
%TRICONTOUR Contour plot for triangulated data.
%   TRICONTOUR(TRI,X,Y,Z,Levels) displays the contour plot based on
%   triangles defined in the M-by-3 face matrix TRI as a surface. A
%   row of TRI contains indexes into the X,Y, and Z vertex vectors
%   to define a single triangular face.
%
%   TRICONTOUR(TRI,X,Y,Z,V,Levels) displays the contour plot based on
%   triangles defined in the M-by-3 face matrix TRI as a surface. A
%   row of TRI contains indexes into the X,Y, and Z vertex vectors
%   to define a single triangular face. The contours are determined
%   by the values V and the Levels.
%
%   H = TRICONTOUR(...) a vector H of handles to LINE or PATCH objects,
%   one handle per line. TRICONTOUR is not compatible with CLABEL.
%
%   The contours are normally colored based on the current colormap
%   and are drawn as PATCH objects. You can override this behavior
%   with the syntax CONTOUR(...,'LINESPEC') to draw the contours as
%   LINE objects with the color and linetype specified.
%
%   Example:
%      x=rand(20); y=rand(20); z=rand(20); tri=delaunay(x,y);
%      tricontour(tri,x,y,z,.3:.1:1); colorbar
%
%   See also CONTOUR, CONTOURF, TRICONTOURF

%----- LGPL --------------------------------------------------------------------
%
%   Copyright (C) 2011-2013 Stichting Deltares.
%
%   This library is free software; you can redistribute it and/or
%   modify it under the terms of the GNU Lesser General Public
%   License as published by the Free Software Foundation version 2.1.
%
%   This library 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
%   Lesser General Public License for more details.
%
%   You should have received a copy of the GNU Lesser General Public
%   License along with this library; if not, see <http://www.gnu.org/licenses/>.
%
%   contact: delft3d.support@deltares.nl
%   Stichting Deltares
%   P.O. Box 177
%   2600 MH Delft, The Netherlands
%
%   All indications and logos of, and references to, "Delft3D" and "Deltares"
%   are registered trademarks of Stichting Deltares, and remain the property of
%   Stichting Deltares. All rights reserved.
%
%-------------------------------------------------------------------------------
%   http://www.deltaressystems.com
%   $HeadURL: https://svn.oss.deltares.nl/repos/delft3d/trunk/src/tools_lgpl/matlab/quickplot/progsrc/tricontour.m $
%   $Id: tricontour.m 2498 2013-05-16 12:38:27Z jagers $

error(nargchk(5,7,nargin));
getdata=0;
if nargin==7
    if strcmp(color,'getdata')
        getdata=1;
        lin = '*';
        col = '*';
    else
        [lin,col,mark,msg] = colstyle(color);
        if ~isempty(msg)
            error(msg)
        end
    end
elseif nargin==6
    if ischar(levels)
        color=levels;
        levels=v;
        v=z;
        z=[];
        if strcmp(color,'getdata')
            getdata=1;
            lin = '*';
            col = '*';
        else
            [lin,col,mark,msg] = colstyle(color);
            if ~isempty(msg)
                error(msg)
            end
        end
    else
        lin = '';
        col = '';
    end
else
    levels=v;
    v=z;
    z=[];
    lin = '';
    col = '';
end

if ~getdata
    ax = newplot;
    if isempty(col) % no color spec was given
        colortab = get(ax,'colororder');
        ncol = size(colortab,1);
    end
end

x=transpose(x(:));
y=transpose(y(:));
zdef=~isempty(z);
if zdef
    z=transpose(z(:));
end
v=transpose(v(:));

Patches=1:size(tri,1);
nlevels = length(levels);
if getdata
    H=cell(1,nlevels);
else
    H=zeros(1,nlevels);
end
NonEmptyLevel=zeros(1,nlevels);
for LevelNr=1:nlevels
    level=levels(LevelNr);
    Nlarger=sum(v(tri)>level,2);
    Nsmaller=sum(v(tri)<level,2);
    NaN_tri=any(isnan(v(tri)),2);
    Nsmaller(NaN_tri)=3;
    Nlarger(NaN_tri)=0;
    CLIndex=1+4*Nlarger+Nsmaller;
    Cutslevel=[0 3 2 0 3 3 3 0 2 3 0 0 0 0 0];
    NLevel=sum(Cutslevel(CLIndex));
    XLevel=repmat(NaN,[NLevel 1]);
    YLevel=XLevel;
    if zdef
        ZLevel=XLevel;
    end
    LvlOffset=0;

    % patches with three equal
    % Patch=Patches(CLIndex==1);

    % patches with two equal
    Patch=Patches((CLIndex==2) | (CLIndex==5));
    if ~isempty(Patch)
        LvlIndex=LvlOffset+(1:3:(3*length(Patch)));
        LvlIndex=[LvlIndex;LvlIndex+1];
        Index=tri(Patch,:);
        [Dummy,Permutation]=sort(v(Index)==level,2);
        Index=Index((Permutation-1)*size(Index,1)+transpose(1:size(Index,1))*[1 1 1]);
        % first element has elevation different from level
        Index=Index(:,[2 3]);
        XPoint=transpose(x(Index));
        XLevel(LvlIndex(:))=XPoint(:);
        YPoint=transpose(y(Index));
        YLevel(LvlIndex(:))=YPoint(:);
        if zdef
            ZPoint=transpose(z(Index));
            ZLevel(LvlIndex(:))=ZPoint(:);
        end
        LvlOffset=LvlOffset+3*length(Patch);
    end

    % patches with one equal, one larger and one smaller
    Patch=Patches(CLIndex==6);
    if ~isempty(Patch)
        LvlIndex=LvlOffset+(1:3:(3*length(Patch)));
        LvlIndex=[LvlIndex;LvlIndex+1];
        Index=tri(Patch,:);
        [Dummy,Permutation]=sort(v(Index),2);
        Index=Index((Permutation-1)*size(Index,1)+transpose(1:size(Index,1))*[1 1 1]);
        % second element has elevation equal to level
        VTemp=v(Index);
        Lambda=min(1,(level-VTemp(:,1))./(VTemp(:,3)-VTemp(:,1)));
        XPoint=transpose([transpose(x(Index(:,1)))+Lambda.*transpose(x(Index(:,3))-x(Index(:,1))) transpose(x(Index(:,2)))]);
        XLevel(LvlIndex(:))=XPoint(:);
        YPoint=transpose([transpose(y(Index(:,1)))+Lambda.*transpose(y(Index(:,3))-y(Index(:,1))) transpose(y(Index(:,2)))]);
        YLevel(LvlIndex(:))=YPoint(:);
        if zdef
            ZPoint=transpose([transpose(z(Index(:,1)))+Lambda.*transpose(z(Index(:,3))-z(Index(:,1))) transpose(z(Index(:,2)))]);
            ZLevel(LvlIndex(:))=ZPoint(:);
        end
        LvlOffset=LvlOffset+3*length(Patch);
    end

    % patches with two larger and one smaller
    Patch=Patches(CLIndex==10);
    if ~isempty(Patch)
        LvlIndex=LvlOffset+(1:3:(3*length(Patch)));
        LvlIndex=[LvlIndex;LvlIndex+1];
        Index=tri(Patch,:);
        [Dummy,Permutation]=sort(v(Index)<level,2);
        Index=Index((Permutation-1)*size(Index,1)+transpose(1:size(Index,1))*[1 1 1]);
        % last element has elevation less than level
        VTemp=v(Index);
        Lambda=min(1,(level-VTemp(:,3)*ones(1,2))./(VTemp(:,[1 2])-VTemp(:,3)*ones(1,2)));
        XPoint=transpose(transpose(x(Index(:,3)))*ones(1,2)+Lambda.*(x(Index(:,[1 2]))-transpose(x(Index(:,3)))*ones(1,2)));
        XLevel(LvlIndex(:))=XPoint(:);
        YPoint=transpose(transpose(y(Index(:,3)))*ones(1,2)+Lambda.*(y(Index(:,[1 2]))-transpose(y(Index(:,3)))*ones(1,2)));
        YLevel(LvlIndex(:))=YPoint(:);
        if zdef
            ZPoint=transpose(transpose(z(Index(:,3)))*ones(1,2)+Lambda.*(z(Index(:,[1 2]))-transpose(z(Index(:,3)))*ones(1,2)));
            ZLevel(LvlIndex(:))=ZPoint(:);
        end
        LvlOffset=LvlOffset+3*length(Patch);
    end

    % patches with two smaller and one larger
    Patch=Patches(CLIndex==7);
    if ~isempty(Patch)
        LvlIndex=LvlOffset+(1:3:(3*length(Patch)));
        LvlIndex=[LvlIndex;LvlIndex+1];
        Index=tri(Patch,:);
        [Dummy,Permutation]=sort(v(Index)>level,2);
        Index=Index((Permutation-1)*size(Index,1)+transpose(1:size(Index,1))*[1 1 1]);
        % last element has elevation larger than level
        VTemp=v(Index);
        Lambda=min(1,(level-VTemp(:,[1 2]))./(VTemp(:,3)*ones(1,2)-VTemp(:,[1 2])));
        XPoint=transpose(x(Index(:,[1 2]))+Lambda.*(transpose(x(Index(:,3)))*ones(1,2)-x(Index(:,[1 2]))));
        XLevel(LvlIndex(:))=XPoint(:);
        YPoint=transpose(y(Index(:,[1 2]))+Lambda.*(transpose(y(Index(:,3)))*ones(1,2)-y(Index(:,[1 2]))));
        YLevel(LvlIndex(:))=YPoint(:);
        if zdef
            ZPoint=transpose(z(Index(:,[1 2]))+Lambda.*(transpose(z(Index(:,3)))*ones(1,2)-z(Index(:,[1 2]))));
            ZLevel(LvlIndex(:))=ZPoint(:);
        end
        LvlOffset=LvlOffset+3*length(Patch);
    end

    % patches with one equal and two larger or two smaller
    Patch=Patches((CLIndex==3) | (CLIndex==9));
    if ~isempty(Patch)
        LvlIndex=LvlOffset+(1:2:(2*length(Patch)));
        Index=tri(Patch,:);
        [Dummy,Permutation]=sort(v(Index)==level,2);
        Index=Index((Permutation-1)*size(Index,1)+transpose(1:size(Index,1))*[1 1 1]);
        % third element has elevation equal to level
        Index=Index(:,3);
        XPoint=x(Index);
        XLevel(LvlIndex(:))=XPoint(:);
        YPoint=y(Index);
        YLevel(LvlIndex(:))=YPoint(:);
        if zdef
            ZPoint=z(Index);
            ZLevel(LvlIndex(:))=ZPoint(:);
        end
        LvlOffset=LvlOffset+2*length(Patch);
    end

    VLevel=level*ones(size(XLevel));

    NonEmptyLevel(LevelNr)=1;
    if getdata
        if zdef
            H{LevelNr}={XLevel YLevel ZLevel LevelNr};
        else
            H{LevelNr}={XLevel YLevel LevelNr};
        end
    elseif isempty(col) && isempty(lin)
        if ~zdef
            ZLevel=VLevel;
        end
        NewH = patch('XData',transpose([XLevel;XLevel]), ...
            'YData',transpose([YLevel;YLevel]), ...
            'ZData',transpose([ZLevel;ZLevel]), ...
            'CData',transpose([VLevel;VLevel]), ...
            'facecolor','none', ...
            'edgecolor','flat',...
            'userdata',level, ...
            'parent',ax);
        H(LevelNr)=NewH;
    else
        if ~zdef
            ZLevel=VLevel;
        end
        NewH = line('XData',XLevel, ...
            'YData',YLevel, ...
            'ZData',ZLevel, ...
            'userdata',level, ...
            'parent',ax);
        H(LevelNr)=NewH;
    end
end

levels=levels(logical(NonEmptyLevel));

if getdata
    % do nothing
elseif isempty(col) && ~isempty(lin)
    nlvl = length(levels);
    colortab = colortab(mod(1:nlvl,ncol)+1,:);
    for i = 1:length(H)
        set(H(i),'linestyle',lin,'color',colortab(i,:));
    end
else
    if ~isempty(lin)
        set(H,'linestyle',lin);
    end
    if ~isempty(col)
        set(H,'color',col);
    end
end


% Configuration function for some constants used in the library
%
%
% Copyright (c) 2018 Department of Computer Science,
%                    University of Toronto, Canada,
%                    Vector Institute, Canada
%
% License
% This file is under the LGPL license,  you can
%  redistribute it and/or modify it under the terms of the GNU Lesser General
%  Public License as published by the Free Software Foundation, either version 3
%  of the License, or (at your option) any later version. This file 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 Lesser General Public License for more
%  details.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Author
%  Yingxue Wang <yingxue@cs.toronto.edu>
%  Sean Robertson <sdrobert@cs.toronto.edu>
%

classdef Config < handle
    properties (Constant)
        EFFECTIVE_SUPPORT_THRESHOLD = double(5e-4)
%         LOG_FLOOR_VALUE = double(1e-5)
        LOG_FLOOR_VALUE = double(1e-10)
    end
end


function variables( varargin )

%VARIABLES Declares one or more CVX variables.
%   VARIABLES x1 x2 x3 ..., where x1, x2, x3, etc. are valid
%   variable names, declares multiple cvx variables. It is
%   exactly equivalent to issuing a separate VARIABLE command
%   for each x1, x2, x3, ...
%
%   VARIABLES allows the declaration of vector, matrix, and
%   array variables. However, unlike VARIABLE, structure modifiers
%   such as "symmetric", "toeplitz", etc. are NOT permitted. Thus
%   VARIABLES cannot be used with variables with structure.
%
%   Examples:
%      variables x y z;
%      variables x(100) y z(100,10);
%
%   See also VARIABLE, DUAL, DUALS.

if ~iscellstr( varargin ),
    error( 'VARIABLES must be used in command mode.' );
end

for k = 1 : nargin,
    evalin( 'caller', [ 'variable ', varargin{k} ] );
end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function Xr=pround(X,d)

Xr=round(X.*(10^d))./(10^d);

end

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function line_ncc_rule_test ( )

%*****************************************************************************80
%
%% LINE_NCC_RULE_TEST tests the LINE_NCC_RULE library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 April 2014
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LINE_NCC_RULE_TEST\n' );
  fprintf ( 1, '  MATLAB version:\n' );
  fprintf ( 1, '  Test the LINE_NCC_RULE library.\n' );

  line_ncc_rule_test01 ( );
  line_ncc_rule_test02 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'LINE_NCC_RULE_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function f = subsasgn(f, index, val)
%SUBSASGN   Chebfun SUBSASGN.
% ( )
%   F(X) = VAL assigns the values VAL at locations specified by X to the
%   CHEBFUN F. SIZE(X, 1) should be equal to LENGTH(VAL) and SIZE(X, 2) should
%   be the number of columns in F. SUBSASGN introduces new breakpoints
%   in F at points in X that were not originally in F.DOMAIN. See DEFINEPOINT
%   for further details.
%
% .
%   CHEBFUN properties are restricted, so F.PROP = VAL has no effect.
%
% {}
%   F{A, B} = G redefines the CHEBFUN F in the interval [A, B] using G. See
%   CHEBFUN/DEFINEINTERVAL for further details.
%
% See also SUBSREF, DEFINEPOINT, DEFINEINTERVAL.

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

% TODO: Error checking. Particularly integer indicies and quasimatrix indexing.

% TODO: Document for array-valued CHEBFUN objects and quasimatrices.

idx = index(1).subs;

switch index(1).type
    case '.'

        % [TODO]: Restrict access to this.
        f = builtin('subsasgn', f, index, val);

    case '()'

        if ( f(1).isTransposed && numel(idx) >= 2 )
            idx(1:2) = idx([2 1]);
        end
        if ( ischar(idx{1}) && strcmp(idx{1}, ':') )
            % Assign a column:
            f = assignColumns(f, idx{2}, val);
        else
            % Define a point value:
            f = definePoint(f, idx{1}, val);
        end

    case '{}'

        % Define an interval:
        f = defineInterval(f, [idx{:}], val);

    otherwise
        error('CHEBFUN:CHEBFUN:subsasgn:UnexpectedType',...
            ['??? Unexpected index.type of ' index(1).type]);
end

end


% Copyright (C) 1993-2011, by Peter I. Corke
%
% This file is part of The Machine Vision Toolbox for Matlab (MVTB).
%
% MVTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% MVTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with MVTB.  If not, see <http://www.gnu.org/licenses/>.
function c = colorize2(im, color)

    if nargin < 2
        color = [1 1 1];
    end
    c = [];
    for i=1:numel(color)
        c = cat(3, c, im*color(i));
    end


classdef IN1KMOP9 < EvoXBenchProblem
% <multi> <real> <large/none> <expensive/none>

%------------------------------- Reference --------------------------------
% Z. Lu, R. Cheng, Y. Jin, K. C. Tan, and K. Deb, Neural architecture
% search as multiobjective optimization benchmarks: Problem formulation and
% performance assessment, IEEE Transactions on Evolutionary Computation,
% 2023.
%--------------------------------------------------------------------------

    methods
        %% Default settings of the problem
        function Setting(obj)
            config.name = 'mnv3';
            config.args.objs = 'err&params&flops&latency';
            config.args.normalized_objectives = false;
            obj.Setting@EvoXBenchProblem(config);
        end
    end
end