%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT 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.
%
% SPHARM-MAT 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 SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ============================================
% patch_mesh.m
%
% Goal: surface mesh rendering
%       need to open figure or subplot before use
%
% Li Shen
% 02/21/2006 - create

function h = patch_mesh(vertices,faces)

h = patch('faces', faces, 'vertices', vertices, ...
	'FaceColor', 'w', 'EdgeColor', 'k', 'FaceAlpha', 1); % transparancy can be adjusted by FaceAlpha
axis image; box on; view(3);

return;


function y = vpa(varargin);
% (1) vpa in Octave produces a lot of unwanted displayed text. It's directly displayed, not part of the
% function  output. I didn't found a way to remove it (I tried changing
% PAGER). But Dennis uses a clever trick (with "tail") to remove that output in the
% online compiler
% (2) (i) After converting to char, the result is different from Matlab. For
% example, char(vpa(pi^pi)) produces the string
%     'Float(''36.462159607207901501624291995540261'', prec=32)''
% instead of just the string
%     '36.46215960720790150162429199554' as in Matlab.
% (ii) Also, precision is lost by using `char`: char(vpa('-3.4')) gives the
% string
%     'Float(''-3.3999999999999999999999999999999988'', prec=32)'
% Both (i) and (ii) seem to be resolved by `pretty` (which actually calls `disp`):
% `pretty(vpa('-3.4'))` gives the string
%     '-3.4000000000000000000000000000000'
% However, `pretty` formats the output string with spaces and newlines. These
% characters are removed if we are sure they are unwanted: real scalars
y = pretty(builtin('vpa', varargin{:}));
if isscalar(varargin{1}) && isreal(double(varargin{1}))
    y = y(y>32); % remove spaces and newlines produced by `pretty`
end
% In Octave `pretty(vpa('765.0908',20))` gives '765.09080000000000000'. In Matlab it gives '765.0908', and 765 gives '765.0'.
% To remove surplus zeros in Octave, the following seems to work. It
% doesn't work for complex values, but the complex case seems to have
% precision loss anyway
if ~ismember('I',y) % complex case not covered
    y = regexprep(y,'(?<=\.\d*)0+(?=(e|$))','0');
end
end


function adjList = meshFaceAdjacency(vertices, edges, faces)
%MESHFACEADJACENCY Compute adjacency list of face around each face.
%
%
%   Example
%     % Create a sample 3D mesh
%     [v, e, f] = createDodecahedron;
%     adjList = meshFaceAdjacency(v, e, f);
%     figure; hold on; axis equal; view([100 40]);
%     drawMesh(v, f);
%     % draw sample face in a different color
%     drawMesh(v, f(1, :), 'faceColor', 'b');
%     % draw the neighbors of a sample face
%     drawMesh(v, f(adjList{1}, :), 'faceColor', 'g')
%
%

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

edgeFaceList = meshEdgeFaces(vertices, edges, faces);

% allocate memory for adjacency list
nFaces = max(edgeFaceList(:));
adjList = cell(1, nFaces);

% iterate over edges to populate adjacency list
for iEdge = 1:size(edgeFaceList)
    f1 = edgeFaceList(iEdge, 1);
    f2 = edgeFaceList(iEdge, 2);
    adjList{f1} = [adjList{f1} f2];
    adjList{f2} = [adjList{f2} f1];
end


classdef regressionTest < matlab.unittest.TestCase

    properties
        testDir = ''
        plotSolvers = []  % 1 to plot new run comparison by sln method
        openCompare = []  % 1 opens all new run vs. stored run plots for comparison of each solver
        regular
        regularCIC
        regularSS
        irregularCIC
        irregularSS
        OriginalDefault
    end

    methods(Access = 'public')

        function obj = regressionTest(plotSolvers, openCompare)
            arguments
                plotSolvers (1,1) double = 1
                openCompare (1,1) double = 1
            end
            % Assign arguments to test Class
            obj.plotSolvers = plotSolvers;
            obj.openCompare = openCompare;
            % Set test directory
            obj.testDir = fileparts(mfilename('fullpath'));
            % Save the visibility state at construction
            obj.OriginalDefault = get(0,'DefaultFigureVisible');
        end

    end

    methods (TestMethodSetup)
        function killPlots (~)
            set(0,'DefaultFigureVisible','off');
        end
    end

    methods(TestClassSetup)

        function runRegTest(testCase)
            cd(fullfile(testCase.testDir,       ...
                        'RegressionTests',      ...
                        'RegularWaves',         ...
                        'regular'))
            runLoadRegular;
            testCase.regular = load('regular.mat').("regular");
            savefig(fullfile('..', 'figReg'));
            cd(testCase.testDir);
        end

        function runRegCICTest(testCase)
            cd(fullfile(testCase.testDir,       ...
                        'RegressionTests',      ...
                        'RegularWaves',         ...
                        'regularCIC'))
            runLoadRegularCIC;
            testCase.regularCIC = load('regularCIC.mat').("regularCIC");
            savefig(fullfile('..', 'figRegCIC'));
            cd(testCase.testDir);
        end

        function runRegSSTest(testCase)
            cd(fullfile(testCase.testDir,       ...
                        'RegressionTests',      ...
                        'RegularWaves',         ...
                        'regularSS'))
            runLoadRegularSS;
            testCase.regularSS = load('regularSS.mat').("regularSS");
            savefig(fullfile('..', 'figRegSS'));
            cd(testCase.testDir);
        end

        function runIrregCICTest(testCase)
            cd(fullfile(testCase.testDir,   ...
                        'RegressionTests',  ...
                        'IrregularWaves',   ...
                        'irregularCIC'))
            runLoadIrregularCIC;
            testCase.irregularCIC = ...
                                load('irregularCIC.mat').("irregularCIC");
            savefig(fullfile('..', 'figIrregCIC'));
            cd(testCase.testDir);
        end

        function runIrregSSTest(testCase)
            cd(fullfile(testCase.testDir,   ...
                        'RegressionTests',  ...
                        'IrregularWaves',   ...
                        'irregularSS'))
            runLoadIrregularSS;
            testCase.irregularSS = load('irregularSS.mat').("irregularSS");
            savefig(fullfile('..', 'figIrregSS'));
            cd(testCase.testDir);
        end

    end

    methods(TestClassTeardown)

        function plotRegTests(testCase)
            % Plot Solver Comparisons
            if testCase.plotSolvers == 1
                cd(fullfile(testCase.testDir,   ...
                            'RegressionTests',  ...
                            'RegularWaves'));
                printPlotRegular;
                cd(fullfile(testCase.testDir,   ...
                            'RegressionTests',  ...
                            'IrregularWaves'));
                printPlotIrregular;
            end
            % Open new vs. org Comparisons
            if testCase.openCompare == 1
                cd(fullfile(testCase.testDir,   ...
                            'RegressionTests',  ...
                            'RegularWaves'));
                openfig('figReg.fig');
                openfig('figRegCIC.fig');
                openfig('figRegSS.fig');
                cd(fullfile(testCase.testDir,   ...
                            'RegressionTests',  ...
                            'IrregularWaves'));
                openfig('figIrregCIC.fig');
                openfig('figIrregSS.fig');
            end
            set(0,'DefaultFigureVisible',testCase.OriginalDefault);
            testCase.assertEqual(get(0,'DefaultFigureVisible'),     ...
                                 testCase.OriginalDefault);
        end
    end

    methods(Test)

        function body1_reg_disp_heave(testCase)
            % Body1 Displacement in Heave
            tol = 1e-10;
            org = testCase.regular.B1.WEC_Sim_org.heave;
            new = testCase.regular.B1.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body1 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body2_reg_disp_heave(testCase)
            % Body2 Displacement in Heave
            tol = 1e-10;
            org = testCase.regular.B2.WEC_Sim_org.heave;
            new = testCase.regular.B2.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body2 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function bodyRel_reg_disp_heave(testCase)
            % Relative Displacement in Heave
            tol = 1e-10;
            org = testCase.regular.Rel.WEC_Sim_org.heave;
            new = testCase.regular.Rel.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Relative Displacement in Heave, Diff = '  ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body1_regCIC_disp_heave(testCase)
            % Body1 Displacement in Heave
            tol = 1e-10;
            org = testCase.regularCIC.B1.WEC_Sim_org.heave;
            new = testCase.regularCIC.B1.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body1 Displacement in Heave, Diff = '     ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function body2_regCIC_disp_heave(testCase)
            % Body2 Displacement in Heave
            tol = 1e-10;
            org = testCase.regularCIC.B2.WEC_Sim_org.heave;
            new = testCase.regularCIC.B2.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body2 Displacement in Heave, Diff = '     ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function bodyRel_regCIC_disp_heave(testCase)
            % Relative Displacement in Heave
            tol = 1e-10;
            org = testCase.regularCIC.Rel.WEC_Sim_org.heave;
            new = testCase.regularCIC.Rel.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Relative Displacement in Heave, Diff = '  ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body1_regSS_disp_heave(testCase)
            % Body1 Displacement in Heave
            tol = 1e-10;
            org = testCase.regularSS.B1.WEC_Sim_org.heave;
            new = testCase.regularSS.B1.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body1 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body2_regSS_disp_heave(testCase)
            % Body2 Displacement in Heave
            tol = 1e-10;
            org = testCase.regularSS.B2.WEC_Sim_org.heave;
            new = testCase.regularSS.B2.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body2 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function bodyRel_regSS_disp_heave(testCase)
            % Relative Displacement in Heave
            tol = 1e-10;
            org = testCase.regularSS.Rel.WEC_Sim_org.heave;
            new = testCase.regularSS.Rel.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Relative Displacement in Heave, Diff = '  ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body1_irreg_disp_heave(testCase)
            % Body1 Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularCIC.B1.WEC_Sim_org.heave;
            new = testCase.irregularCIC.B1.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body1 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function body2_irreg_disp_heave(testCase)
            % Body2 Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularCIC.B2.WEC_Sim_org.heave;
            new = testCase.irregularCIC.B2.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body2 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function bodyRel_irreg_disp_heave(testCase)
            % Relative Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularCIC.Rel.WEC_Sim_org.heave;
            new = testCase.irregularCIC.Rel.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Relative Displacement in Heave, Diff = '  ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function irreg_0th_Spectral_Moment(testCase)
            % 0th Order Spectral Moment
            tol = 1e-10;
            org = testCase.irregularCIC.Sp.WEC_Sim_org.m0;
            new = testCase.irregularCIC.Sp.WEC_Sim_new.m0;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['0th Order Spectral Moment, Diff = '       ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function irreg_2nd_Spectral_Moment(testCase)
            % 2nd Order Spectral Moment
            tol = 1e-10;
            org = testCase.irregularCIC.Sp.WEC_Sim_org.m2;
            new = testCase.irregularCIC.Sp.WEC_Sim_new.m2;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['2nd Order Spectral Moment, Diff = '       ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function body1_irregSS_disp_heave(testCase)
            % Body1 Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularSS.B1.WEC_Sim_org.heave;
            new = testCase.irregularSS.B1.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body1 Displacement in Heave, Diff = '     ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function body2_irregSS_disp_heave(testCase)
            % Body2 Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularSS.B2.WEC_Sim_org.heave;
            new = testCase.irregularSS.B2.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Body2 Displacement in Heave, Diff = '     ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function bodyRel_irregSS_disp_heave(testCase)
            % Relative Displacement in Heave
            tol = 1e-10;
            org = testCase.irregularSS.Rel.WEC_Sim_org.heave;
            new = testCase.irregularSS.Rel.WEC_Sim_new.heave;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['Relative Displacement in Heave, Diff = '  ...
                      num2str(max(abs(org-new))) '\n']);
        end

        function irregSS_0th_Spectral_Moment(testCase)
            % 0th Order Spectral Moment
            tol = 1e-10;
            org = testCase.irregularSS.Sp.WEC_Sim_org.m0;
            new = testCase.irregularSS.Sp.WEC_Sim_new.m0;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['0th Order Spectral Moment, Diff = '       ...
                     num2str(max(abs(org-new))) '\n']);
        end

        function irregSS_2nd_Spectral_Moment(testCase)
            % 2nd Order Spectral Moment
            tol = 1e-10;
            org = testCase.irregularSS.Sp.WEC_Sim_org.m2;
            new = testCase.irregularSS.Sp.WEC_Sim_new.m2;
            testCase.verifyEqual(new,org,'AbsTol',tol);
            fprintf(['2nd Order Spectral Moment, Diff = '       ...
                     num2str(max(abs(org-new))) '\n']);
        end

    end

end


classdef math_model_opf_acci_legacy < mp.math_model_opf_acci & mp.mm_shared_opf_legacy
%MP.MATH_MODEL_OPF_ACCI_LEGACY  MATPOWER mathematical model for AC optimal power flow (OPF) problem.
%   ?
%
%   MP.MATH_MODEL_OPF_ACCI_LEGACY ... power flow ...
%
%   Properties
%       ? - ?
%
%   Methods
%       ?

%   MATPOWER
%   Copyright (c) 2021-2022, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%     end

    methods
        %% constructor
        function obj = math_model_opf_acci_legacy()
            obj@mp.math_model_opf_acci();
            if nargin > 0 && isstruct(mpc)
                obj.mpc = mpc;
            end

            %% Due to a bug related to inheritance in constructors in
            %% Octave 5.2 and earlier (https://savannah.gnu.org/bugs/?52614),
            %% INIT_SET_TYPES() cannot be called directly in the
            %% MP_IDX_MANAGER constructor, as desired.
            %%
            %% WORKAROUND:  INIT_SET_TYPES() is called explicitly as needed
            %%              (if om.var is empty) in ADD_VAR(), DISPLAY() and
            %%              INIT_INDEXED_NAME(), after object construction,
            %%              but before object use.
        end

        function obj = add_named_set(obj, varargin)
            % call parent method (also checks for valid type for named set)
            add_named_set@mp.math_model_opf_acci(obj, varargin{:});
            obj.add_named_set_legacy(varargin{:});
        end

        function obj = def_set_types(obj)
            obj.def_set_types_legacy();
        end

        function obj = init_set_types(obj)
            init_set_types@mp.math_model_opf_acci(obj);
            obj.init_set_types_legacy();
        end

        function obj = build(obj, nm, dm, mpopt)
            obj.mpc = dm.source;
            build@mp.math_model_opf_acci(obj, nm, dm, mpopt);
            obj.build_legacy(nm, dm, mpopt);
        end

        function obj = add_vars(obj, nm, dm, mpopt)
            add_vars@mp.math_model_opf_acci(obj, nm, dm, mpopt);  %% call parent

            %% legacy user-defined variables
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_vars(nm, dm, mpopt);
            end
        end

        function add_system_costs(obj, nm, dm, mpopt)
            add_system_costs@mp.math_model_opf_acci(obj, nm, dm, mpopt);    %% call parent

            %% legacy user-defined costs
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_costs(nm, dm, 0);
            end
        end

        function obj = add_system_constraints(obj, nm, dm, mpopt)
            %% call parent
            add_system_constraints@mp.math_model_opf_acci(obj, nm, dm, mpopt);

            %% legacy user-defined constraints
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_constraints_ac(nm, dm, mpopt);
            end
        end

        function names = legacy_user_var_names(obj)
            names = {'Vr', 'Vi', 'Pg', 'Qg'};
        end
    end     %% methods
end         %% classdef


function rs = rms(s)

%tstoolbox/@signal/rms
%   Syntax:
%     * rs = rms(s)
%
%   Calculate root mean square value for signal along dimension 1.
%
% Copyright 1997-2001 DPI Goettingen, License http://www.physik3.gwdg.de/tstool/gpl.txt

narginchk(1,1);

c = rms(s.core); 	% call real working routine for parent core object
rs = signal(c, s);

if ndim(rs) > 0
	rs.xaxes = s.xaxes(2:end);
end

rs = addhistory(rs,  ['Calculated root mean square value along dimension 1'] );
rs = addcommandlines(rs, 's = rms(s');


function [motionC, measC] = factorCoord(Lmk,Frm,Fac)

nframes  = sum([Frm.used]);
nlmks    = sum([Lmk.used]);

% Motion
motionC = zeros(nframes,3);

% Measurements
measC = zeros(nframes+nlmks,3);

for fac = find([Fac.used])

    frames = Fac(fac).frames;
    lmk = Fac(fac).lmk;

    switch Fac(fac).type
        case'motion'
            motionC(frames(1),1:3) = Frm(frames(1)).state.x(1:3)';
            motionC(frames(2),1:3) = Frm(frames(2)).state.x(1:3)';
        case 'absolute'
        case 'measurement'
            measC(frames,1:3) = Frm(frames).state.x(1:3)';
            measC(lmk+nframes,1:3) = Lmk(lmk).state.x(1:3)';
    end

end

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

%   # START GPL LICENSE

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

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

%   # END GPL LICENSE


% ASTROTIK by Francesco Santilli

function [orbits0,t0,mi,R,mi0,J] = checkscenario(scenario)

    if ~isa(scenario,'struct')
        error('Wrong class of an input argument.')
    end

    f(1) = isfield(scenario,'orbits0');
    f(2) = isfield(scenario,'t0');
    f(3) = isfield(scenario,'mi');
    f(4) = isfield(scenario,'R');
    f(5) = isfield(scenario,'mi0');

    if ~all(f)
        error('Missing field in scenario structure.')
    end

    orbits0 = scenario.orbits0;
    t0      = scenario.t0;
    mi      = scenario.mi;
    R       = scenario.R;
    mi0     = scenario.mi0;

    [J,D] = check(orbits0,2);
    check(t0,1)
    check(mi,1)
    check(R,1)
    check(mi0,0)

    if ~(D==3 || D==5)
        error('Wrong size of input arguments.')
    end

    if ~(length(t0)==J && length(mi)==J && length(R)==J)
        error('Wrong size of input arguments.')
    end

    if any(mi < 0)
        error('mi must be a positive value.')
    end

    if any(R < 0)
        error('R must be a positive value.')
    end

    if mi0 <= 0
        error('mi0 must be a strictly positive value.')
    end

end


function[]=makefigs_patchcontourf
%MAKEFIGS_PATCHCONTOURF  Makes a sample figure for PATCHCONTOURF.

load jtopo
use jtopo

figure
h=patchcontourf(lon,lat,topo,0,'k');latratio(30)
axis([-180 180 -75 75]),boxon,axis tight
title('Continents filled with PATCHCONTOURF')

%Make a second figure if m_map is installed
if exist('m_map')==7
    figure
    m_proj('miller','lat',75);
    m_grid('linestyle','none')
    patchcontourf(lon,lat,topo,0,'k','m_map');
    title('Continents filled with PATCHCONTOURF, M-MAP option')
end


classdef MAD < Algorithms.CDAlg
    properties
        nMADUsed = uint8(255);
    end
    methods
        function obj = MAD(k)
            obj@Algorithms.CDAlg('Multivariate Alteration Detection', ...
                ['Nielsen, Allan & Conradsen, Knut & Simpson, James. (1998). ',...
                'Multivariate Alteration Detection (MAD) and MAF Postprocessing',...
                'in Multispectral, Bitemporal Image Data: ',...
                'New Approaches to Change Detection Studies.',...
                'Remote Sensing of Environment.',...
                '64. 1-19. 10.1016/S0034-4257(97)00162-4. '] ...
                );
            if exist('k', 'var'), obj.nMADUsed=uint8(k); end
        end
        [DI, k] = detectChange(obj, t1, t2);
    end
end


function [ output_args ] = create_html_file_gm( filename, rx_lat, rx_long, hyperbola_lat, hyperbola_long, heatmap_cell, heatmap_threshold )
%CREATE_HTML_FILE   Generates the html code for google maps showing RX
%                   positions and the hyperbolas with a heatmap
%
%   rx_lat:         list of latitudes for RX positions (for displaying receiver positions)
%   rx_long:        list of longitudes for RX positions
%   hyperbola_lat:  cell array of latitudes for RX positions (one cell array elements correspond to one hyperbola)
%   hyperbola_lat:  cell array of longitudes for RX positions (one cell array elements correspond to one hyperbola)
%   heatmap_cell:   cell array, that contains {1} = long vector, {2} = lat vector and {3} = magnitude of heatmap points vector

    disp('writing html for google maps... ');

    % consistency checks
    if ~iscell(heatmap_cell)
        error('Parameter heatmap_cell needs to be a cell array with long, lat and magnitude');
    end

    if size(heatmap_cell) ~= 3
        error('Parameter heatmap_cell needs to be a cell array with long, lat and magnitude');
    end

    if ~iscell(hyperbola_lat) || ~iscell(hyperbola_long)
        error('Parameter hyperbola_lat, hyperbola_long need to be cell arrays');
    end

    if length(hyperbola_lat) ~= length(hyperbola_long)
        error('Length of hyperbola latitude and longitude values do not match');
    end

    for ii=1:length(hyperbola_lat)
        if length(cell2mat(hyperbola_lat(ii))) ~= length(cell2mat(hyperbola_long(ii)))
            error(['Length of hyperbola latitude and longitude in cell array doesn not for hyperbola ' num2str(ii)]);
        end
    end

    if size(rx_lat) ~= size(rx_long)
        error('Dimensions of rx latitude and longitude values do not match');
    end

    num_rx_positions = length(rx_lat);

    num_hyperbolas = length(hyperbola_lat);  % length of cell array

    num_hyperb_points = zeros(1, num_hyperbolas);
    for ii = 1:num_hyperbolas
        num_hyperb_points(ii) = length(hyperbola_lat{ii}); % length of each vector in the cell array
    end

    %% generate html code
    disp(['write html to file: ' filename]);

    fid = fopen(filename,'w');

    fprintf(fid, [...
        '<!DOCTYPE html>\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        '

\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        '\n'...
        ]);

    fclose(fid);

    disp('writing html, done!');
end


% ConvertBasler2pos - Convert Basler data to pos file format
%
%  USAGE
%
%    ConvertBasler2pos(filebasename,<options>)
%
%    filebasename   basename of the video file (should be filebasenmae.avi)
%    <options>      optional list of property-value pairs (see table below)
%
%    =========================================================================
%     Properties    Values
%    -------------------------------------------------------------------------
%     'syncDatFile' name of binary file where sync signal is stored
%                   (default = filebasename_digitalin.dat)
%     'syncSampFq'  sampling freqeuncy of the sync signal (default= 20kHz)
%     'syncChan'    sync channel to read (default = 1)
%     'syncNbCh'    number of channels in the sync file (default = 1)
%     'posSampFq'   sampling frequency of the final pos file (after
%                   interpolation)
%    =========================================================================
%
% DEPENDENCIES:
%
%   bz_LoadBinary
%   Process_DetectLED

% Copyright (C) 2015 Adrien Peyrache
% edited by David Tingley, 2017
%
% 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.

warning('This function is now deprecated and needs to be replaced.')

function Process_ConvertBasler2Pos(fbasename,varargin)

syncDatFile = ['analogin.dat'];
syncSampFq  = 20000;
syncChan    = 1;
syncNbCh    = 1;
posSampFq   = 30; %in Hz

% Parse options
for i = 1:2:length(varargin),
  if ~isa(varargin{i},'char'),
    error(['Parameter ' num2str(i+3) ' is not a property (type ''help Process_ConvertBasler2Pos'' for details).']);
  end
  switch(lower(varargin{i})),
    case 'syncdatfile',
      syncDatFile = varargin{i+1};
      if ~isa(duration,'char')
        error('Incorrect value for property ''syncDatFile'' (type ''help Process_ConvertBasler2Pos'' for details).');
      end
    case 'syncsampfq',
      syncSampFq = varargin{i+1};
      if ~isa(frequency,'numeric')
        error('Incorrect value for property ''syncsampfq'' (type ''help Process_ConvertBasler2Pos'' for details).');
      end
    case 'syncchan',
      syncChan = varargin{i+1};
      if ~isa(start,'numeric')
        error('Incorrect value for property ''syncChan'' (type ''help Process_ConvertBasler2Pos'' for details).');
      end
		if start < 0, start = 0; end
    case 'syncnbch',
      syncNbCh = varargin{i+1};
      if ~isa(syncNbCh,'numeric')
        error('Incorrect value for property ''syncNbCh'' (type ''help Process_ConvertBasler2Pos'' for details).');
      end
    case 'possampfq',
      posSampFq = varargin{i+1};
      if ~isa(posSampFq,'numeric')
        error('Incorrect value for property ''posSampFq'' (type ''help Process_ConvertBasler2Pos'' for details).');
      end

    otherwise,
      error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help Process_ConvertBasler2Pos'' for details).']);
  end
end

    if ~exist([fbasename '.led'])
%         for thresh = [.05 .15 .3 .7 .9 1.5 5 10]
            thresh = .3;
        Process_DetectLED(fbasename,thresh);
%         end
    end
    pos = load([fbasename '.led']);

    fid = fopen(syncDatFile);
    dat = fread(fid,[syncNbCh inf],'uint16=>uint16');
    dat = dat(syncChan,:);

    % the line below does not work correctly with Intan analogin.dat files
%     dat = bz_LoadBinary(syncDatFile,'nchannels',syncNbCh,'channels',syncChan);

    t = (0:length(dat)-1)'/syncSampFq;

    %It's a pull-off, trigger is toward 0
%     dat = double(fastrms(fastrms(fastrms(dat,10),50),100)<500);
	dat = uint16(smooth(single(dat)))<1000;

% if bad camera pulses, use below
%     dat = smooth(dat,100);
%     dat = dat<0;

    dPos = find(diff(dat)==1);
    dNeg = find(diff(dat)==-1);

    if length(dPos) == length(dNeg)+1
        dPos = dPos(1:end-1);
    elseif length(dPos) > length(dNeg)+1 || length(dPos) < length(dNeg)
         keyboard
    end

    %Frame timing is the middle of shuter opening
    frameT = (t(dPos)+t(dNeg))/2;

    %The camera keeps on recording a few frames after software stopped
    %recording. So we skipthe last frames of the TTL
    if length(frameT)<size(pos,1);
        warning('Too many video frames!')
        keyboad
    elseif length(frameT)>size(pos,1);
        frameT = frameT(1:size(pos,1));
    end

    %We now interpolate the data at 60 Hz (or sampling fqcy specified in
    %arguments)
    recDuration = length(dat)/syncSampFq;

    timestamps = (0:1/posSampFq:recDuration-1/posSampFq)';
    pos(pos==-1) = NaN;
    newPos = interp1(frameT,pos,timestamps);

    behavior.positions.x = nanmean(pos(:,[2 4])');
    behavior.positions.y = nanmean(pos(:,[3 5])');
    behavior.position.z = [];
    dx = pos(:,3) - pos(:,5);
    dy = pos(:,2) - pos(:,4);
% 	ang = atan2(dy,dx)-angOffset;
% 	ang = mod(ang,2*pi);
    [orientation rho] = cart2pol(pos(:,3)-pos(:,5),pos(:,2)-pos(:,4));
    behavior.orientations.yaw = orientation;
    behavior.orientation.pitch = [];
    behavior.orientation.roll = [];
    behavior.rotationType = 'euler';
    behavior.description = '';
    behavior.events = [];

    warning('come up with a better head dir calculation...')
error('this function is unfinished and may not comform to the new data formatting standards...')
    behavior.timestamps = pos(:,1);
%     dlmwrite([fbasename '.pos'],[timestamps newPos],'delimiter','\t', 'precision', 32);
    save([fbasename '.behavior.mat'],'behavior');
end


%                                              x = frameit(lab,frmq,frms,K)
% FRAMEIT
%
% **********  INTERNAL FUNCTION OF SEDUMI **********
%
% See also sedumi

function x = frameit(lab,frmq,frms,K)
%
% This file is part of SeDuMi 1.1 by Imre Polik and Oleksandr Romanko
% Copyright (C) 2005 McMaster University, Hamilton, CANADA  (since 1.1)
%
% Copyright (C) 2001 Jos F. Sturm (up to 1.05R5)
%   Dept. Econometrics & O.R., Tilburg University, the Netherlands.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% Affiliation SeDuMi 1.03 and 1.04Beta (2000):
%   Dept. Quantitative Economics, Maastricht University, the Netherlands.
%
% Affiliations up to SeDuMi 1.02 (AUG1998):
%   CRL, McMaster University, Canada.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% 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.,  51 Franklin Street, Fifth Floor, Boston, MA
% 02110-1301, USA
%
x = [lab(1:K.l); qframeit(lab,frmq,K); psdframeit(lab,frms,K)];


function [view ROI] = createROIFromRange(view, range, varargin)
% createROIFromRange
%   Generates an ROI from a range of values given by the user.  Optional
%   ability to generate histogram with feedback re: data within range.
%
% Usage:
%   [view ROI] = createROIFromRange(view, range, varargin)
%
%   View:
%       Volume/gray struct.
%
%   Range:
%       String encoding desired values.  If empty, will prompt for string.
%           FORMAT: OPAREN MINNUMBER , MAXNUMBER CPAREN
%               OPAREN - ( for exlusive, [ for inclusive
%               MINNUMBER - int/double of min, empty for no min
%               MAXNUMBER - int/double of max, empty for no max
%               CPAREN - ) for exclusive, ] for inclusive
%
%           Examples:
%               (3, 4] - from 3 exclusive to 4 inclusive
%               [2,) - from 2 inclusive to max
%               [,-1] - from min to -1 inclusive
%
%               Note:
%                   inclusive/exclusive does not effect empty nums (always
%                   treated as 'inclusive' on the min/max value)
%
%   Varargin Options:
%       'showhist' - Display histogram of values in range (true/false)
%           * DEFAULT false
%       'addflag' - Add ROI to view
%           * DEFAULT true
%       'roiname' - String for new name of ROI
%           * DEFAULT named by input range string
%
% Output:
%   View:
%       Volume/gray struct with ROI added
%
%   ROI:
%       ROI struct
%
% [renobowen@gmail.com 2010]
%
    if (isempty(view.map))
        ROI = [];
        error('No parameter map loaded.');
        return;
    end

    if (isempty(range))
        range = inputdlg('Enter range (see help CreateROIFromRange for instructions):',...
            'Enter Range', 1, {'[,]'});
        range = range{1};
    end

    [isOpenInclusive num1 num2 isCloseInclusive] = ParseRange(range);
    if (isempty(isOpenInclusive))
        ROI = [];
        return;
    end

    curScan = view.curScan;

    % Defaults
    showHist = false;
    addFlag = true;
    roiname = [];
    for i = 1:2:length(varargin)
        switch lower(varargin{i})
            case {'showhist'}
                showHist = varargin{i + 1};
            case {'addflag'}
                addFlag = varargin{i + 1};
            case {'roiname'}
                roiname = varargin{i + 1};
            otherwise
                fprintf(1, 'Unrecognized option: ''%s''', varargin{i});
        end
    end

    if (isempty(num1)), num1 = min(view.map{curScan}); isOpenInclusive = 1; end
    if (isempty(num2)), num2 = max(view.map{curScan}); isCloseInclusive = 1; end

    if (isOpenInclusive)
        openInds = find(view.map{curScan} >= num1);
    else
        openInds = find(view.map{curScan} > num1);
    end

    if (isCloseInclusive)
        closeInds = find(view.map{curScan} <= num2);
    else
        closeInds = find(view.map{curScan} < num2);
    end

    inds = intersect(openInds, closeInds);

    coords = view.coords(:, inds);

    ROI.coords = coords;
    ROI.color = 'w';
    if isempty(roiname)
        ROI.name = sprintf('range%s',range);
    else
        ROI.name = roiname;
    end
    ROI.viewType = view.viewType;

    if (addFlag), view = addROI(view, ROI); view.ui.showROIs = -1; end
    if (showHist), ShowRangeHistogram(view.map{curScan}(inds)); end
end

function [isOpenInclusive num1 num2 isCloseInclusive] = ParseRange(range)
% [isOpenInclusive num1 num2 isCloseInclusive] = parseRange(range)
%   Parse a range statement using regular expressions, returning properly
%   digested tokens to be used in selecting the values.
%
    isCloseInclusive = 0;
    num1 = 0; num2 = 0;

    % Regular expressions to parse range
    number = '((-)?(\d)+(\.(\d)+)?)';
    optNumber = [number '?'];
    openParen = '(\(|\[)';
    closeParen = '(\)|\])';
    comma = '(\,)';
    whitespace = '((\s)*)';
    rangeExp = ['(?<openParen>' openParen ')' whitespace '(?<num1>' optNumber ')' ...
        whitespace comma whitespace '(?<num2>' optNumber ')' whitespace '(?<closeParen>' closeParen ')'];
    result = regexp(range, rangeExp, 'names');

    if (isempty(result))
        isOpenInclusive = [];
        error('Malformed range input, please see the following help text for instructions.');
        return;
    end

    isOpenInclusive = strcmp(result.openParen, '[');
    isCloseInclusive = strcmp(result.closeParen, ']');
    num1 = str2num(result.num1);
    num2 = str2num(result.num2);

end

function ShowRangeHistogram(data)
    h = figure;
    hist(data);
    axes = get(h, 'CurrentAxes');

    yLim = get(axes, 'YLim');
    yRange = yLim(2) - yLim(1);
    yPos = [(yLim(2) - yRange * .05), (yLim(2) - yRange * .1)];

    xLim = get(axes, 'XLim');
    xRange = xLim(2) - xLim(1);
    xPos = ones(1, 2) * (xLim(1) + xRange * .05);

    text(xPos(1), yPos(1), ['min: ' num2str(min(data))]);
    text(xPos(2), yPos(2), ['max: ' num2str(max(data))]);
end


function dlx = mat2dl_complex(x)
% Convert x into a particular data structure to store complex numbers
%
% function dlx = mat2dl_complex(x)
%
% The iput x can be defined recursively by arrays, structs and cells. Each
% part of x should contain complex numbers. The function converts each
% part of x into a struct containing dlarrays with fields real and imag
% which indicate the real and imaginary part of the stored complex numbers.
%
% See also: dl2mat_complex, manoptADhelp

% This file is part of Manopt: www.manopt.org.
% Original author: Xiaowen Jiang, July. 31, 2021.
% Contributors: Nicolas Boumal
% Change log:

    if ~isstruct(x) && ~iscell(x) && ~isnumeric(x)
        up = MException('manopt:autodiff:mat2dl_complex', ...
                    'mat2dl_complex should only accept a struct, a cell or a numeric array');
        throw(up);
    end

    % recursively convert each part of x into a particular struct
    if isstruct(x)
        dlx = mat2dl_struct(x);
    elseif iscell(x)
        dlx = mat2dl_cell(x);
    else
        xreal = real(x);
        ximag = imag(x);
        dlx.real = dlarray(xreal);
        dlx.imag = dlarray(ximag);
    end

    % convert x into a particular dlarray struct if x is a struct
    function dlx = mat2dl_struct(x)
        elems = fieldnames(x);
        nelems = numel(elems);
        for ii = 1:nelems
            if isstruct(x.(elems{ii}))
                dlx.(elems{ii}) = mat2dl_struct(x.(elems{ii}));
            elseif iscell(x.(elems{ii}))
                dlx.(elems{ii}) = mat2dl_cell(x.(elems{ii}));
            else
                dlx.(elems{ii}) = struct();
                xreal = real(x.(elems{ii}));
                ximag = imag(x.(elems{ii}));
                dlx.(elems{ii}).real = dlarray(xreal);
                dlx.(elems{ii}).imag = dlarray(ximag);
            end
        end
    end

    % convert x into a particular dlarray struct if x is a cell
    function dlx = mat2dl_cell(x)
        ncell = length(x);
        for ii = 1:ncell
            if isstruct(x{ii})
                dlx{ii} = mat2dl_struct(x{ii});
            elseif iscell(x{ii})
                dlx{ii} = mat2dl_cell(x{ii});
            else
                xreal = real(x{ii});
                ximag = imag(x{ii});
                dlx{ii} = struct();
                dlx{ii}.real = dlarray(xreal);
                dlx{ii}.imag = dlarray(ximag);
            end
        end
    end
end


% @Author: amishkin
% @Date:   2018-07-10T13:36:34-07:00
% @Email:  amishkin@cs.ubc.ca
% @Last modified by:   aaronmishkin
% @Last modified time: 2018-07-25T13:18:48-07:00

% #################################################
% ############# Reproduce Figure 2(c) #############
% #################################################

% Load the dataset with a fixed seed.
addpath(genpath('.'))

output_dir = './breast_cancer_experiment_data'
mkdir(output_dir)

dataset_name = 'breast_cancer_scale';
[y, X, y_te, X_te] = get_data_log_reg(dataset_name, 1);
[N,D] = size(X);

% Set initial conditions. These will be the same for all methods and restarts.
mu_start = zeros(D,1);
s = 1.*ones(D,1);
sigma_start = diag(1./s);

% Use the same split of the dataset for each random restart.
random_split = 0;

% Run MF_Exact.
method = 'mf_exact'
num_restarts = 1;

% List batch sizes and epochs for each batch size.
% In the case of mf-exact (which is a batch method), the number of epochs controls the number of function
% evaluations L-BFGS is allowed.
epoch_list = [500];
% M_list does not matter for mf-exact because it is a batch method.
M_list = [1]

run_experiment(dataset_name, method, M_list, epoch_list, 0, 0, 0, 0, num_restarts, mu_start, sigma_start, random_split, output_dir)

% Run Vadam with different minibatch sizes:
method = 'Vadam'

% Define the experiment parameters:
num_samples = 1
beta = 0.01;
alpha = 0.01;
decay_rate = 0.55   % controls the rate at which alpha and beta decay during training.

num_restarts = 20;

%  List batch sizes and epochs for each batch size.
M_list = [1,8,16,32,64];
epoch_list = [10000, 10000, 10000, 10000, 10000];

run_experiment(dataset_name, method, M_list, epoch_list, alpha, beta, decay_rate, num_samples, num_restarts, mu_start, sigma_start, random_split, output_dir);

% Run VOGN with a minibatch size of one:
method = 'VOGN'
num_samples = 1
beta = 0.0005;
alpha = 0.0005;
decay_rate = 0;

num_restarts = 20;

%  List batch sizes and epochs for each batch size.
M_list = [1];
epoch_list = [2000];

run_experiment(dataset_name, method, M_list, epoch_list, alpha, beta, decay_rate, num_samples, num_restarts, mu_start, sigma_start, random_split, output_dir);

% generate figure 2(c) using the data from this experiment:
make_fig_two_c


clear;
load('../general/ccnf_patches_0.25_general.mat', 'centers', 'visiIndex', 'normalisationOptions');

mirrorInds = [1,17;2,16;3,15;4,14;5,13;6,12;7,11;8,10;18,27;19,26;20,25;21,24;22,23;...
  32,36;33,35;37,46;38,45;39,44;40,43;41,48;42,47;49,55;50,54;51,53;60,56;59,57;...
  61,65;62,64;68,66];

% For mirroring
frontalView = 1;
profileViewInds = [2,3,4];

% Grab all related experts and mirror them appropriatelly, just need to
% mirror the first layer

non_mirrored = mirrorInds(:,1);
normalisationOptions = rmfield(normalisationOptions, 'ccnf_ratio');
normalisationOptions.dccnf = true;

n_landmarks = size(visiIndex, 2);
n_views = size(visiIndex, 1);

patch_experts.correlations = zeros(n_views, n_landmarks);
patch_experts.rms_errors = zeros(n_views, n_landmarks);
patch_experts.types = {'reg'};
patch_experts.patch_experts = cell(n_views, n_landmarks);

scales = {'0.25', '0.35', '0.50', '1.00'};

root = 'D:/deep_experts/2017-02-02/rmses/';

for s=scales

    for c=1:n_views

        if(c == frontalView || sum(profileViewInds==c)> 0)

            for i=1:n_landmarks

                if(visiIndex(c,i))
                    mirror = false;
                    % Find the relevant file
                    if(c == frontalView)
                        rel_file = sprintf([root, 'MultiGeneral_arch4general_%s_frontal_%d_512.mat'], s{1}, i);
                    else
                        rel_file = sprintf([root, 'MultiGeneral_arch4general_%s_profile%d_%d_512.mat'], s{1}, c-1, i);
                    end
                    if(exist(rel_file, 'file'))
                       load(rel_file);
                    else
                       rel_id = mirrorInds(mirrorInds(:,2)==i,1);
                       if(isempty(rel_id))
                           rel_id = mirrorInds(mirrorInds(:,1)==i,2);
                       end
                       if(~visiIndex(c, rel_id))
                           continue;
                       end
                       if(c == frontalView)
                           rel_file = sprintf([root, 'MultiGeneral_arch4general_%s_frontal_%d_512.mat'], s{1}, rel_id);

                           mirror = true;
                           load(rel_file);
                       end
                    end
                    patch_experts.correlations(c, i) = correlation_2;
                    patch_experts.rms_errors(c, i) = rmse;

                    if(~mirror)
                        patch_experts.patch_experts{c, i} = weights;
                    else
                        flips = fliplr(reshape([1:121]', 11, 11));
                        weights_flipped = weights;
                        weights_flipped{1}(2:end,:) = weights{1}(flips+1,:);
                        patch_experts.patch_experts{c,i} = weights_flipped;
                    end
                end

            end
        else

            swap_id = find(centers(:,2) == -centers(c,2));

            corr_T = patch_experts.correlations(swap_id,:);
            % Appending a mirror view instead, based on the profile view
            corr_T  = swap(corr_T, mirrorInds(:,1), mirrorInds(:,2));
            patch_experts.correlations(c,:) = corr_T;

            rmsT = patch_experts.rms_errors(swap_id,:);
            rmsT = swap(rmsT, mirrorInds(:,1), mirrorInds(:,2));
            patch_experts.rms_errors(c,:) = rmsT;

            patchExpertMirror = patch_experts.patch_experts(swap_id,:);
            patchExpertMirrorT1 = patchExpertMirror(1,mirrorInds(:,1),:);
            patchExpertMirrorT2 = patchExpertMirror(1,mirrorInds(:,2),:);
            patchExpertMirror(1,mirrorInds(:,2),:) = patchExpertMirrorT1;
            patchExpertMirror(1,mirrorInds(:,1),:) = patchExpertMirrorT2;

            % To flip a patch expert it
            for p=1:size(patchExpertMirror,2)
                if(visiIndex(c, p))
                    weights = patchExpertMirror{p};
                    flips = fliplr(reshape([1:121]', 11, 11));
                    weights_flipped = weights;
                    weights_flipped{1}(2:end,:) = weights{1}(flips+1,:);
                    patch_experts.patch_experts{c,p} = weights_flipped;
                end
            end

        end
    end
    trainingScale = str2num(s{1});
    save(['cen_patches_', s{1} '_general.mat'], 'trainingScale', 'centers', 'visiIndex', 'patch_experts', 'normalisationOptions');

end


function Control = setupController(P)

if P.Sim.springDoublePendulum

    Control.legOne.nomPos = 1; %(m)
    Control.legOne.Kp = 35;

    Control.legTwo.nomPos = 1; %(m)
    Control.legTwo.Kp = 35;

    %Then set everything to zero except for the proportional gains on the
    %leg length actuators. This turns them both into springs, which makes
    %the system conserve energy. This is a handle error check.

    %The Foot One actuator operates on the absolute angle of leg one
    Control.footOne.nomPos = 0;
    Control.footOne.nomVel = 0;
    Control.footOne.Kp = 0;
    Control.footOne.Kd = 0;

    %The Foot Two actuator operates on the absolute angle of leg two
    Control.footTwo.nomPos = 0;
    Control.footTwo.nomVel = 0;
    Control.footTwo.Kp = 0;
    Control.footTwo.Kd = 0;

    %The Leg One actuator operates on the length of leg one
    Control.legOne.nomVel = 0;
     Control.legOne.Kd = 0;

    %The Leg Two actuator operates on the length of leg two
    Control.legTwo.nomVel = 0;
    Control.legTwo.Kd = 0;

    %The Hip actuator operates on the angle between the legs: th2-th1
    Control.hip.nomPos = 0;
    Control.hip.nomVel = 0;
    Control.hip.Kp = 0;
    Control.hip.Kd = 0;
else
    %Allow system to be fully controlled. This will not necessarily
    %conserve energy.

    %The Foot One actuator operates on the absolute angle of leg one
    Control.footOne.nomPos = 0;
    Control.footOne.nomVel = 0;
    Control.footOne.Kp = 0;
    Control.footOne.Kd = 0;

    %The Foot Two actuator operates on the absolute angle of leg two
    Control.footTwo.nomPos = 0;
    Control.footTwo.nomVel = 0;
    Control.footTwo.Kp = 0;
    Control.footTwo.Kd = 0;

    %The Leg One actuator operates on the length of leg one
    Control.legOne.nomPos = 1; %(m)
    Control.legOne.nomVel = 0;
    Control.legOne.Kp = 100;
    Control.legOne.Kd = 50;

    %The Leg Two actuator operates on the length of leg two
    Control.legTwo.nomPos = 1; %(m)
    Control.legTwo.nomVel = 0;
    Control.legTwo.Kp = 100;
    Control.legTwo.Kd = 500;

    %The Hip actuator operates on the angle between the legs: th2-th1
    Control.hip.nomPos = 0;
    Control.hip.nomVel = 0;
    Control.hip.Kp = 0;
    Control.hip.Kd = 0;
end

end


function bdDistWeight = sc_get_bdDistWeight(mask)

[D,IDX] = bwdist(~mask);

end


function dres = build_graph(dres)
ov_thresh = 0.3;  %original = 0.5

for fr = 2:max(dres.fr)
  f1 = find(dres.fr == fr);     %% indices for detections on this frame
  f2 = find(dres.fr == fr-1);   %% indices for detections on the previous frame
  if(isfield(dres, 'ft'))
      feat1 = dres.ft(f1,:);
      feat2 = dres.ft(f2,:);
  end
  for i = 1:length(f1)
    ovs1  = calc_overlap(dres, f1(i), dres, f2);
    if(isfield(dres, 'ft'))
        dist = pdist2(feat1(i,:),feat2);
        inds1 = find(ovs1 > ov_thresh & dist < 5);                       %% find overlapping bounding boxes.
    else
        inds1 = find(ovs1 > ov_thresh);
    end

    ratio1 = dres.h(f1(i))./dres.h(f2(inds1));
    inds2  = (min(ratio1, 1./ratio1) > 0.8);          %% we ignore transitions with large change in the size of bounding boxes.

    dres.nei(f1(i),1).inds  = f2(inds1(inds2))';      %% each detction window will have a list of indices pointing to its neighbors in the previous frame.
  end
end


function y=sqr(x)
y = x*x;


function [L_BG]=uiThreshErode(varargin)

% function [L_BG]=uiThreshErode(M,thresholdInitial,blurKernelSize,groupCropOption,inConvexHull)

%% Parse input

thresholdInitial=[];
blurKernelSize=[];
groupCropOpt=[];
inConvexHullOpt=[];
switch nargin
    case 1
        M=varargin{1};
    case 2
        M=varargin{1};
        thresholdInitial=varargin{2};
    case 3
        M=varargin{1};
        thresholdInitial=varargin{2};
        blurKernelSize=varargin{3};
    case 4
        M=varargin{1};
        thresholdInitial=varargin{2};
        blurKernelSize=varargin{3};
        groupCropOpt=varargin{4};
    case 5
        M=varargin{1};
        thresholdInitial=varargin{2};
        blurKernelSize=varargin{3};
        groupCropOpt=varargin{4};
        inConvexHullOpt=varargin{5};
end

%Set defaults
if isempty(thresholdInitial)
     thresholdInitial=0.1;
end

%Quick fix for low thresholds
if thresholdInitial<0.01
    thresholdInitial=0.01;
end

if isempty(blurKernelSize)
     blurKernelSize=ndims(M);
end

if isempty(groupCropOpt)
     groupCropOpt=0;
end

if isempty(inConvexHullOpt)
     inConvexHullOpt=0;
end
%% PLOT SETTINGS

fontSize=10;
cMap=gray(250);
falpha=1;

logicVoxels=false(size(M));
logicVoxels(round(size(M,1)/2),:,:)=1;
logicVoxels(:,round(size(M,2)/2),:)=1;
logicVoxels(:,:,round(size(M,3)/2))=1;

%%
M_original=M;
M=double(M);

%% Normalizing the image data
M=dataNorm(M,1);

%% APPLY PRE-BLURRING
if blurKernelSize>0
    %Defining erosion/dilation kernel
    k=blurKernelSize;
    p=k-round(k./2);

    hb=gauss_kernel(k,ndims(M),1.5,'width'); %Gaussian kernel

    M_rep=zeros(size(M)+(2.*p));
    M_rep(p+(1:size(M,1)),p+(1:size(M,2)),p+(1:size(M,3)))=M;
    M = convn(M_rep,hb,'valid');
end

%% Defining erosion/dilation kernel
k=3;
hg=ones(k,k,k);
p=k-round(k./2);

%% Start loop
done=0;
while done==0
    %Get initial threshold level
    T_threshold=thresholdInitial; %default start value
    done=0;
    qc=1;
    runMode=1;
    while done==0

        switch runMode
            case 1 %Determining threshold
                L_BG=M>T_threshold;
            case 2 %Setting erosion/dilation
                %"Blurring current mask"
                L_BG_rep=zeros(size(M)+(2.*p));
                L_BG_rep(p+(1:size(M,1)),p+(1:size(M,2)),p+(1:size(M,3)))=L_BG;
                L_BG_blur = convn(double(L_BG_rep),hg,'valid');
        end

        if qc==1 %Plot figure on first iteration

            %Cropped image
            [Fs,Vs,Cs]=ind2patch(logicVoxels&L_BG,M_original,'v');

            hf1=cFigure;
            title(['Threshold is ',num2str(T_threshold),'*mean, press up to increase or down to decrease (by 10%), press space to keep and continue'],'FontSize',fontSize);
            hold on; xlabel('X-J','FontSize',fontSize);ylabel('Y-I','FontSize',fontSize);zlabel('Z-K','FontSize',fontSize);
            hs=patch('Faces',Fs,'Vertices',Vs,'EdgeColor','none', 'CData',Cs,'FaceColor','flat');
            set(hs,'FaceAlpha',falpha); hold on; grid on;  view(3); axis equal; axis tight; axis vis3d;  colormap(cMap); colorbar;
            set(gca,'FontSize',fontSize);
            drawnow;

        else %redefine patch data
            delete(hs); %remove patch data from figure

            %redefine patch data for the cropped image
            [Fs,Vs,Cs]=ind2patch(logicVoxels&L_BG,M_original,'v');

            %patch again
            if runMode==1
                title(['Threshold is ',num2str(T_threshold),'*mean, press up to increase or down to decrease (by 10%), press space to keep and continue'],'FontSize',fontSize);
            else
                title('Current cropping press up/down to dilate/erode, WARNING EROSION MAY REMOVE ENTIRE SLICES','FontSize',fontSize);
            end

            hs=patch('Faces',Fs,'Vertices',Vs,'EdgeColor','none', 'CData',Cs,'FaceColor','flat');
            set(hs,'FaceAlpha',falpha); hold on; grid on;  view(3); axis equal; axis tight; axis vis3d;  colormap(cMap); colorbar;
            set(gca,'FontSize',fontSize);
            drawnow;
        end

        [~,~,b]=qginput(1);
        switch b
            case 30 %  up arrow key => increase threshold by 10% OR dilate
                if runMode==1
                    T_threshold=T_threshold.*1.1;
                else
                    L_BG=(L_BG_blur>0); %blurred boundary elements that increased due to blur are now set to 1 as well so added to mask
                end
            case 31 %down arrow key => decrease threshold by 10% OR erode
                if runMode==1
                    T_threshold=T_threshold.*0.9;
                else
                    L_BG=(L_BG_blur==sum(hg(:))); %blurred boundary elements that decreased due to blur are now set to 0 as well so removed from mask
                end
            case 32 %spacebar key => confirms current threshold result, exits while loop
                if runMode==1
                    runMode=2;
                else
                    done=1;
                end
        end
        qc=qc+1;
    end

    %% GROUPING BASED CROPPING
    if groupCropOpt==1

        GROUP_STRUCT = bwconncomp(L_BG,6);
        IMAGE_OBJECTS=GROUP_STRUCT.PixelIdxList;

        %Filtering out groups that are too small
        group_sizes = cell2mat(cellfun(@(x) max(size(x)), IMAGE_OBJECTS,'UniformOutput',0)'); %get group sizes
        [~,ind_max]=max(group_sizes); %Index of largest group
        IND_OBJECT=IMAGE_OBJECTS{ind_max}; %indices of voxels for largest group

        %Redefining background logic using group
        L_BG=false(size(L_BG));
        L_BG(IND_OBJECT)=1;

        %Plotting the result
        delete(hs); %remove patch data from figure

        %redefine patch data for the cropped image
        [Fs,Vs,Cs]=ind2patch(logicVoxels&L_BG,M_original,'v');

        title('Grouping result','FontSize',fontSize);

        hs=patch('Faces',Fs,'Vertices',Vs,'EdgeColor','none', 'CData',Cs,'FaceColor','flat');
        set(hs,'FaceAlpha',falpha); hold on; grid on;  view(3); axis equal; axis tight; axis vis3d;  colormap(cMap);
        set(gca,'FontSize',fontSize);
        drawnow;
    end

    %% Convex hull based filling
    if inConvexHullOpt==1
        [I,J]=ndgrid(1:1:size(M,1),1:1:size(M,2));
        for q=1:1:size(M,3);
            l_bg=L_BG(:,:,q);
            if nnz(l_bg)>0
                if nnz(l_bg)>3
                    try
                        P=[I(l_bg) J(l_bg)];
                        K = convhull(P(:,1),P(:,2));
                        indNot=find(~l_bg);
                        [Lp,~] = inpolygon(I(indNot),J(indNot),P(K,1),P(K,2));
                        indAdd=indNot(Lp);
                        L=false(size(M,1),size(M,2));
                        L(indAdd)=1;
                        L_BG(:,:,q)=L_BG(:,:,q) | L;
                    end
                end
            else
               L_BG(:,:,q)=0;
            end
        end

        title('Convexhull fill result','FontSize',fontSize);
        delete(hs); %remove patch data from figure
        %redefine patch data for the cropped image
        [Fs,Vs,Cs]=ind2patch(logicVoxels&L_BG,M_original,'v');

        hs=patch('Faces',Fs,'Vertices',Vs,'EdgeColor','none', 'CData',Cs,'FaceColor','flat');
        set(hs,'FaceAlpha',falpha); hold on; grid on;  view(3); axis equal; axis tight; axis vis3d;  colormap(cMap);
        set(gca,'FontSize',fontSize);
        drawnow;
    end

    %%
    Q = questdlg('Would you like to keep this result?','Keep result?','YES','NO','YES');
    switch Q
        case 'YES'
            done=1;
        case 'NO'
            done=0;
    end
    close(hf1)

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 [returnVal, txtReturnVal] = lvmTwoDPlot(X, lbl, symbol, fhandle)

% LVMTWODPLOT Helper function for plotting the labels in 2-D.
% FORMAT
% DESC helper function for plotting an embedding in 2-D with symbols.
% ARG X : the data to plot.
% ARG lbl : the labels of the data point.
% ARG symbol : the symbols to use for the different labels.
%
% SEEALSO : lvmScatterPlot, lvmVisualise
%
% COPYRIGHT : Neil D. Lawrence, 2004, 2005, 2006, 2008

% MLTOOLS

if nargin < 2
    lbl = [];
end
if(strcmp(lbl, 'connect'))
    connect = true;
    lbl = [];
else
    connect = false;
end

if iscell(lbl)
    lblStr = lbl{2};
    lbl = lbl{1};
    labelsString = true;
else
    labelsString = false;
end

if nargin < 3 || isempty(symbol)
    if isempty(lbl)
        symbol = getSymbols(1);
    else
        symbol = getSymbols(size(lbl,2));
    end
end
if nargin > 3 && ~isempty(fhandle)
    axisHand = fhandle;
else
    axisHand = gca;
end
returnVal = [];
textReturnVal = [];
nextPlot = get(axisHand, 'nextplot');
for i = 1:size(X, 1)
    if i == 2
        set(axisHand, 'nextplot', 'add');
    end
    if ~isempty(lbl)
        labelNo = find(lbl(i, :));
    else
        labelNo = 1;
    end
    %try
    returnVal = [returnVal; plot(X(i, 1), X(i, 2), symbol{labelNo})];
    if labelsString
        textReturnVal = [textReturnVal; text(X(i, 1), X(i, 2), ['   ' lblStr{i}])];
    end
    if connect
        if i>1
            line([X(i-1, 1) X(i, 1)], [X(i-1, 2) X(i, 2)]);
        end
    end
    %catch
    % if strcmp(lasterr, 'Index exceeds matrix dimensions.')
    %  error(['Only ' num2str(length(symbol)) ' labels supported (it''s easy to add more!)'])
    % end
    %end
end
set(axisHand, 'nextplot', nextPlot);
set(returnVal, 'markersize', 10);
set(returnVal, 'linewidth', 2);
end


x0=2;
[x,y]=fminsearch(@fun5,x0)


function [gcX, gcY, gcZ] = get_gc_initial_pos()
%     NeuroSLAM System Copyright (C) 2018-2019
%     NeuroSLAM: A Brain inspired SLAM System for 3D Environments
%
%     Fangwen Yu (www.yufangwen.com), Jianga Shang, Youjian Hu, Michael Milford(www.michaelmilford.com)
%
%     The NeuroSLAM V1.0 (MATLAB) was developed based on the OpenRatSLAM (David et al. 2013).
%     The RatSLAM V0.3 (MATLAB) developed by David Ball, Michael Milford and Gordon Wyeth in 2008.
%
%     Reference:
%     Ball, David, Scott Heath, Janet Wiles, Gordon Wyeth, Peter Corke, and Michael Milford.
%     "OpenRatSLAM: an open source brain-based SLAM system." Autonomous Robots 34, no. 3 (2013): 149-176.
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.

    % set the initial position in the grid cell network
    global GC_X_DIM;
    global GC_Y_DIM;
    global GC_Z_DIM;

    gcX = floor(GC_X_DIM / 2);  % in 1:36
    gcY = floor(GC_Y_DIM / 2);  % in 1:36
    gcZ = floor(GC_Z_DIM / 2);  % in 1:36
%     gcX = 1;  % in 1:36
%     gcY = 1;  % in 1:36
%     gcZ = 1;  % in 1:36
end


function [Y,x,DCM] = spm_dcm_generate(syn_model,SNR,show_graphics)
% Generate synthetic data from a DCM specification
% FORMAT [Y,x,DCM] = spm_dcm_generate(syn_model,SNR)
%
% syn_model     - Name of synthetic DCM file
% SNR           - Signal to noise ratio [default: 1]
% show_graphics - Whether to plot each timeseries [default: true]
%
% This routine will update the DCM.Y field as follows:
%           Y.y    - synthetic BOLD data
%           Y.secs - overall number of seconds
%           Y.Q    - components of error precision
%
% and will enter neuronal activity (first hidden var in each region) into
% DCM.x
%
% Y           - Simulated (Noisy) BOLD data
% x           - Simulated neuronal activity (first hidden variable in each region)
% DCM         - Full generative model
%
%__________________________________________________________________________
% Copyright (C) 2002-2014 Wellcome Trust Centre for Neuroimaging

% Will Penny & Klaas Enno Stephan
% $Id: spm_dcm_generate.m 6716 2016-02-08 18:21:37Z peter $

% Check parameters and load specified DCM
%--------------------------------------------------------------------------
if isstruct(syn_model)
    DCM       = syn_model;
    syn_model = ['DCM-' date '.mat'];
else
    load(syn_model)
end
if nargin < 2 || isempty(SNR)
    SNR = 1;
end
if nargin < 3 || isempty(show_graphics)
    show_graphics = true;
end

% Unpack
%--------------------------------------------------------------------------
U     = DCM.U;        % inputs
v     = DCM.v;        % number of scans
n     = DCM.n;        % number of regions
m     = size(U.u,2);  % number of inputs

% Check whether the model is stable by examining the eigenvalue
% spectrum for the intrinsic connectivity matrix
%--------------------------------------------------------------------------
[is_stable, eigval] = spm_dcm_check_stability(DCM);
if ~is_stable
    fprintf('Modelled system is potentially unstable:\n');
    fprintf('Lyapunov exponent of combined connectivity matrix is %f\n',max(eigval));
    fprintf('Check the output to ensure that values are in a normal range.\n')
end

% check whether this is a nonlinear DCM
%--------------------------------------------------------------------------
if ~isfield(DCM,'d') || isempty(DCM.d)
    DCM.d = zeros(n,n,0);
    M.IS  = 'spm_int';
else
    M.IS  = 'spm_int_D';
end

% priors
%--------------------------------------------------------------------------
[pE,pC] = spm_dcm_fmri_priors(DCM.a,DCM.b,DCM.c,DCM.d);

% complete model specification
%--------------------------------------------------------------------------
M.f     = 'spm_fx_fmri';
M.g     = 'spm_gx_state_fmri';
M.x     = sparse(n,5);
M.pE    = pE;
M.pC    = pC;
M.m     = size(U.u,2);
M.n     = size(M.x(:),1);
M.l     = size(M.x,1)*2; % twice as many "outputs" (as hemo and neuronal)
M.N     = 32;
M.dt    = 16/M.N;
M.ns    = v;

% fMRI slice time sampling
%--------------------------------------------------------------------------
try, M.delays = DCM.delays; end
try, M.TE     = DCM.TE;     end

% twice as many "outputs" (hemo and neuronal) - need this to coerce spm_int
%--------------------------------------------------------------------------
M.delays = [M.delays; M.delays];

% Integrate and compute hemodynamic response at v sample points
%--------------------------------------------------------------------------
y      = feval(M.IS,DCM.Ep,M,U);

% Compute required r: standard deviation of additive noise, for all areas
%--------------------------------------------------------------------------
if isinf(SNR)
    r = zeros(n,n);
else
    r = diag(std(y(:,1:n))/SNR);
end

% Add noise
%--------------------------------------------------------------------------
p      = 1;
a      = 1/16;
a      = [1 -a];
K      = inv(spdiags(ones(v,1)*a,-[0:p],v,v));
K      = K*sqrt(v/trace(K*K'));
z      = randn(v,n);
e      = K*z;
Y      = DCM.Y;
Y.Q    = spm_Ce(v*ones(1,n));

Y.y    = y(:,1:n) + e*r;
x      = y(:,n+1:2*n);
Y.secs = Y.dt*v;

% Save synthetic DCM
%--------------------------------------------------------------------------
DCM.Y  = Y;                                    % simulated data
DCM.y  = y(:,1:n);                             % simulated BOLD
DCM.x  = x;                                    % simulated neuronal
DCM.M  = M;                                    % model

save(syn_model, 'DCM', spm_get_defaults('mat.format'));

if spm('CmdLine') || ~show_graphics, return; end

% Display the time series generated
%--------------------------------------------------------------------------
spm_figure('GetWin','Simulated BOLD time series');
t     = Y.dt*[1:1:v];
for i = 1:n,
    subplot(n,1,i);
    plot(t,Y.y(:,i));
    title(sprintf('Region %s', Y.name{i}));
    if i<n set(gca,'XTickLabel',[]); end
end
xlabel('secs');

spm_figure('GetWin','Simulated Neuronal Activity');

t     = Y.dt*[1:1:v];
for i = 1:n,
    subplot(n,1,i);
    plot(t,x(:,i));
    title(sprintf('Region %s', Y.name{i}));
    if i<n set(gca,'XTickLabel',[]); end
end
xlabel('secs');


function [cost, grad] = getCostGrad(problem, x, storedb, key)
% Computes the cost function and the gradient at x in one call if possible.
%
% function [cost, grad] = getCostGrad(problem, x)
% function [cost, grad] = getCostGrad(problem, x, storedb)
% function [cost, grad] = getCostGrad(problem, x, storedb, key)
%
% Returns the value at x of the cost function described in the problem
% structure, as well as the gradient at x.
%
% storedb is a StoreDB object, key is the StoreDB key to point x.
%
% See also: canGetCost canGetGradient getCost getGradient

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Dec. 30, 2012.
% Contributors:
% Change log:
%
%   April 3, 2015 (NB):
%       Works with the new StoreDB class system.
%
%   Aug. 2, 2018 (NB):
%       The value of the cost function is now always cached.
%
%   Sep. 6, 2018 (NB):
%       The gradient is now also cached.

    % Allow omission of the key, and even of storedb.
    if ~exist('key', 'var')
        if ~exist('storedb', 'var')
            storedb = StoreDB();
        end
        key = storedb.getNewKey();
    end

    % Contrary to most similar functions, here, we get the store by
    % default. This is for the caching functionality described below.
    store = storedb.getWithShared(key);
    store_is_stale = false;

    % Check if the cost or gradient are readily available from the store.
    force_grad_caching = true;
    if isfield(store, 'cost__')
        cost = store.cost__;
        if force_grad_caching && isfield(store, 'grad__')
            grad = store.grad__;
            return;
        else
            grad = getGradient(problem, x, storedb, key); % caches grad
            return;
        end
    end
    % If we get here, the cost was not previously cached, but maybe the
    % gradient was?
    if force_grad_caching && isfield(store, 'grad__')
        grad = store.grad__;
        cost = getCost(problem, x, storedb, key); % this call caches cost
        return;
    end

    % Neither the cost nor the gradient were available: let's compute both.

    if isfield(problem, 'costgrad')
    %% Compute the cost/grad pair using costgrad.

        % Check whether this function wants to deal with storedb or not.
        switch nargin(problem.costgrad)
            case 1
                [cost, grad] = problem.costgrad(x);
            case 2
                [cost, grad, store] = problem.costgrad(x, store);
            case 3
                % Pass along the whole storedb (by reference), with key.
                [cost, grad] = problem.costgrad(x, storedb, key);
                store_is_stale = true;
            otherwise
                up = MException('manopt:getCostGrad:badcostgrad', ...
                    'costgrad should accept 1, 2 or 3 inputs.');
                throw(up);
        end

    else
    %% Revert to calling getCost and getGradient separately

        % The two following calls will already cache cost and grad, then
        % the caches will be overwritten at the end of this function, with
        % the same values (it is not a problem).
        cost = getCost(problem, x, storedb, key);
        grad = getGradient(problem, x, storedb, key);
        store_is_stale = true;

    end

    if store_is_stale
        store = storedb.getWithShared(key);
    end

    % Cache here.
    store.cost__ = cost;
    if force_grad_caching
        store.grad__ = grad;
    end

    storedb.setWithShared(store, key);

end


function orthogonalslicer(imaVOL, pixsize, colormaptype, minpix, maxpix)
% ORTHOGONALSLICER
%
% Orthogonalslicer creates 3 figures showing the 3 orthogonal slices
% from a scalar volume of data. Cross lines on each image represents lines of
% intersection of the appropriate plane and the two other orthogonal plane.
% By left dragging the mouse on any plane the user can explore the volume.
% Additional mouse options:
%   - the images can be zoomed and paned with middle and right mouse dragging
%   - to restore the original state (zoom and pan) double click on the image
%
% Usage:
%
%   orthogonalslicer; or orthogonalslicer(1);
%   DEMO using the MATLAB 'MRI' data set.
%
%   orthogonalslicer(2);
%   DEMO using the MATLAB 'FLOW' data set.
%
%   orthogonalslicer(VOLUME)
%       - VOLUME a 3D scalar data array
%
%   orthogonalslicer(VOLUME, PIXELSIZE)
%       - PIXELSIZE describes the size(aspect) of the pixel in 3D /default = [1 1 1]/
%
%   orthogonalslicer(VOLUME, PIXELSIZE, COLORMAPTYPE)
%       - COLORMAPTYPE selects the colormap to be used /default = jet/
%
%   orthogonalslicer(VOLUME, PIXELSIZE, COLORMAPTYPE,MINPIX,MAXPIX))
%       - MINPIX,MAXPIX normalizes the values in VOLUME to the range
%       specified (same as IMAGESC does)
%

%
% University of Debrecen, PET Center/LB 2004

if nargin == 0
    mridata = load('mri');
    imaVOL = squeeze(mridata.D);
    minpix = 0; maxpix = max(imaVOL(:));
    pixsize = [1 1 1/0.4];
    colormaptype = bone(256);
elseif nargin == 1
    if sum(size(imaVOL)) == 2
        if imaVOL == 1
            mridata = load('mri');
            imaVOL = squeeze(mridata.D);
            minpix = 0; maxpix = max(imaVOL(:));
            pixsize = [1 1 1/0.4];
            colormaptype = bone(256);
        elseif imaVOL == 2
            imaVOL = permute(flow(50),[1 3 2]);
            pixsize = [1 1 1];
            colormaptype = 'jet';
            minpix = min(imaVOL(:)); maxpix = max(imaVOL(:));
        end
        mia_Start3dCursor(imaVOL, pixsize, colormaptype, minpix, maxpix);
        return;
    end
    pixsize = [1 1 1];
    colormaptype = jet;
    minpix = min(imaVOL(:)); maxpix = max(imaVOL(:));
elseif nargin == 2
    colormaptype = jet;
    minpix = min(imaVOL(:)); maxpix = max(imaVOL(:));
elseif nargin == 3
    minpix = min(imaVOL(:)); maxpix = max(imaVOL(:));
elseif nargin == 4
    maxpix = max(imaVOL(:));
end

mia_Start3dCursor(imaVOL, pixsize, colormaptype, minpix, maxpix);


function varargout = plotgrid(varargin)
% VL_PLOTGRID  Plot a 2-D grid
%  VL_PLOTGRID(X,Y) plots a grid with vertices (X,Y). X and Y are MxN
%  matrices, with one entry per vertex.
%
%  H=VL_PLOTGRID(...) returns the handle to the grid object.
%
%  See also: VL_HELP().
[varargout{1:nargout}] = vl_plotgrid(varargin{:});


%--- help for dsge/check_derivatives ---
%
%  Compares the derivatives and the solutions from various differentiation techniques
%
%  ::
%
%    check_derivatives(obj)
%    retcode=check_derivatives(obj)
%
%  Args:
%     obj (rise | dsge): model object or vectors of model objects
%
%  Returns:
%     :
%
%     - **retcode** [numeric]: 0 if no problem is encountered during the
%       comparisons. Else the meaning of recode can be found by running
%       decipher(retcode)
%
%  Note:
%
%     - The derivatives computed are 'automatic', 'symbolic' or 'numerical'
%     - The comparisons are done relative to automatic derivatives, which are
%       assumed to be the most accurate.
%
%


function [meg_loc, meg_dir] = msi_file_MEG_loc(set_fid)
%function [meg_loc, meg_dir] = msi_file_MEG_loc(set_fid, chans)
%	MSI_FILE_GET_LONG(set_fid, chans)	Skip to a keyword in a file FID
%	and return the single float value
%

key_count = msi_file_find_keyword(set_fid, 'MSI.MegChanCount:');
if (key_count == 1)
    MegChanCount = msi_file_get_long(set_fid, 'MSI.MegChanCount:');
end

frewind(set_fid);
keyword = 'MSI.Meg_Position_Information.Begin:';

while feof(set_fid) == 0
    	line = fgetl(set_fid);
	matches = findstr(line, keyword);
	num = length(matches);
	if num > 0
	    fprintf(1, 'I found a %s\n', line);
	    for (ii=1:MegChanCount)
		line = fgetl(set_fid);
		[name, count, errmsg, nextindex] = sscanf(line, '%s\t', 1);
		[token, nextline] = strtok(line, '	');
		[bigresult, count, errmsg, nextindex] = sscanf(nextline, '\t%f\t%f\t%f\t%f\t%f\t%f', 6);
		loc(1) = bigresult(1);
		loc(2) = bigresult(2);
		loc(3) = bigresult(3);
		dir(1) = bigresult(4);
		dir(2) = bigresult(5);
		dir(3) = bigresult(6);
		%fprintf(1, 'chan: %s\n',  name);
		%fprintf(1, '  %f %f %f   ',  loc(1), loc(2), loc(3));
		%fprintf(1, '  %f %f %f \n',  dir(1), dir(2), dir(3));
		%fprintf(1, 'chan: %s (%f,%f,%f) (%f,%f,%f)\n',  name, loc[1], loc[2], loc[3], dir[1], dir[2], dir[3]);
		outloc(ii,1) = loc(1);
		outloc(ii,2) = loc(2);
		outloc(ii,3) = loc(3);

		outdir(ii,1) = dir(1);
		outdir(ii,2) = dir(2);
		outdir(ii,3) = dir(3);
	    end
meg_loc = outloc;
meg_dir = outdir;
	end
end


function fmarginal = add_ev_to_dmarginal(fmarginal, evidence, ns)
% ADD_EV_TO_DMARGINAL 'pump up' observed nodes back to their original size.
% fmarginal = add_ev_to_dmarginal(fmarginal, evidence, ns)
%
% We introduce 0s into the array in positions which are incompatible with the evidence.

dom = fmarginal.domain;
odom = dom(~isemptycell(evidence(dom)));
vals = cat(1, evidence{odom});
index = mk_multi_index(length(dom), find_equiv_posns(odom, dom), vals);
T = 0*myones(ns(dom));
ens = ns(:)';
ens(odom) = 1;
T(index{:}) = myreshape(fmarginal.T, ens(dom));
fmarginal.T = T;


function [cl2,classes] = image_histogram1d(varargin)
% Visualize a change_point map stored in hewma_cp.img
% (output from hewma2)
% and classify voxels into groupings based on CP
%
% :Usage:
% ::
%
%     [cl2,classes] = image_histogram1d([image name],[overlay])
%

name = 'hewma_cp.img';
%name = 'hewma_runlen.img';
overlay = [];

if length(varargin) > 0, name = varargin{1};,end
if length(varargin) > 1, overlay = varargin{2};,end

% ----------------------------------------------------
% initial viewing of CP map
% ----------------------------------------------------

[CLU.XYZ,CLU.XYZmm,CLU.Z,CLU.V] = img2voxel(name);
CLU.XYZ = CLU.XYZ(1:3,:);
%cl = mask2clusters(name);

%cluster_orthviews(cl,'overlay',overlay);
v2 = CLU.Z;

% ----------------------------------------------------
% load data
% ----------------------------------------------------

%v = spm_read_vols(spm_vol(name));
%v2 = v(:);

%discretize for convenience
v2 = round(v2.*100);
%v2(abs(v2) < eps | isnan(v2)) = [];  % shoul

% ----------------------------------------------------
% make histogram and get clusters (classifications) of CPs
% ----------------------------------------------------

nbins = input('Number of bins: '); %unique(v2);
tor_fig; f1 = gcf; [h,x] = hist(v2./100,nbins); hh = bar(x,h); set(hh,'FaceColor',[.5 .5 .5])

nclasses = input('How many classes?');
str = sprintf('%3.0f Classes: color image overlay starting at which class (e.g., 1 for all classes): ',nclasses)
startclass = input(str);

err = 1; indx = 1;
while err
    try
        classes = kmeans(v2, nclasses);   % ,'start','uniform');
        err = 0;
    catch
    end
    indx = indx + 1;
    if indx == 11, disp('kmeans: tried 10 times.  No solution.'); err = 0;, return, end
end

% For each x, find the modal class
% this is used to color the histogram
x100 = x*100;
binwid = diff(x100); binwid = binwid(1)./2;

for i =1:length(x100)
    xrange = [x100(i)-binwid x100(i)+binwid];
    xclass = classes(v2>xrange(1) & v2<=xrange(2));
    binclass(i) = mode(xclass);
end

%v2 = round(v2.*100);
% % classmap's elements are the range of values in v2
% mincp = min(v2);
% maxcp = max(v2);
% for i = mincp:maxcp, tmp = unique(classes(find(v2==i)));
%     if isempty(tmp), classmap(i) = 0;,
%     else,classmap(i) = tmp(1);, end
% end

% CLU = clusters2CLU(cl);
% CLU.Z = v2';
% CLU.Z(abs(CLU.Z)<eps) = NaN;

CLU.cp = v2';
v2(v2<=0) = 1;   %make sure no negative numbers or zeros for some reason
CLU.Z = classes';  %classmap(v2);

% ----------------------------------------------------
% define colors and sort by class size
% ----------------------------------------------------

%colors = {[1 0 0] [0 1 0] [0 0 1] [1 1 0] [1 0 1] [0 1 1]};
%while length(colors) < nclasses, colors = [colors colors];,end

colors = hot(nclasses+2 - startclass + 1);
colors = colors(2:end-1,:);

%un-plotted classes
colors = [repmat(.5,startclass-1,3); colors];

for i = 1:length(colors), col{i} = colors(i,:);,end
colors = col;
%colors = col(2:end);    %(floor(length(col)./3):end);

% sort by change point, ascending
for i = 1:nclasses,
    meancp(i) = mean(v2(classes==i));,
    nvox(i) = sum(classes==i);
    indx(i) = i;
end
[meancp,i] = sort(meancp,2,'ascend');
%nvox(i) = nvox(1:length(i));
%indx(i) = indx(1:length(i));
nvox  = nvox(i);
indx = indx(i);

meancp = meancp ./ 100; % convert back to original units.  resolution = 2 dec. places.

%table
fprintf(1,'\nClass\tNum. Voxels\tMean Value\tColor\t\t\n');
for j =1:nclasses
    fprintf(1,'%3.0f\t%3.0f\t%3.2f\t%3.2f\t%3.2f\t%3.2f\t\n',indx(j),nvox(j),meancp(j),colors{j}(1),colors{j}(2),colors{j}(3));
end
fprintf(1,'\n');

% sort by class size
%for i = 1:nclasses, nvox(i) = sum(classes==i);,end
%[nvox,i] = sort(nvox,2,'descend');

%colors(i) = colors(1:length(i));

% ----------------------------------------------------
% re-plot histogram with color codes
% ----------------------------------------------------
figure(f1);

clear i
for i = startclass:nclasses
    %     wh = find(classmap == indx(i)); range = [min(wh) max(wh)+1];
    %     wh = find(x*100 <= range(2) & x*100 >= range(1));
    %     hh = bar(x(wh),h(wh)); set(hh,'FaceColor',colors{i});

    wh = find(binclass == indx(i));
    hh = bar(x(wh),h(wh)); set(hh,'FaceColor',colors{i});

end
xlabel('Image value')
ylabel('Number of voxels')

% ----------------------------------------------------
% re-make separate clusters for each class
% and plot on brain
% ----------------------------------------------------

clear cl2
for i = startclass:nclasses
    CLUtmp = CLU;
    wh = find(CLUtmp.Z == indx(i));
    CLUtmp.XYZmm = CLUtmp.XYZmm(:,wh);
    CLUtmp.XYZ = CLUtmp.XYZ(:,wh);
    CLUtmp.Z = CLUtmp.Z(:,wh);
    CLUtmp.cp = CLUtmp.cp(:,wh);
    cl2{i} = tor_extract_rois([],CLUtmp,CLUtmp);

    if i == startclass
        cluster_orthviews(cl2{i},colors(i),'overlay',overlay);
    else
        cluster_orthviews(cl2{i},colors(i),'add','overlay',overlay);
    end
end

% write mask of sig. results
domask = input('Write mask of colormapped voxels? (1 or 0): ');
if domask
    xyz = [];
    for i=1:length(cl2)
        if ~isempty(cl2{i}), xyz = [xyz cl2{i}.XYZ];, end
    end
    V = spm_vol(name);
    V.fname = 'img_hist_mask.img';
    mask = voxel2mask(xyz', V.dim(1:3));
    spm_write_vol(V,mask);
end

return


function wiggleinterferogram(c,scale,type,norm,range)

% Private method. See ../plot for details.

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

% EXTRACT IMAGE
w = get(c,'WAVES');
if isempty(get(w(1),'interferogram_time'))
    error('PLOT INTERFER method can only be used following INTERFEROGRAM function');
end
I.time  = get(w(1),'INTERFEROGRAM_TIME');
I.index = get(w(1),'INTERFEROGRAM_INDEX');
I.CC    = get(w(1),'INTERFEROGRAM_MAXCORR');
I.LL    = get(w(1),'INTERFEROGRAM_LAG');

% SET COLOR SCALE FOR LAG PLOT
I.LL = I.LL ./ range;
f = find((I.LL)<-1); I.LL(f)=-1;      % eliminate outliers
f = find((I.LL)> 1); I.LL(f)= 1;
I.LL = 31.5 * I.LL;
I.LL = round(I.LL + 32.5);                       % shift to positive indices

I.TRANS = I.CC - 0.6;
f = find(I.TRANS<0);
I.TRANS(f) = 0;
I.TRANS = round(0.75*10*I.TRANS);
I.LL = I.LL + 64*I.TRANS;

% PREP PLOT
figure('Color','w','Position',[50 50 850 1100]);
box on; hold on;

% FIX ORDER OF TRACES
ord = 1:get(c,'TRACES');

% GET MEAN TRACE AMPLITUDE FOR SCALING BELOW (when norm = 0)
maxlist = [];
for i = ord
    maxlist(end+1) = max(abs( get(c.W(i),'DATA') ));
end;
normval = mean(maxlist);

% ADD IMAGE
if strncmpi(type,'C',1)
    imagesc(I.time,I.index,I.CC);
    colormap(c,'LTC');
    colorbar;
    hold on;
elseif strncmpi(type,'L',1)
    h = image(I.time,I.index,I.LL);
    colormap(jet);
    %caxis([-1 1]);
    cmap = load('colormap_lag.txt');
    invcmap = 1 - cmap;
    cmap = 1 - [0*invcmap ; 0.33*invcmap ; 0.66*invcmap ; 1*invcmap];
    colormap(cmap);
    hcb = colorbar;
    set(hcb,'YLim',[193 256]);
    set(hcb,'YTick',193+64*[0:.125:1]);
    set(hcb,'YTickLabel',range*[-1:.25:1]);

    hold on;
else
    error('Plot type not recognized.');
end

% SET COLOR

% LOOP THROUGH WAVEFORMS
% tmin =  999999;
% tmax = -999999;
% count = 0;
% for i = ord
% 	count = count + 1;
%     d = get(c.W(i),'DATA');            %%%d = c.w(:,i);
% 	if norm==0
%         d = scale * d/normval;			% do not normalize trace amplitudes
%     else
%         if max(abs(d))==0
%             d = scale * d;              	% ignore zero traces
%         else
%             d = scale * d/max(abs(d));		% normalize trace amplitudes
%         end
%     end
%     d = -1 * d; 				% because scale is reversed below
% 	wstartrel = 86400*(get(c.W(i),'START_MATLAB')-c.trig(i));	% relative start time (trigger is at zero)
% 	tr = wstartrel + [ 0:length(d)-1]'/get(c.W(i),'Fs');
% 	plot(tr,d+count,'k-','LineWidth',1.5);
%     % save min and max relative trace times
% 	if tr(1) < tmin
% 		tmin = tr(1);
% 	end;
% 	if tr(end) > tmax
% 		tmax = tr(end);
% 	end;
%
% end;

% --------------------------------
wstartrel = 86400 *( get(c.W(ord),'START_MATLAB') - c.trig(ord));% relative start time (trigger is at zero)
freq = get(c.W(ord),'Fs');
lengths = get(c.W(ord),'data_length');
tr = nan(max(lengths),numel(ord)); %pre allocate with nan to not plot
abs_max =  max(abs(c.W(ord)));
for count = 1:numel(ord)
    tr(1:lengths(count),ord(count)) = ...
        wstartrel(count) + [ 0:lengths(count)-1]'/freq(count);
end;

% scale is negative because it is reversed below
if norm==0
    % GET MEAN TRACE AMPLITUDE FOR SCALING BELOW (when norm = 0)
    maxlist = max(abs(c.W(ord)));
    normval = mean(maxlist);
    d =  double(c.W(ord) .*( -scale ./ normval)+ [1:numel(ord)]','nan'); % do not normalize trace amplitudes
else
    abs_max(abs_max==0) = 1; % ignore zero traces

    d = double(c.W(ord) .* (-scale ./ abs_max)+[1:numel(ord)]','nan'); % normalize trace amplitudes
end

plot(tr,d,'k-','LineWidth',1.5);
% ------------------------------------------------------
% adjust figure
axis([min(tr(:)) max(tr(:)) 0 length(ord)+1]);
%axis([tmin tmax 0 length(ord)+1]);
set(gca,'YDir','reverse');
set(gca,'YTick',1:length(ord));
set(gca,'YTickLabel',datestr(c.trig(ord)),'FontSize',6);
xlabel('Relative Time,(s)','FontSize',8);

% replace dates with station names if stations are different
if ~check(c,'STA')
    sta  = get(c,'STA');
    chan = get(c,'CHAN');

    for i=1:get(c,'TRACES')
       labels(i) = strcat( sta(i) , '_' , chan(i) );
    end
    set( gca , 'YTick' , [1:1:get(c,'TRACES')] );
    set( gca , 'YTickLabel' , labels );
end

%PRINT OUT FIGURE
set(gcf, 'paperorientation', 'landscape');
set(gcf, 'paperposition', [.25 .25 10.5 8] );
try
if strncmpi(type,'C',1)
    print(gcf, '-depsc2', 'FIG_interferogram_corr.ps')
else
    print(gcf, '-depsc2', 'FIG_interferogram_lag.ps')
end
catch
disp('Warning: Unable to save figure in current directory.');
end


%%
%
% This version is the working version from Pasadena 12/00
% it uses a single Mc cut, not a time variable cut.
% this is the most basic version of the pval code
%
%
%
%%

global m0 m events t dt obs_events calc_events maxt pl1
global bvm cut_cat all_minx fval tstep_tmp disc_events
global ncst length_log vts calc_time synth_events
global calc_sd  calc_ed pre_events daymc pl2  binv cua
global magco_fixed comp_flag

all_minx = [];
obs_events=[];
events = [];
synth_events = [];
cutobs_events = [];
nocutobs_events = [];
tstep_tmp = [];
vts = [];
daymc = [];
fval = [];
mmc = [];

report_this_filefun(mfilename('fullpath'));
m0 = maepi(1,6);
dt = .1;
%%
% get GUI input for time interval for calculation
% and for prediction.
%%

prompt   = {'Enter A,b,c,p calculation start time(days):',...
    'Enter calculation end time:',...
    'Enter forecast start time(days):',...
    'Enter forecast end time:'};
title    = 'Forecast based on A,b,c & p';
lines = 1;
def     = {'0','10','10','30'};
answer   = inputdlg(prompt,title,lines,def);
calc_sd = str2double(answer{1,1});
calc_ed = str2double(answer{2,1});
fore_sd = str2double(answer{3,1});
fore_ed = str2double(answer{4,1});

%%
% get catalog ffrom the plot cumulative number window
%%
tcut_cat = newt2;
hold_newt2 = newt2;
%%
% transform input days to decimal years
%%
calc_start = maepi(:,3) + calc_sd/365.0;
calc_end = maepi(:,3) + calc_ed/365.0;
fore_start = maepi(:,3) + fore_sd/365.0;
fore_end = maepi(:,3) + fore_ed/365.0;
endt = (calc_ed-calc_sd);

%%
% error check on GUI values
%%
maxt = (max(newt2.Date)-min(newt2.Date)+(0.05/365))*365;
if (calc_ed-calc_sd) > maxt
    disp('Less days in catalog that calculation period');
    return;
end

%%
% the following line is to take care of last eq's missed in
% bwith t calc
%%
m = min(newt2.Magnitude);

%%
% cut the events to the correct days
%
%%

ll = tcut_cat(:,3) <= calc_end;
cut_cat = tcut_cat(ll,:);
ll = cut_cat(:,3) < calc_start;
[pre_events,dump] = size(cut_cat(ll,3));
ll = cut_cat(:,3) > calc_start;
cut_cat=cut_cat(ll,:);

%%
% bvm from bwithtimc_nogui is used in the plot and c determination
% DO NOT USE THIS Mc
% calculate Mc in 100 event steps, returned in bvm
% same tool as for b with time
% defaults to best of 90 or 95% option
% ni is step size for Mc calc Set in bwithtimc_nogui too
%%
% use all events to compute mc
if ~exist('cutcat_flag', 'var')
    keep_newt2 = newt2;
    newt2 = cut_cat;
    bwithtimc_nogui;
    newt2 = keep_newt2;
end

%%
% calculate b value for entire sequence and get stand dev
% and use for constraints in search
%%
tmp_newt2=newt2;
newt2=cut_cat;
bdiff_omori;
bmin = bvml-.01*stanml;
bmax = bvml+.01*stanml;
bv = bvml;
bv0 = bvml;
av0 = avml;
newt2=tmp_newt2;
disp(['Initial b value: ',num2str(bvml),'+/-',num2str(stanml)]);

%%
% calculate a 6th order poly fit to the mc
% and find the mean of that for the last third
% of the data.  Used only for plotting
%%
[xb,yb] = size(bvm);
numpoly = min(xb-1,10);
csday = cumsum(bvm(:,5));
[pcof] = polyfit(csday,bvm(:,4),numpoly);
smoo_mc = polyval(pcof,csday);
mmc(1:length(csday)) = magco;

figure
pbvm = plot(csday,bvm(:,4),'-mo');
hold on
psm = plot(csday,smoo_mc,'-b');
pmag = plot(csday,mmc,'k-');
xlabel('days')
ylabel('Mc')
legend([pbvm,psm,pmag],'Mc in 100 event steps','Smoothed Mc','Mc cut','location','northeast');

tlen = calc_ed;

%%
% get GUI input for fixed mc
%%

prompt   = {'The calculated Mc is as follows, this value may be adjusted.'};
title    = 'Fixed Magnitude of Completeness';
lines = 1;
def     = {num2str(magco)};
answer   = inputdlg(prompt,title,lines,def);
magco_fixed = str2double(answer{1,1});

%%
% cut the catalog at the given Mc
%%
ll = cut_cat(:,6) >= magco_fixed - .05;
cut_cat = cut_cat(ll,:);

disp(['Number of events used: ',num2str(length(cut_cat))]);

%%
% see if cmin should be increased based on fixed Mc cutting
%%
cmin = .05;

for cib = 1:length(bvm)
    if bvm(cib,4) <= magco_fixed
        cmin = (bvm(cib,2)-maepi(1,3))*365
        break
    end
    if cib == length(bvm)
        disp('%%%ERROR%%% -- no bins complete to the Mc cut!!');
        return
    end
end

%create initial obs_events
binv = maepi(:,3)+0.05/365:dt/365:maepi(:,3)+calc_ed/365;
[nn,pdfbin] = histc(cut_cat(:,3),binv);
obs_events = cumsum(nn(1:length(nn)));

tbin = (binv-maepi(1,3))*365;
smc = interp1(csday,smoo_mc,tbin,'linear',smoo_mc(1));

%if compflag == 'of'
%    figure
%    pl1 = plot(obs_events,'-rx');
%    hold on
%    pl2 = plot(obs_events+50,'b');
%    legend([pl1,pl2],'Observed','Calculated Events',2);
%    drawnow
%end

vlb = [-3.5 bv0 cmin -0.30];
vub = [-1.0 bv0 cmin 1.99];
minx = [-2.00 bv0 cmin 2.0];

lobs = [];
Ap = [];
Aparmas = [];
Ap2=[];
lamda= [];
nlAp2=[];
obs = diff(obs_events(1:length(binv)));
dll = obs > 0;
nobs = obs(dll);
lobs = log10(nobs);

Mm=maepi(:,6)-magco_fixed;
cfixed = cmin;

stbin = tbin(2:length(tbin));
stbin = stbin(dll);
ll = length(stbin);
Aparams = zeros(ll,2);
Aparams(1:ll,1) = 1;
Aparams(1:ll,2) = Mm;

for i = 1:length(stbin)-1
    nlAp2(i) = ((stbin(i+1)-stbin(i)));
end
nlAp2 = [nlAp2 nlAp2(length(nlAp2'))]';
Ap2 = log10(nlAp2);

Ap = -log10(stbin+cfixed)';
Aparams = cat(2,Aparams,Ap);
id= eye(3);
id(1,1) = 1/10000;
id(3,3) = 1/10000;
id(2,2) = 1/10;
apri = [-1.67/10000 bv0/10 1.08/10000]';

lamda = (lobs-Ap2);
lamda = [lamda;apri];
Aparams = [Aparams; id];

valinv = Aparams\(lamda)

%options = optimset('Display','iter','Diagnostics','on','HessUpdate','dfp',...
%   'TolX',.000002,'TolFun',.0000001,'DiffMinChange',1e-3,...
%   'DiffMaxChange',.01)
%[x,fval] = fmincon('norm(func_omoris(x))',minx,[],[],[],[],vlb,vub,[],options);
%fval = [];

%rjA = log(10x(1))-bv0*(maepi(1,6)-magco_fixed);
x=[];
x(1) = valinv(1);
x(2) = bv0;
x(3) = cfixed;
x(4) = valinv(3);

if compflag == 'of'

    %%
    % plot results
    %%
    figure
    p1 = plot(newt2.Date,1:newt2.Count,'.k','MarkerSize',3);
    hold on
    l = cut_cat(:,3) > maepi(1,3) + x(3)/365;
    p2 = plot(cut_cat(l,3),1:length(cut_cat(l,3)),'.y','MarkerSize',6);
    p3 = plot(binv,obs_events,'r-.');
    %p4 = plot(binv,cumsum(calc_events),'b');

    obs = max(obs_events);

    forecast_omoris;
    p5 = plot(fore_time,(cumsum(fore_events)+obs+pre_events),'ms','Markersize',4);

    di = (max(obs_events) - sum(calc_events))

    legend([p1,p2,p3,p5],'Original','Cut in M','Observed','Forecast','Location', 'NorthWest');

    axes('Position',[.7,.1,.2,.2],'Box','on')
    axis off
    text(.1,.6,['A = ',num2str(x(1))]);
    text(.1,.45,['b = ',num2str(x(2))]);
    text(.1,.3,['c = ',num2str(x(3))]);
    text(.1,.15,['p = ',num2str(x(4))]);
end

newt2 = hold_newt2;


function [L, f, FAIL] = linop(N)
%LINOP   Convert a CHEBOP to a LINOP.
%   L = LINOP(N) converts a CHEBOP N to a linop L if N is a linear operator. If
%   N is not linear, an error message is returned.
%
%   [L, F] = LINOP(N) returns also the affine part F of the linear CHEBOP N such
%   that L*u + F(x) = N.op(x,u).
%
%   [L, F, FAIL] = LINOP(N) will prevent an error from being thrown if N is not
%   linear, but instead return FAIL = TRUE and L = []. If N is linear, FAIL =
%   FALSE.
%
% See also LINOP, CHEBOP/LINEARIZE, CHEBOP/ISLINEAR.

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

% Tell CHEBOP/LINEARIZE() to stop if it detects nonlinearity:
linCheck = 1;

% Linearize, thereby obtaining linearity information and a LINOP:
[L, f, isLinear] = linearize(N, N.init, [], linCheck);

% We need the entire operator (including BCs) to be linear:
FAIL = ~all(isLinear);

% Throw an error is the CHEBOP is nonlinear:
if ( FAIL && (nargout < 3) )
    error('CHEBFUN:CHEBOP:linop:nonlinear',...
        'This does not appear to be a linear operator.')
end

% All values of the LINOPCONSTRAINT stored in L will be of incorrect sign when
% returned from LINEARIZE(), if we want to use it for a LINOP backslash. This is
% because when problems are solved with LINOP backslash, the solution to the
% problem is the output itself, while in a Newton iteration, we have to add the
% output of the LINOP solution to the current guess. Thus, flip the signs of the
% values of L.constraint.
L.constraint = -L.constraint;

end