%CLEVALB Classifier evaluation (learning curve), bootstrap version
%
% 	E = CLEVALB(A,CLASSF,TRAINSIZES,NREPS)
%
% INPUT
%   A           Training dataset
%   CLASSF      Classifier to evaluate
%   TRAINSIZES  Vector of class sizes, used to generate subsets of A
%               (default [2,3,5,7,10,15,20,30,50,70,100])
%   NREPS       Number of repetitions (default 1)
%
% OUTPUT
%   E           Error structure (see PLOTE)
%
% DESCRIPTION
% Generates at random, for all class sizes defined in TRAINSIZES, training
% sets out of the dataset A and uses these for training the untrained
% classifier CLASSF. CLASSF may also be a cell array of untrained
% classifiers; in this case the routine will be run for all of them. The
% resulting trained classifiers are tested on all objects in A. This
% procedure is then repeated N times.
%
% Training set generation is done "with replacement" and such that for each
% run the larger training sets include the smaller ones and that for all
% classifiers the same training sets are used.
%
% If CLASSF is fully deterministic, this function uses the RAND random
% generator and thereby reproduces if its seed is reset (see RAND).
% If CLASSF uses RANDN, its seed may have to be set as well.
%
% Use FID = 1 to report progress to the command window.
%
% EXAMPLES
% See PREX_CLEVAL.
%
% SEE ALSO (PRTools Guide)
% MAPPINGS, DATASETS, CLEVALB, TESTC, PLOTE

% Copyright: R.P.W. Duin, duin@ph.tn.tudelft.nl
% Faculty of Applied Sciences, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands

% $Id: clevalb.m,v 1.4 2008/07/03 09:05:50 duin Exp $

function e = clevalb(a,classf,learnsizes,nreps,fid)

  % use of fid is outdated
  if (nargin < 4) || isempty(nreps)
		prwarning(2,'number of repetitions not specified, assuming NREPS = 1');
		nreps = 1;
	end;
  if (nargin < 3) || isempty(learnsizes)
		prwarning(2,'vector of training set class sizes not specified, assuming [2,3,5,7,10,15,20,30,50,70,100]');
 		learnsizes = [2,3,5,7,10,15,20,30,50,70,100];
	end;

	% If a single mapping is given, convert it to a 1 x 1 cell array.

  if (ismapping(classf)), classf = {classf}; end

	% Correct for old argument order.

  if (isdataset(classf)) & (ismapping(a))
  	tmp = a; a = classf; classf = {tmp};
  end
  if (isdataset(classf)) & (iscell(a)) & (ismapping(a{1}))
  	tmp = a; a = classf; classf = tmp;
  end
  if ~iscell(classf), classf = {classf}; end

	% Assert that all is right.
  isdataset(a); ismapping(classf{1});

	% Remove requested class sizes that are larger than the size of the
	% smallest class.

  mc = classsizes(a); [m,k,c] = getsize(a);
	toolarge = find(learnsizes >= min(mc));
	if (~isempty(toolarge))
		prwarning(2,['training set class sizes ' num2str(learnsizes(toolarge)) ...
								 ' larger than the minimal class size in A; removed them']);
	  learnsizes(toolarge) = [];
	end
  learnsizes = learnsizes(:)';

	% Fill the error structure.

  nw = length(classf(:));
  datname = getname(a);

  e.n       = nreps;
  e.error   = zeros(nw,length(learnsizes));
  e.std     = zeros(nw,length(learnsizes));
  e.xvalues = learnsizes(:)';
  e.names   = [];
  e.xlabel  = 'Training set size';
  if (nreps > 1)
  	e.ylabel= ['Averaged error (' num2str(nreps) ' experiments)'];
  elseif (nreps == 1)
  	e.ylabel = 'Error';
  else
		error('Number of repetitions NREPS should be >= 1.');
	end;
  if (~isempty(datname))
  	e.title = ['Bootstrapped learning curve on ' datname];
  end
  if (learnsizes(end)/learnsizes(1) > 20)
  	e.plot = 'semilogx'; 				% If range too large, use a log-plot for X.
  end

	% Report progress.

	s1 = sprintf('clevalb: %i classifiers: ',nw);
	prwaitbar(nw,s1);

	% Store the seed, to reset the random generator later for different
	% classifiers.

  seed = randreset;

	% Loop over all classifiers (with index WI).

  for wi = 1:nw

  	isuntrained(classf{wi});
    name = getname(classf{wi});
    e.names = char(e.names,name);
    prwaitbar(nw,wi,[s1 name]);

		% E1 will contain the error estimates.

  	e1 = zeros(nreps,length(learnsizes));

		% Take care that classifiers use same training set.

  	randreset(seed); seed2 = seed;

		% For NREPS repetitions...
		s2 = sprintf('cleval: %i repetitions: ',nreps);
		prwaitbar(nreps,s2);

  	for i = 1:nreps

			prwaitbar(nreps,i,[s2 int2str(i)]);
			% Store the randomly permuted indices of samples of class CI to use in
			% this training set in JR(CI,:).

  		JR = zeros(c,max(learnsizes));
  		for ci = 1:c
				JC = findnlab(a,ci);

				% Necessary for reproducable training sets: set the seed and store
				% it after generation, so that next time we will use the previous one.
  			randreset(seed2);

  			R = ceil(rand(1,max(learnsizes))*length(JC));
  			JR(ci,:) = JC(R)';

  			seed2 = randreset;
  		end

  		li = 0;										% Index of training set.
			nlearns = length(learnsizes);
			s3 = sprintf('cleval: %i sizes: ',nlearns);
			prwaitbar(nreps,s3);
  		for j = 1:nlearns
				nj = learnsizes(j);
        prwaitbar(nlearns,j,[s3 int2str(j) ' (' int2str(nj) ')']);
        li = li + 1;

				% J will contain the indices for this training set.

				J = [];
  			for ci = 1:c
  				J = [J;JR(ci,1:nj)'];
  			end;

				% Train classifier CLASSF{WI} on this training set and calculate
				% error.

  			W = a(J,:)*classf{wi};
    		e1(i,li) = testc(a,W);

  		end
      prwaitbar(0);

  	end
    prwaitbar(0);

		% Calculate average error and standard deviation for this classifier
		% (or set the latter to zero if there's been just 1 repetition).

  	e.error(wi,:) = mean(e1,1);
  	if (nreps == 1)
  		e.std(wi,:) = zeros(1,size(e.std,2));
  	else
  		e.std(wi,:) = std(e1)/sqrt(nreps);
  	end

  end
  prwaitbar(0);

  % The first element is the empty string [], remove it.
  e.names(1,:) = [];

return


function n = p34_n ( )

%*****************************************************************************80
%
%% P34_N returns the number of variables for problem 34.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer N.  If N is positive, N represents the
%    only legal value for N for this problem.  If N is
%    negative, the absolute value of N is the least legal
%    value of N, but other values are allowable.
%
  n = 2;

  return
end


% function lineStyles = linspecer(N)
% This function creates an Nx3 array of N [R B G] colors
% These can be used to plot lots of lines with distinguishable and nice
% looking colors.
%
% lineStyles = linspecer(N);  makes N colors for you to use: lineStyles(ii,:)
%
% colormap(linspecer); set your colormap to have easily distinguishable
%                      colors and a pleasing aesthetic
%
% lineStyles = linspecer(N,'qualitative'); forces the colors to all be distinguishable (up to 12)
% lineStyles = linspecer(N,'sequential'); forces the colors to vary along a spectrum
%
% % Examples demonstrating the colors.
%
% LINE COLORS
% N=6;
% X = linspace(0,pi*3,1000);
% Y = bsxfun(@(x,n)sin(x+2*n*pi/N), X.', 1:N);
% C = linspecer(N);
% axes('NextPlot','replacechildren', 'ColorOrder',C);
% plot(X,Y,'linewidth',5)
% ylim([-1.1 1.1]);
%
% SIMPLER LINE COLOR EXAMPLE
% N = 6; X = linspace(0,pi*3,1000);
% C = linspecer(N)
% hold off;
% for ii=1:N
%     Y = sin(X+2*ii*pi/N);
%     plot(X,Y,'color',C(ii,:),'linewidth',3);
%     hold on;
% end
%
% COLORMAP EXAMPLE
% A = rand(15);
% figure; imagesc(A); % default colormap
% figure; imagesc(A); colormap(linspecer); % linspecer colormap
%
%   See also NDHIST, NHIST, PLOT, COLORMAP, 43700-cubehelix-colormaps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% by Jonathan Lansey, March 2009-2013  Lansey at gmail.com               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% credits and where the function came from
% The colors are largely taken from:
% http://colorbrewer2.org and Cynthia Brewer, Mark Harrower and The Pennsylvania State University
%
%
% She studied this from a phsychometric perspective and crafted the colors
% beautifully.
%
% I made choices from the many there to decide the nicest once for plotting
% lines in Matlab. I also made a small change to one of the colors I
% thought was a bit too bright. In addition some interpolation is going on
% for the sequential line styles.
%
%
%%

function lineStyles=linspecer(N,varargin)

if nargin==0 % return a colormap
    lineStyles = linspecer(128);
    return;
end

if ischar(N)
    lineStyles = linspecer(128,N);
    return;
end

if N<=0 % its empty, nothing else to do here
    lineStyles=[];
    return;
end

% interperet varagin
qualFlag = 0;
colorblindFlag = 0;

if ~isempty(varargin)>0 % you set a parameter?
    switch lower(varargin{1})
        case {'qualitative','qua'}
            if N>12 % go home, you just can't get this.
                warning('qualitiative is not possible for greater than 12 items, please reconsider');
            else
                if N>9
                    warning(['Default may be nicer for ' num2str(N) ' for clearer colors use: whitebg(''black''); ']);
                end
            end
            qualFlag = 1;
        case {'sequential','seq'}
            lineStyles = colorm(N);
            return;
        case {'white','whitefade'}
            lineStyles = whiteFade(N);return;
        case 'red'
            lineStyles = whiteFade(N,'red');return;
        case 'blue'
            lineStyles = whiteFade(N,'blue');return;
        case 'green'
            lineStyles = whiteFade(N,'green');return;
        case {'gray','grey'}
            lineStyles = whiteFade(N,'gray');return;
        case {'colorblind'}
            colorblindFlag = 1;
        otherwise
            warning(['parameter ''' varargin{1} ''' not recognized']);
    end
end
% *.95
% predefine some colormaps
set3 = colorBrew2mat({[141, 211, 199];[ 255, 237, 111];[ 190, 186, 218];[ 251, 128, 114];[ 128, 177, 211];[ 253, 180, 98];[ 179, 222, 105];[ 188, 128, 189];[ 217, 217, 217];[ 204, 235, 197];[ 252, 205, 229];[ 255, 255, 179]}');
set1JL = brighten(colorBrew2mat({[228, 26, 28];[ 55, 126, 184]; [ 77, 175, 74];[ 255, 127, 0];[ 255, 237, 111]*.85;[ 166, 86, 40];[ 247, 129, 191];[ 153, 153, 153];[ 152, 78, 163]}'));
set1 = brighten(colorBrew2mat({[ 55, 126, 184]*.85;[228, 26, 28];[ 77, 175, 74];[ 255, 127, 0];[ 152, 78, 163]}),.8);

% colorblindSet = {[215,25,28];[253,174,97];[171,217,233];[44,123,182]};
colorblindSet = {[215,25,28];[253,174,97];[171,217,233]*.8;[44,123,182]*.8};

set3 = dim(set3,.93);

if colorblindFlag
    switch N
        %     sorry about this line folks. kind of legacy here because I used to
        %     use individual 1x3 cells instead of nx3 arrays
        case 4
            lineStyles = colorBrew2mat(colorblindSet);
        otherwise
            colorblindFlag = false;
            warning('sorry unsupported colorblind set for this number, using regular types');
    end
end
if ~colorblindFlag
    switch N
        case 1
            lineStyles = { [  55, 126, 184]/255};
        case {2, 3, 4, 5 }
            lineStyles = set1(1:N);
        case {6 , 7, 8, 9}
            lineStyles = set1JL(1:N)';
        case {10, 11, 12}
            if qualFlag % force qualitative graphs
                lineStyles = set3(1:N)';
            else % 10 is a good number to start with the sequential ones.
                lineStyles = cmap2linspecer(colorm(N));
            end
        otherwise % any old case where I need a quick job done.
            lineStyles = cmap2linspecer(colorm(N));
    end
end
lineStyles = cell2mat(lineStyles);

end

% extra functions
function varIn = colorBrew2mat(varIn)
for ii=1:length(varIn) % just divide by 255
    varIn{ii}=varIn{ii}/255;
end
end

function varIn = brighten(varIn,varargin) % increase the brightness

if isempty(varargin),
    frac = .9;
else
    frac = varargin{1};
end

for ii=1:length(varIn)
    varIn{ii}=varIn{ii}*frac+(1-frac);
end
end

function varIn = dim(varIn,f)
for ii=1:length(varIn)
    varIn{ii} = f*varIn{ii};
end
end

function vOut = cmap2linspecer(vIn) % changes the format from a double array to a cell array with the right format
vOut = cell(size(vIn,1),1);
for ii=1:size(vIn,1)
    vOut{ii} = vIn(ii,:);
end
end
%%
% colorm returns a colormap which is really good for creating informative
% heatmap style figures.
% No particular color stands out and it doesn't do too badly for colorblind people either.
% It works by interpolating the data from the
% 'spectral' setting on http://colorbrewer2.org/ set to 11 colors
% It is modified a little to make the brightest yellow a little less bright.
function cmap = colorm(varargin)
n = 100;
if ~isempty(varargin)
    n = varargin{1};
end

if n==1
    cmap =  [0.2005    0.5593    0.7380];
    return;
end
if n==2
    cmap =  [0.2005    0.5593    0.7380;
        0.9684    0.4799    0.2723];
    return;
end

frac=.95; % Slight modification from colorbrewer here to make the yellows in the center just a bit darker
cmapp = [158, 1, 66; 213, 62, 79; 244, 109, 67; 253, 174, 97; 254, 224, 139; 255*frac, 255*frac, 191*frac; 230, 245, 152; 171, 221, 164; 102, 194, 165; 50, 136, 189; 94, 79, 162];
x = linspace(1,n,size(cmapp,1));
xi = 1:n;
cmap = zeros(n,3);
for ii=1:3
    cmap(:,ii) = pchip(x,cmapp(:,ii),xi);
end
cmap = flipud(cmap/255);
end

function cmap = whiteFade(varargin)
n = 100;
if nargin>0
    n = varargin{1};
end

thisColor = 'blue';

if nargin>1
    thisColor = varargin{2};
end
switch thisColor
    case {'gray','grey'}
        cmapp = [255,255,255;240,240,240;217,217,217;189,189,189;150,150,150;115,115,115;82,82,82;37,37,37;0,0,0];
    case 'green'
        cmapp = [247,252,245;229,245,224;199,233,192;161,217,155;116,196,118;65,171,93;35,139,69;0,109,44;0,68,27];
    case 'blue'
        cmapp = [247,251,255;222,235,247;198,219,239;158,202,225;107,174,214;66,146,198;33,113,181;8,81,156;8,48,107];
    case 'red'
        cmapp = [255,245,240;254,224,210;252,187,161;252,146,114;251,106,74;239,59,44;203,24,29;165,15,21;103,0,13];
    otherwise
        warning(['sorry your color argument ' thisColor ' was not recognized']);
end

cmap = interpomap(n,cmapp);
end

% Eat a approximate colormap, then interpolate the rest of it up.
function cmap = interpomap(n,cmapp)
x = linspace(1,n,size(cmapp,1));
xi = 1:n;
cmap = zeros(n,3);
for ii=1:3
    cmap(:,ii) = pchip(x,cmapp(:,ii),xi);
end
cmap = (cmap/255); % flipud??
end


function tests = test_imEuler3d(varargin)
%TESTIMEULER3D  One-line description here, please.
%
%   output = testImEuler3d(input)
%
%   Example
%   testImEuler3d
%
%   See also
%

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

tests = functiontests(localfunctions);

function test_ball(testCase)

% create a simple ball
img = discreteBall(1:20, 1:20, 1:20, [10 10 10 6]);

% check EPC=1 for all adjacencies
epcTh = 1;
assertEqual(testCase, epcTh, imEuler3d(img));
assertEqual(testCase, epcTh, imEuler3d(img, 6));
assertEqual(testCase, epcTh, imEuler3d(img, 26));

% add a holes in the ball -> EPC=2
img = img & ~discreteBall(1:20, 1:20, 1:20, [10 10 10 3]);

% check EPC=1 for all adjacencies
epcTh  = 2;
assertEqual(testCase, epcTh, imEuler3d(img));
assertEqual(testCase, epcTh, imEuler3d(img, 6));
assertEqual(testCase, epcTh, imEuler3d(img, 26));

function test_Torus(testCase)

% create a torus, EPC=0
img = discreteTorus(1:60, 1:60, 1:60, [30 30 30 20 5 60 45]);

% check EPC=1 for all adjacencies
epcTh = 0;
assertEqual(testCase, epcTh, imEuler3d(img));
assertEqual(testCase, epcTh, imEuler3d(img, 6));
assertEqual(testCase, epcTh, imEuler3d(img, 26));

function test_3d_cube_C6(testCase)

% create a simple cube
img = false([5 5 5]);
img(2:4, 2:4, 2:4) = true;

% check EPC=1
epcTh = 1;
assertEqual(testCase, epcTh, imEuler3d(img, 6));

% add a hole in the ball -> EPC=2
img(3, 3, 3) = false;

% check EPC=2
epcTh  = 2;
assertEqual(testCase, epcTh, imEuler3d(img, 6));

function test_3d_cube_C26(testCase)

% create a simple cube
img = false([5 5 5]);
img(2:4, 2:4, 2:4) = true;

% check EPC=1
epcTh = 1;
assertEqual(testCase, epcTh, imEuler3d(img, 26));

% add a hole in the ball -> EPC=2
img(3, 3, 3) = false;

% check EPC=2
epcTh  = 2;
assertEqual(testCase, epcTh, imEuler3d(img, 26));

function test_3d_cubeRing_C6(testCase)

% create a simple cubic ring
img = false([5 5 5]);
img(2:4, 2:4, 2:4) = true;
img(3, 3, 2:4) = false;

% check EPC=0
epcTh = 0;
assertEqual(testCase, epcTh, imEuler3d(img, 6));

function test_3d_cubeRing_C26(testCase)

% create a cubic ring
img = false([5 5 5]);
img(2:4, 2:4, 2:4) = true;
img(3, 3, 2:4) = false;

% check EPC=0
epcTh = 0;
assertEqual(testCase, epcTh, imEuler3d(img, 26));

function test_3D_cubeDiagonals_C6(testCase)

% create a small 3D image with points along cube diagonal
img = false([5 5 5]);
for i = 1:5
    img(i, i, i) = true;
    img(6-i, i, i) = true;
    img(i, 6-i, i) = true;
    img(6-i, 6-i, i) = true;
end

epc6 = imEuler3d(img, 6);

epc6Th = 17;
assertEqual(testCase, epc6, epc6Th);

function test_3D_cubeDiagonals_C26(testCase)

% create a small 3D image with points along cube diagonal
img = false([7 7 7]);
for i = 2:6
    img(i, i, i) = true;
    img(8-i, i, i) = true;
    img(i, 8-i, i) = true;
    img(8-i, 8-i, i) = true;
end

epc26 = imEuler3d(img, 26);

epc26Th = 1;
assertEqual(testCase, epc26, epc26Th);

function test_3D_cubeDiagonals_touchingBorder_C26(testCase)

% create a small 3D image with points along cube diagonal
img = false([5 5 5]);
for i = 1:5
    img(i, i, i) = true;
    img(6-i, i, i) = true;
    img(i, 6-i, i) = true;
    img(6-i, 6-i, i) = true;
end

epc26 = imEuler3d(img, 26);

epc26Th = 1;
assertEqual(testCase, epc26, epc26Th);


function r8_sign_test ( )

%*****************************************************************************80
%
%% R8_SIGN_TEST tests R8_SIGN.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 September 2014
%
%  Author:
%
%    John Burkardt
%
  test_num = 5;

  r8_test = [ -1.25, -0.25, 0.0, +0.5, +9.0 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8_SIGN_TEST\n' );
  fprintf ( 1, '  R8_SIGN returns the sign of an R8.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    R8  R8_SIGN(R8)\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
    r8 = r8_test(test);
    s = r8_sign ( r8 );
    fprintf ( 1, '  %8f  %8f\n', r8, s );
  end

  return
end


function month_name = month_to_month_name_iranian ( m )

%*****************************************************************************80
%
%% MONTH_TO_MONTH_NAME_IRANIAN returns the name of an Iranian month.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the month index.
%
%    Output, string MONTH_NAME, the month name.
%
  name = [ ...
    'Farvardin  ', 'Ordibehesht', 'Xordad     ', 'Tir        ', ...
    'Mordad     ', 'Shahrivar  ', 'Mehr       ', 'Aban       ', ...
    'Azar       ', 'Dey        ', 'Bahman     ', 'Esfand     ' ];

  if ( m < 1 || 12 < m )

    month_name = '??????????';

  else

    month_name = name(m,:);

  end

  return
end


function fixed_num = p11_fixed_num ( )

%*****************************************************************************80
%
%% P11_FIXED_NUM returns the number of fixed points in problem 11.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer FIXED_NUM, the number of fixed points.
%
  fixed_num = 6;

  return
end


function [Sim_Rate, Sim_Mse, Sim_Ber] = simulation_plot(Data, vec, Algorithms)
% function for plotting figures
% Data is a cell containing all the results
% vec is the x axis vector

[row,col] = size(Data);

for i = 1 : row
    for j = 1 : col
        data_one = Data{i,j};
        Sim_Rate(i,j) = data_one.Rate;
        Sim_Mse(i,j) = data_one.Mse;
        Sim_Ber(i,j) = data_one.Ber;
    end
end

plot_Rate;
plot_Mse;
plot_Ber;

    function plot_Rate
        figure;
        for m = 1: col
            plot(vec,Sim_Rate(:,m),'LineWidth',2);
            hold on
        end
        title('Rate');
        ylabel('Rate(bits/s/Hz');
        legend(Algorithms);
    end

    function plot_Mse
        figure;
        for m = 1: col
            semilogy(vec,Sim_Mse(:,m),'LineWidth',2);
            hold on
        end
        title('MSE');
        ylabel('MSE Value');
        legend(Algorithms);
    end

function plot_Ber
        figure;
        for m = 1: col
            semilogy(vec,Sim_Ber(:,m),'LineWidth',2);
            hold on
        end
        title('BER');
        ylabel('BER');
        legend(Algorithms);
    end
end


function h=Iabais(x)
L=length(x);
k=1;
i=1;
while i<=L/2
   h(i)=x(k)*256+x(k+1);
     k=k+2;
   i=i+1;
end;


%SHOWIMG  Pajdla: Shows scaled images in the gray palette
%
%
%	function f = showimg(m,f)
%
%	m = image matrix
%	f = figure handle
%
%       See also:  IMAGE, IMAGESC, COLORMEN.

%	Author: 	Tomas Pajdla, Tomas.Pajdla@esat.kuleuven.ac.be
%					    pajdla@vision.felk.cvut.cz
%			03/06/95 ESAT-MI2, KU Leuven
%	Documentation:
%	Language: 	Matlab 4.2, (c) MathWorks
%
function f = showimg(m,f);

if (nargin==2)
 figure(f);
else
 f=figure;
%  colormen;
 colormap('gray');
end

imagesc(m);
axis('image');

return


function neqn = p14_neqn ( )

%*****************************************************************************80
%
%% P14_NEQN returns the number of equations for problem P14.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer NEQN, the number of equations.
%
  neqn = 51;

  return
end


function Pbest = UpdatePbest(Pbest,Population)
% Update the local best position of each particle

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    replace        = ~all(Population.objs>=Pbest.objs,2);
    Pbest(replace) = Population(replace);
end


function jed = epoch_to_jed_zoroastrian ( )

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

  return
end


function Y = selb(M1, M2, mp)
%Y = selb(M1, M2, mp) coefficient selection for base image
%
%    M1  - coefficients A
%    M2  - coefficients B
%    mp  - switch for selection type
%          mp == 1: select A
%          mp == 2: select B
%          mp == 3: average A and B
%
%    Y   - combined coefficients

%    (Oliver Rockinger 16.08.99)

switch (mp)
  case 1, Y = M1;
  case 2, Y = M2;
  case 3, Y = (M1 + M2) / 2;
  otherwise, error('unknown option');
end;


function test_suite = test_grFindGeodesicPath
%TEST_GRFINDGEODESICPATH  One-line description here, please.
%
%   output = test_grFindGeodesicPath(input)
%
%   Example
%   testGrFindGeodesicPath
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2011-05-22,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2011 INRA - Cepia Software Platform.

test_suite = functiontests(localfunctions);

function testGraph01(testCase) %#ok<*DEFNU>

[nodes, edges] = createTestGraph01;
path = grFindGeodesicPath(nodes, edges, 3, 8);
exp = [4 1 3 10];
testCase.assertEqual(exp, path);

function testGraph03(testCase)

[nodes, edges] = createTestGraph03;
path = grFindGeodesicPath(nodes, edges, 1, 12);
exp = [1 2 5 7 11 13];
testCase.assertEqual(exp, path);


function y = cvx_s_lower_triangular( m, n )
%CVX_S_LOWER_TRIANGULAR Lower triangular matrices.
y = cvx_s_banded( m, n, m, 0 );

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


function fem1d_bvp_linear_test ( )

%*****************************************************************************80
%
%% FEM1D_BVP_LINEAR_TEST tests the FEM1D_BVP_LINEAR library.
%
%  Location:
%
%    http://people.sc.fsu.edu/~jburkardt/m_src/fem1d_bvp_linear/fem1d_bvp_linear_test.m
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 June 2014
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FEM1D_BVP_LINEAR_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the FEM1D_BVP_LINEAR library.\n' );

  fem1d_bvp_linear_test01 ( );
  fem1d_bvp_linear_test02 ( );
  fem1d_bvp_linear_test03 ( );
  fem1d_bvp_linear_test04 ( );
  fem1d_bvp_linear_test05 ( );
  fem1d_bvp_linear_test06 ( );
  fem1d_bvp_linear_test07 ( );
  fem1d_bvp_linear_test08 ( );
  fem1d_bvp_linear_test09 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FEM1D_BVP_LINEAR_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


% FROM: LabelMe Toolbox
function h=subplottight(Ny, Nx, j, margin)
% General utility function
%
% This function is like subplot but it removes the spacing between axes.
%
% subplottight(Ny, Nx, j)

if nargin <4
    margin = 0;
end

j = j-1;
x = mod(j,Nx)/Nx;
y = (Ny-fix(j/Nx)-1)/Ny;
h=axes('position', [x+margin/Nx y+margin/Ny 1/Nx-2*margin/Nx 1/Ny-2*margin/Ny]);


function test_suite = test_drawLine
% Tests the function 'drawLine'
%   output = test_drawLine(input)
%
%   Example
%   testClipLine
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2009-04-22,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2009 INRA - Cepia Software Platform.
% Licensed under the terms of the LGPL, see the file "license.txt"

test_suite = functiontests(localfunctions);

function testHoriz(testCase) %#ok<*DEFNU>
% test clipping of horizontal lines

box = [0 100 0 100];

hf = figure; clf;
axis(box);

% inside, to the right
line = [30 40 10 0];
edge = [0 40 100 40];

hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% inside, to the left
line = [30 40 -10 0];
edge = [100 40 0 40];
hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% outside
line = [30 140 10 0];
hl = drawLine(line);
testCase.assertEqual(-1, hl);

close(hf);

function testVert(testCase)
% test clipping of vertical lines

box = [0 100 0 100];

hf = figure; clf;
axis(box);

% inside, upward
line = [30 40 0 10];
edge = [30 0 30 100];
hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% inside, downward
line = [30 40 0 -10];
edge = [30 100 30 0];
hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% outside
line = [140 30 0 10];
hl = drawLine(line);
testCase.assertEqual(-1, hl);

close(hf);

function testDiagUp(testCase)
% test clipping of upward diagonal lines

box = [0 100 0 100];

hf = figure; clf;
axis(box); hold on;

% inside, top right corner
line = [80 30 10 10];
edge = [50 0 100 50];
hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% inside, down right corner
line = [20 70 10 10];
edge = [0 50 50 100];
hl = drawLine(line);
testCase.assertEqual(edge([1 3]), get(hl, 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge([2 4]), get(hl, 'ydata'), 'AbsTol', .01);

% outside
line = [140 -30 10 10];
hl = drawLine(line);
testCase.assertEqual(-1, hl);

line = [-40 130 10 10];
hl = drawLine(line);
testCase.assertEqual(-1, hl);

close(hf);

function testMultiLines(testCase)

box = [0 100 0 100];

hf = figure; clf;
axis(box);

% inside, top right corner
line = [...
    80 30 10 10; ...
    20 70 10 10; ...
    140 -30 10 10; ...
    -40 130 10 10];
edge = [...
    50 0 100 50; ...
    0 50 50 100];
hl = drawLine(line);
testCase.assertEqual(4, length(hl));
testCase.assertEqual(edge(1, [1 3]), get(hl(1), 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge(1, [2 4]), get(hl(1), 'ydata'), 'AbsTol', .01);
testCase.assertEqual(edge(2, [1 3]), get(hl(2), 'xdata'), 'AbsTol', .01);
testCase.assertEqual(edge(2, [2 4]), get(hl(2), 'ydata'), 'AbsTol', .01);
testCase.assertEqual(-1, hl(3));
testCase.assertEqual(-1, hl(4));

close(hf);


function lbl = removeBorderRegions(lbl, varargin)
%REMOVEBORDERREGIONS Remove regions on the border of an image
%
%   LBL2 = removeBorderRegions(LBL);
%   LBL is a labeled image, or a binary image. Image can be 2D or 3D.
%   In the case of binary image, the image is labeled using 4-adjacency for
%   2D images, or 6-adjacency for 3D images.
%   The regions which touch the border of the image are removed, and the
%   remaining regions are re-labeled. Result has the same class than the
%   original image.
%
%   LBL2 = removeBorderRegions(LBL, BORDERS);
%   Specifies which borders need to be removed. BORDERS is a cell array of
%   strings, with each string corresponding to a border:
%   'left':     all pixels with x=1
%   'right':    all pixels with x=last
%   'top':      all pixels with y=1
%   'bottom':   all pixels with y=last
%
%   For 3D images, 2 additonal borders can be removed:
%   'front':    all pixels with z=1
%   'back':     all pixels with z=last
%
%   LBL2 = removeBorderRegions(LBL, BORDERS, RELABEL);
%   where RELABEL is a logical, specifies wheter remaining regions should
%   be relabeled or not (default is TRUE).
%
%   See also:
%   bwmorph
%
%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 23/04/2007
%

% HISTORY :
%   19/07/2007: add possibility to specify borders
%   07/08/2007: relabeling is now optional
%   01/02/2008: return binImg image if input is binImg

warning('matImage:deprecated', ...
    'function "removeBorderRegion" has been replaced by "imKillBorders"');

% default values
binImg  = false;
relabel = true;

% If image is binImg, convert to labeled image
if islogical(lbl)
    binImg = true;
    relabel = false;
    if ndims(lbl)==2 %#ok<ISMAT>
        lbl = bwlabel(lbl, 4);
    elseif ndims(lbl)==3
        lbl = bwlabeln(lbl, 6);
    end
end

% check if relabel flag is present
if ~isempty(varargin)
    if islogical(varargin{end})
        relabel = varargin{end};
        varargin(end) = [];
    end
end

% find borders to remove
borders = {'top', 'bottom', 'left', 'right'};
if ~isempty(varargin)
    if iscell(varargin{1})
        borders = varargin{1};
    else
        borders = varargin;
    end
end

% create mask for borders
mask = false(size(lbl));
if ndims(lbl)==2 %#ok<ISMAT>
    for i=1:length(borders)
        border = borders{i};
        if strcmp(border, 'left')
            mask(:,1) = true;
        elseif strcmp(border, 'right')
            mask(:,end) = true;
        elseif strcmp(border, 'top')
            mask(1,:) = true;
        elseif strcmp(border, 'bottom')
            mask(end,:) = true;
        end
    end
else
    for i=1:length(borders)
        border = borders{i};
        if strcmp(border, 'left')
            mask(:,1,:) = true;
        elseif strcmp(border, 'right')
            mask(:,end,:) = true;
        elseif strcmp(border, 'top')
            mask(1,:,:) = true;
        elseif strcmp(border, 'bottom')
            mask(end,:,:) = true;
        elseif strcmp(border, 'front')
            mask(:,:,1) = true;
        elseif strcmp(border, 'back')
            mask(:,:,end) = true;
        end
    end
end

% find labels of regions touching borders
lbl2 = unique(lbl(mask));

% remove label '0', which corresponds to background
if lbl2(1)==0
    lbl2 = lbl2(2:length(lbl2));
end

% set labels of border regions to 0
indices = ismember(lbl, lbl2);
lbl(indices)=0;

% Eventually relabel remaining regions by shifting labels
if relabel && ~isempty(lbl2)
    % For remaining regions, shift the labels
    for i=1:length(lbl2)-1
        indices = lbl>lbl2(i) & lbl<=lbl2(i+1);
        lbl(indices) = imsubtract(lbl(indices), i);
    end

    % Shift labels for regions whose index is greater than last index of LBL2.
    indices = lbl>lbl2(length(lbl2));
    lbl(indices) = imsubtract(lbl(indices), length(lbl2));
end

% convert to binImg image if needed
if binImg
    lbl = lbl>0;
end


function ppma_write ( file_name, r, g, b )

%*****************************************************************************80
%
%% PPMA_WRITE writes RGB data into an ASCII PPM file.
%
%  The PPMA file will have the format:
%
%    P3
%    # file_name created by Matlab PPMA_WRITE.
%    ncol nrow
%    maxrgb, the maximum legal value for the data.
%    row 1, a list of ncol triples between 0 and maxrgb.
%    row 2, a list of ncol triples between 0 and maxrgb.
%    ...
%    row nrow, a list of ncol triples between 0 and maxrgb.
%
%    Lines beginning with '#' are comments.
%
%  Example:
%
%    P3
%    # feep.ppma
%    4 4
%    15
%     0  0  0  0  0  0    0  0  0   15  0 15
%     0  0  0  0 15  7    0  0  0    0  0  0
%     0  0  0  0  0  0    0 15  7    0  0  0
%    15  0 15  0  0  0    0  0  0    0  0  0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string FILENAME, the name of the PPMA file to create.
%
%    Input, integer R(NROW,NCOL), G(NROW,NCOL), B(NROW,NCOL), the RGB data.
%
  fid = fopen ( file_name, 'wt' );

  if ( fid < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PPMA_WRITE - Fatal error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'PPMA_WRITE - Fatal error!' );
    return;
  end
%
%  First line identifies the file as a PPMA file.
%
  fprintf ( fid, 'P3\n' );
%
%  Second line is a comment with the filename and creator.
%
  fprintf ( fid, '# %s created by PPMA_IO::PPMA_WRITE.\n', file_name );
%
%  Third line holds NCOL and NROW.
%
  [nrow, ncol] = size ( r );
  fprintf ( fid, '%d %d\n', ncol, nrow );
%
%  Fourth line contains the maximum RGB value.
%
  maxr = max ( max ( r ) );
  maxg = max ( max ( g ) );
  maxb = max ( max ( b ) );
  maxrgb = max ( maxr, max ( maxg, maxb ) );
  fprintf ( fid, '%d\n', maxrgb );
%
%  Subsequent lines contain the RGB values, no more than 3 triples to a line.
%
  for i = 1 : nrow
    for j = 1 : ncol
      fprintf ( fid, '%d ', r(i,j), g(i,j), b(i,j) );
      if ( j == ncol || rem ( j, 3 ) == 0 )
        fprintf ( fid, '\n' );
      end
    end
  end

  fclose ( fid );

  return
end


function [ h, hmin, hmax ] = p19_stepsize ( option )

%*****************************************************************************80
%
%% P19_STEPSIZE returns step sizes for problem 19.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer OPTION, the option index.
%
%    Output, real H, HMIN, HMAX, suggested values for the
%    initial step, the minimum step, and the maximum step.
%
  h =    0.125000;
  hmin = 0.015625;
  hmax = 4.000000;

  return
end


function dy = scopy ( n, dx, incx, dy, incy )

%*****************************************************************************80
%
%% SCOPY copies a vector X to a vector Y.
%
%  Discussion:
%
%    The routine uses unrolled loops for increments equal to one.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 May 2006
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979.
%
%    Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
%    Basic Linear Algebra Subprograms for Fortran Usage,
%    Algorithm 539,
%    ACM Transactions on Mathematical Software,
%    Volume 5, Number 3, September 1979, pages 308-323.
%
%  Parameters:
%
%    Input, integer N, the number of elements in DX and DY.
%
%    Input, real DX(*), the first vector.
%
%    Input, integer INCX, the increment between successive entries of DX.
%
%    Input, real DY(*), the second vector, into which elements are copied.
%
%    Input, integer INCY, the increment between successive entries of DY.
%
%    Output, real DY(*), the second vector, with elements copied from DX.
%
  if ( n <= 0 )
    dy = [];
    return
  end

  if ( incx == 1 & incy == 1 )

    m = mod ( n, 7 );

    if ( m ~= 0 )

      dy(1:m) = dx(1:m);

    end

    for i = m+1 : 7 : n
      dy(i) = dx(i);
      dy(i + 1) = dx(i + 1);
      dy(i + 2) = dx(i + 2);
      dy(i + 3) = dx(i + 3);
      dy(i + 4) = dx(i + 4);
      dy(i + 5) = dx(i + 5);
      dy(i + 6) = dx(i + 6);
    end

  else

    if ( 0 <= incx )
      ix = 1;
    else
      ix = ( -n + 1 ) * incx + 1;
    end

    if ( 0 <= incy )
      iy = 1;
    else
      iy = ( -n + 1 ) * incy + 1;
    end

    for i = 1 : n
      dy(iy) = dx(ix);
      ix = ix + incx;
      iy = iy + incy;
    end

  end

  return
end


function [ y, j ] = j_borrow_english ( y, j )

%*****************************************************************************80
%
%% J_BORROW_ENGLISH borrows year-days from years in an English date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y, J, a YJ date.
%
  while ( j <= 0 )

    y = y - 1;

    days = year_length_english ( y );

    j = j + days;

  end

  return
end


function title = p01_title ( title )

%*****************************************************************************80
%
%% P01_TITLE returns the title of problem 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'F(X) = SIN(X) - 0.5 * X';

  return
end


function suite = test_assertElementsAlmostEqual
initTestSuite;

%===============================================================================
function test_happyCase

% All code here should execute with no error.
assertElementsAlmostEqual(1, 1 + sqrt(eps)/10);
assertElementsAlmostEqual(1, 1 + sqrt(eps)/10, 'custom message');

%===============================================================================
function test_failedAssertion

f = @() assertElementsAlmostEqual(1, 1 + 10*sqrt(eps));
assertExceptionThrown(f, 'assertElementsAlmostEqual:tolExceeded');

%===============================================================================
function test_nonFloatInputs()
assertExceptionThrown(@() assertElementsAlmostEqual('hello', 'world'), ...
    'assertElementsAlmostEqual:notFloat');

%===============================================================================
function test_sizeMismatch()
assertExceptionThrown(@() assertElementsAlmostEqual(1, [1 2]), ...
    'assertElementsAlmostEqual:sizeMismatch');

function test_finiteAndInfinite()
assertExceptionThrown(@() assertElementsAlmostEqual(1, Inf), ...
    'assertElementsAlmostEqual:tolExceeded');

function test_infiniteAndInfinite()
assertElementsAlmostEqual(Inf, Inf);

function test_finiteAndNaN()
assertExceptionThrown(@() assertElementsAlmostEqual(1, NaN), ...
    'assertElementsAlmostEqual:tolExceeded');

function test_nanAndNaN()
assertElementsAlmostEqual(NaN, NaN);

function test_plusMinusInfinity()
assertExceptionThrown(@() assertElementsAlmostEqual(+Inf, -Inf), ...
    'assertElementsAlmostEqual:tolExceeded');

function test_infiniteAndNaN()
assertExceptionThrown(@() assertElementsAlmostEqual(Inf, NaN), ...
    'assertElementsAlmostEqual:tolExceeded');


function n = p33_n ( )

%*****************************************************************************80
%
%% P33_N returns the number of variables for problem 33.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer N.  If N is positive, N represents the
%    only legal value for N for this problem.  If N is
%    negative, the absolute value of N is the least legal
%    value of N, but other values are allowable.
%
  n = 4;

  return
end


function i4vec_print ( n, a, title )

%*****************************************************************************80
%
%% I4VEC_PRINT prints an I4VEC.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the dimension of the vector.
%
%    Input, integer A(N), the vector to be printed.
%
%    Input, string TITLE, a title.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );
  fprintf ( 1, '\n' );

  for i = 1 : n
    fprintf ( 1, '%6d: %6d\n', i, a(i) );
  end

  return
end


%% Copyright (C) 2016 Lagu
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy 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 software 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 software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @deftypefun check_assumptions (@var{x})
%% Check if the input have valid assumptions.
%%
%% Private helper function.
%%
%% @seealso{sym}
%% @end deftypefun

function check_assumptions (x)

  ca_helper (x)

end

%% Is safer use a helper when private functions call it self for classdef.
function ca_helper (x)

  persistent valid_asm

  if (isempty (valid_asm))
    valid_asm = assumptions ('possible');
  end

  if (~islogical (x))
    if (isa (x, 'char'))
      assert (ismember (x, valid_asm), ['sym: the assumption "' x '" is not supported in your Sympy version.'])
    elseif (isstruct (x))
      fields = fieldnames (x);
      for j = 1:numel (fields)
        ca_helper (fields{j})
      end
    elseif (iscell (x))
      for j = 1:length (x)
        ca_helper (x{j})
      end
    else
      error ('sym: assumption must be a string or struct or cell')
    end
  end

end


function p21_default ( dim_num )

%*****************************************************************************80
%
%% P21_DEFAULT sets default values for problem 21.
%
%  Discussion:
%
%    If a problem uses vector parameters, then the spatial dimension
%    DIM_NUM is needed as input, so that the vector parameters can be
%    properly dimensioned.
%
%    Every problem keeps a count of the number of function calls.  Calling
%    this routine causes that count to be reset to 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the problem.
%
  i4 = 0;
  p21_i4 ( 'D', '*', i4 );

  r8 = 0.0;
  p21_r8 ( 'D', '*', r8 );

  i4vec = [];
  p21_i4vec ( 'D', '*', dim_num, i4vec );

  return
end


function [ y, next ] = p39_equil ( neqn, next )

%*****************************************************************************80
%
%% P39_EQUIL returns equilibrium solutions of problem p39.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Input, integer NEXT, the index of the previous
%    equilibrium, which should be 0 on first call.
%
%    Output, real Y(NEQN), the "next" equilibrium solution, if any.
%
%    Output, integer NEXT, the index of the current equilibrium,
%    or 0 if there are no more.
%
  next = 0;
  y = [];

  return
end


function [ y2, m2, d2, f2 ] = ymdf_next_gregorian ( y1, m1, d1, f1 )

%*****************************************************************************80
%
%% YMDF_NEXT_GREGORIAN returns the Gregorian YMDF date of the next day.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y1, M1, D1, real F1,
%    the YMDF date.
%
%    Output, integer Y2, M2, D2, real F2,
%    tomorrow's YMDF date.
%
  y2 = y1;
  m2 = m1;
  d2 = d1 + 1;
  f2 = f1;

  [ y2, m2, d2 ] = day_carry_gregorian ( y2, m2, d2 );

  return
end


function [cMap]=viridis(varargin)

% function [cMap]=viridis(n)
% ------------------------------------------------------------------------
% Creates the colormap data for the viridis colormap.
%
% This colormap is a MATLAB implementation of the matplotlib colormap by
% Nathaniel J. Smith, Stefan van der Walt, and Eric Firing.
%
% Kevin Mattheus Moerman
% gibbon.toolbox@gmail.com
%
% 2018/04/10
%------------------------------------------------------------------------

%%
switch nargin
    case 0
        n=[];
    case 1
        n=varargin{1};
end

%%

[cMap]=matplotlibColormap('viridis',n);

%%
% _*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 p = prior_unif(varargin)
%PRIOR_UNIF  Uniform prior structure
%
%  Description
%    P = PRIOR_UNIF creates uniform prior structure.
%
%  See also
%    PRIOR_*
%
% Copyright (c) 2009 Jarno Vanhatalo
% Copyright (c) 2010 Aki Vehtari

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

  ip=inputParser;
  ip.FunctionName = 'PRIOR_UNIFORM';
  ip.addOptional('p', [], @isstruct);
  ip.parse(varargin{:});
  p=ip.Results.p;

  if isempty(p)
    init=true;
    p.type = 'Uniform';
  else
    if ~isfield(p,'type') && ~isequal(p.type,'Uniform')
      error('First argument does not seem to be a valid prior structure')
    end
    init=false;
  end

  if init
    % set functions
    p.fh.pak = @prior_unif_pak;
    p.fh.unpak = @prior_unif_unpak;
    p.fh.lp = @prior_unif_lp;
    p.fh.lpg = @prior_unif_lpg;
    p.fh.recappend = @prior_unif_recappend;
  end

end

function [w, s, h] = prior_unif_pak(p, w)
  w=[];
  s={};
  h=[];
end

function [p, w] = prior_unif_unpak(p, w)
  w = w;
  p = p;
end

function lp = prior_unif_lp(x, p)
  lp = 0;
end

function lpg = prior_unif_lpg(x, p)
  lpg = zeros(size(x));
end

function rec = prior_unif_recappend(rec, ri, p)
% The parameters are not sampled in any case.
  rec = rec;
end


if mcs == 1879
    display('1879: Birth of Albert Einstein')
elseif mcs == 1955
    display('1955: Albert Einstein passed away')
elseif mcs == 1933
    display('1933: Albert Einstein, driven by the Nazis, took asylum in U.S.A')
elseif mcs == 1947
    display('Indian Independence')
    display('- - - - - - - - - -')
    display('Dr. B R Ambedkar became law minister of free independent India')
elseif mcs == 1114
    display('Birth of great mathematician bhAskarAchArya.')
    display('He wrote "sidhAnta samhita" which has 2 parts')
    display('1: Two mathematical parts.')
    display('2: Two astronomical parts.')
end

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


function z = trimr(x,n1,n2)
% PURPOSE: return a matrix (or vector) x stripped of the specified rows.
% -----------------------------------------------------
% USAGE: z = trimr(x,n1,n2)
% where: x = input matrix (or vector) (n x k)
%       n1 = first n1 rows to strip
%       n2 = last  n2 rows to strip
% NOTE: modeled after Gauss trimr function
% -----------------------------------------------------
% RETURNS: z = x(n1+1:n-n2,:)
% -----------------------------------------------------

% written by:
% James P. LeSage, Dept of Economics
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jpl@jpl.econ.utoledo.edu

  [n junk] = size(x);
  if (n1+n2) >= n;
     error('Attempting to trim too much in trimr');
  end;
  h1 = n1+1;
  h2 = n-n2;
  z = x(h1:h2,:);


function out = flattenMaskOverlay(img, mask, varargin)
% FLATTENMASKOVERLAY  Create a flattened image with overlayed mask (with transparency)
%  FLATTENMASKOVERLAY(IMG, MASK) applies a MASK (defined as logical) on top
%     of the original IMG and displays the result in the current axes. The
%     mask (locations of 1's) will be displayed as a red color with 50%
%     opacity. The resulting image will be a flat image (no use of
%     AlphaData), and therefore will have better interactive performance
%     (zooming, panning, data cursors). IMG must be MxN (gray scale) or
%     MxNx3 (RGB). Supported data types are double, uint8, uint16. MASK
%     must be an MxN logical array.
%
%  FLATTENMASKOVERLAY(IMG, MASK, ALPHALEVEL, OVERLAYCOLOR) specifies the
%     opacity level and the overlay color of the mask. ALPHALEVEL must be a
%     scalar between 0 to 1. Pass in [] for default (0.5). OVERLAYCOLOR can
%     be a string indicating the color (see list below) or a 1x3 double
%     array (0 to 1) representing the RGB values. Default is red.
%            b     blue
%            g     green
%            r     red
%            c     cyan
%            m     magenta
%            y     yellow
%            k     black
%            w     white
%
%  IM = FLATTENMASKOVERLAY(IMG, MASK, ...) returns the image data without
%     displaying the image.
%
%  Example:
%     load mandrill
%     rgb = ind2rgb(X, map);
%
%     subplot(2, 2, 1);
%     image(rgb); axis image off; title('Original image');
%
%     subplot(2, 2, 2);
%     % try to segment out the nose
%     mask = rgb(:, :, 1) > 0.8 & rgb(:, :, 2) < 0.3 & rgb(:, :, 3) < 0.3;
%     image(mask); colormap(gray(2)); axis image off; title('Mask image');
%
%     subplot(2, 2, 3);
%     flattenMaskOverlay(rgb, mask, [], 'g');
%     title('Green mask with 50% opacity');
%
%     subplot(2, 2, 4);
%     flattenMaskOverlay(rgb, mask, 1, 'g');
%     title('Green mask with 100% opacity');

% Jiro Doke
% v1.0 - Nov 2011
% v1.1 - Nov 2011. Bug in default alphaLevel and typo in example.
%
% Copyright 2011 The MathWorks, Inc.

%%

% Default alpha level
DEFAULT_ALPHA = 0.5;

% Default overlay color
DEFAULT_COLOR = [1 0 0];

% Image size
sz = size(img);

%% Input Validation
p = inputParser();
p.addRequired('img', @isvalidImageData);
p.addRequired('mask', @(x) isvalidMaskData(x, sz));
p.addOptional('alphaLevel', DEFAULT_ALPHA, @(x) ...
    assert(isempty(x) || ...
    (isa(x, 'double') && numel(x) == 1 && x >= 0 && x <= 1), ...
    sprintf('%s:InvalidAlphaLevel', mfilename), ...
        '''alphaLevel'' must be a scalar between [0, 1]'));
p.addOptional('overlayColor', DEFAULT_COLOR, @(x) ...
    validateattributes(x, {'char', 'double'}, {'2d'}));

p.parse(img, mask, varargin{:});

img = p.Results.img;
mask = p.Results.mask;
alphaLevel = p.Results.alphaLevel;
overlayColor = p.Results.overlayColor;

if isempty(alphaLevel)
    alphaLevel = DEFAULT_ALPHA;
end

if ischar(overlayColor)
    switch lower(overlayColor)
        case {'y','yellow'}
            overlayColor = [1 1 0];
        case {'m','magenta'}
            overlayColor = [1 0 1];
        case {'c','cyan'}
            overlayColor = [0 1 1];
        case {'r','red'}
            overlayColor = [1 0 0];
        case {'g','green'}
            overlayColor = [0 1 0];
        case {'b','blue'}
            overlayColor = [0 0 1];
        case {'w','white'}
            overlayColor = [1 1 1];
        case {'k','black'}
            overlayColor = [0 0 0];
        case {''}
            overlayColor = DEFAULT_COLOR;
        otherwise
            error(sprintf('%s:UnknownOverlayColor', mfilename), ...
                'Unknown overlayColor "%s".', overlayColor);
    end
else
    if isempty(overlayColor)
        overlayColor = DEFAULT_COLOR;
    end
    assert(isequal(size(overlayColor), [1 3]) && ...
        nnz(overlayColor < 0 | overlayColor > 1) == 0, ...
        sprintf('%s:InvalidOverlayColor', mfilename), ...
        '''overlayColor'' must be a 1x3 array between [0, 1]');
end

%% Create overlay
rMask = mask * overlayColor(1);
gMask = mask * overlayColor(2);
bMask = mask * overlayColor(3);

[img_r, img_g, img_b] = getDoubleRGB(img);

% Red plane
tmp = img_r + (rMask - img_r) * alphaLevel;
img_r(mask) = tmp(mask);

% Blue plane
tmp = img_g + (gMask - img_g) * alphaLevel;
img_g(mask) = tmp(mask);

% Green plane
tmp = img_b + (bMask - img_b) * alphaLevel;
img_b(mask) = tmp(mask);

% Convert back to the original data type
if isa(img, 'double');
    finalImg = cat(3, img_r, img_g, img_b);
else
    finalImg = cast(cat(3, img_r, img_g, img_b) * ...
        double(intmax(class(img))), class(img));
end

if nargout == 0
    image(finalImg); axis image off
else
    out = finalImg;
end

end

%% Validate IMG
function tf = isvalidImageData(img)

tf = true;
validateattributes(img, {'double', 'uint8', 'uint16'}, {'nonempty'}, ...
    mfilename, 'img');

if isa(img, 'double')
    % Check that the values are between 0 and 1
    assert(nnz(img < 0 | img > 1) == 0, ...
        sprintf('%s:InvalidDoubleImageRange', mfilename), ...
        'Values in a double ''img'' must be between [0, 1].');

end

% IMG should be a 2D or an MxNx3 array
sz = size(img);
assert((numel(sz) == 2) || (numel(sz) == 3 && sz(3) == 3), ...
    sprintf('%s:InvalidImageSize', mfilename), ...
    'Size of ''img'' must be MxN or MxNx3.');

end

%% Validate MASK
function tf = isvalidMaskData(mask, sz)

tf = true;
thisSZ = size(mask);
assert(isequal(thisSZ, sz(1:2)), ...
    sprintf('%s:InvalidMaskSize', mfilename), ...
    'Size of ''mask'' must be %dx%d.', sz(1), sz(2));

end

%% Convert IMG to MxNx3 double array
function [r, g, b] = getDoubleRGB(img)

if ndims(img) == 2
    img = repmat(img, [1 1 3]);
end

if isa(img, 'double')
    newImg = img;
else
    newImg = double(img) / double(intmax(class(img)));
end
r = newImg(:, :, 1);
g = newImg(:, :, 2);
b = newImg(:, :, 3);

end


function asa266_test ( )

%*****************************************************************************80
%
%% ASA266_TEST tests the ASA266 library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 August 2010
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ASA266_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Tests for the ASA266 package.\n' );

  asa266_test01 ( );
  asa266_test02 ( );
  asa266_test03 ( );
  asa266_test04 ( );
  asa266_test05 ( );
  asa266_test06 ( );
  asa266_test07 ( );
  asa266_test08 ( );
  asa266_test09 ( );
  asa266_test10 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ASA266_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end


function [ t_start, y_start ] = p26_start ( neqn )

%*****************************************************************************80
%
%% P26_START returns the starting point for problem p26.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Output, real T_START, Y_START(NEQN,1), the initial data.
%
  y_start = zeros ( neqn, 1 );

  t_start = 0.0;
  y_start = [ 0.0; 0.0 ];

  return
end


function n = p31_n ( )

%*****************************************************************************80
%
%% P31_N returns the number of variables for problem 31.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer N.  If N is positive, N represents the
%    only legal value for N for this problem.  If N is
%    negative, the absolute value of N is the least legal
%    value of N, but other values are allowable.
%
  n = 4;

  return
end


function x = forloop(x, n, f, cleanup_fcn)

% x = forloop(x, n, f, cleanup_fcn)
%
% Loop a given number of times. f should be a function handle taking in
% x and k, the iteration number (which starts at 1), and returning the
% updated x. If x is a cell array, each cell is handed to f as in
% f(x{:}), which allows f to have the form @(x1, x2,..., k).
%
% forloop(1,                        % Start with x = 1.
%         9,                        % Loop 9 times.
%         @(x, k) last(fprintf('Factorial(%d): %d\n', k, k*x), ...
%                      k*x))        % Print the result and return k*x.
%
% Tucker McClure
% Copyright 2013 The MathWorks, Inc.

    for k = 1:n
        if iscell(x)
            x = f(x{:}, k);
        else
            x = f(x, k);
        end
    end

    if nargin == 4
        if iscell(x)
            x = cleanup_fcn(x{:});
        else
            x = cleanup_fcn(x);
        end
    end

end


function [node,elem]=readsmf(fname)
%
% [node,elem]=readsmf(fname)
%
% read simple model format (SMF)
%
% author: Qianqian Fang, <q.fang at neu.edu>
% date: 2007/11/21
%
% input:
%    fname: name of the	SMF data file
%
% output:
%    node: node coordinates of the mesh
%    elem: list of elements of the mesh
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%
node=[];
elem=[];
fid=fopen(fname,'rt');
while(~feof(fid))
    line=fgetl(fid);
    if(line(1)=='v')
        dd=sscanf(line,'v %f %f %f');
        if(length(dd)==3)
            node=[node;dd];
        end
    elseif(line(1)=='f')
        dd=sscanf(line,'f %d %d %d');
        if(length(dd)==3)
            elem=[elem;dd];
        end
    end
end
fclose(fid);
node=reshape(node,3,length(node)/3)';
elem=reshape(elem,3,length(elem)/3)';


function sample_runscript_matlab(doParallelize,saveIncrement,fileName)
% SAMPLE_RUNSCRIPT_MATLAB  Template function for looping over a hctsa analysis when
%                           using local Matlab files (initializing with TS_init).
%
%---INPUTS:
% doParallelize, (binary) whether to parallelize computations over available
%                   CPUs using Matlab's Parallel Computing Toolbox (default: 1).
% saveIncrement, saves the results back to the hctsa file after computing for
%               this many time series (default: 5)
% fileName, the source of the HCTSA dataset (a .mat file)
%
%---EXAMPLE USAGE:
% sample_runscript_matlab(1,'HCTSA.mat');

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This work is licensed under the Creative Commons
% Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of
% this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send
% a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View,
% California, 94041, USA.
% ------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
% Set parameters for computation:
%-------------------------------------------------------------------------------
if nargin < 1
    % Set to 1 to
    doParallelize = true;
end

if nargin < 2
    saveIncrement = 5;
end

if nargin < 3
    fileName = 'HCTSA.mat';
end

% ------------------------------------------------------------------------------
%% Preparations:
% ------------------------------------------------------------------------------
% Get IDs of all time series in the hctsa datafile:
[~,TimeSeries,Operations] = TS_LoadData(fileName);
tsIDs = TimeSeries.ID;

% Set the IDs to compute at each iteration:
ID_inc = 1:saveIncrement:length(tsIDs)+1;

% Provide a quick message:
fprintf(1,['About to calculate across %u time series and %u operations ' ...
                'saving back to file every %u time series\n'], ...
                height(TimeSeries),height(Operations),saveIncrement);

%-------------------------------------------------------------------------------
% Running calculations:
%-------------------------------------------------------------------------------
% Loop across time series:
for i = 1:length(ID_inc)-1
	fprintf(1,'\n\n\nWe''re looking at time series with IDs from %u--%u\n\n\n', ...
                            	tsIDs(ID_inc(i)),tsIDs(ID_inc(i+1)-1));

    % Compute any missing values for this range of time series, then save back:
    TS_Compute(doParallelize,tsIDs(ID_inc(i):ID_inc(i+1)-1),[],'missing',fileName);
end


function subplots(data, varargin)
    figureTitle = '';
    numRows = [];
    numCols = [];
    xAxis = [];
    linkingAxes = 1;

    for i=1:length(varargin)
        if(ischar(varargin{i}) || isscalar(varargin{i}))
            switch(varargin{i})
                case 'Title'
                    figureTitle = varargin{i+1};
                case 'NumRows'
                    numRows = varargin{i+1};
                case 'NumCols'
                    numCols = varargin{i+1};
                case 'LinkingAxes'
                    linkingAxes = varargin{i+1};
                case {'XAxis', 'xAxis'}
                    xAxis = varargin{i+1};
            end
        end
    end

    if(isempty(numCols) && isempty(numRows))
        numRows = size(data,2);
        numCols = 1;
    elseif(~isempty(numCols) && isempty(numRows))
        numRows = ceil(size(data,2)/numCols);
    end

    figure('Name',figureTitle);
    %subplot(numRows, numCols, 1);
    if(isempty(xAxis))
        xAxis = (1:length(data));
    end
    ah = [];
    for i=1:size(data,2)
        ah(i) = subplot(numRows, numCols, i);
        plot(xAxis, data(:,i));
    end
    if(linkingAxes)
        linkaxes(ah);
    end
end


function [ t_start, y_start ] = p23_start ( neqn )

%*****************************************************************************80
%
%% P23_START returns the starting point for problem p23.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Output, real T_START, Y_START(NEQN,1), the initial data.
%
  y_start = zeros ( neqn, 1 );

  t_start = 0.0;
  y_start = [ 0.0; 0.0 ];

  return
end


function tests = test_imSurfaceArea(varargin)
% Test case for the file imSurfaceArea.
%
%   output = test_imSurfaceArea(input)
%
%   Example
%   test_imSurfaceArea
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% Created: 2010-10-08,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRAE - Cepia Software Platform.

tests = functiontests(localfunctions);

function testAddBorderD3(testCase)

img = ones([5 5 5]) > 0;
imgb = padarray(img, [1 1 1]) > 0;

nDir = 3;
b = imSurfaceArea(img, nDir);
bb = imSurfaceArea(imgb, nDir);
assertEqual(testCase, b, bb);

function testAddBorderD13(testCase)

img = ones([5 5 5]) > 0;
imgb = padarray(img, [1 1 1]) > 0;

nDir = 13;
b = imSurfaceArea(img, nDir);
bb = imSurfaceArea(imgb, nDir);
assertEqual(testCase, b, bb);

function test_Anisotropic(testCase)

img = ones([5 5 5]) > 0;
imgb = padarray(img, [1 1 1]) > 0;

nDir = 3;
b = imSurfaceArea(img, nDir, [1 2 3]);
bb = imSurfaceArea(imgb, nDir, [1 2 3]);
assertEqual(testCase, b, bb);

function test_Labels_D3(testCase)

img = zeros([5 5 5]);
img(1:3, 1:3, 1:3) = 1;
img(4:5, 1:3, 1:3) = 2;
img(1:3, 4:5, 1:3) = 3;
img(4:5, 4:5, 1:3) = 4;
img(1:3, 1:3, 4:5) = 5;
img(4:5, 1:3, 4:5) = 6;
img(1:3, 4:5, 4:5) = 7;
img(4:5, 4:5, 4:5) = 8;

b3 = imSurfaceArea(img, 3);
assertEqual(testCase, 8, length(b3));

imgb = padarray(img, [1 1 1]);
bb3 = imSurfaceArea(imgb, 3);

assertEqual(testCase, b3, bb3);

function test_Labels_D13(testCase)

img = zeros([5 5 5]);
img(1:3, 1:3, 1:3) = 1;
img(4:5, 1:3, 1:3) = 2;
img(1:3, 4:5, 1:3) = 3;
img(4:5, 4:5, 1:3) = 4;
img(1:3, 1:3, 4:5) = 5;
img(4:5, 1:3, 4:5) = 6;
img(1:3, 4:5, 4:5) = 7;
img(4:5, 4:5, 4:5) = 8;

b13 = imSurfaceArea(img, 13);
assertEqual(testCase, 8, length(b13));

imgb = padarray(img, [1 1 1]);
bb13 = imSurfaceArea(imgb, 13);
assertEqual(testCase, b13, bb13);

function test_Labels2_D3(testCase)

img = zeros([5 5 5]);
img(1:3, 1:3, 1:3) = 2;
img(4:5, 1:3, 1:3) = 3;
img(1:3, 4:5, 1:3) = 5;
img(4:5, 4:5, 1:3) = 7;
img(1:3, 1:3, 4:5) = 11;
img(4:5, 1:3, 4:5) = 13;
img(1:3, 4:5, 4:5) = 17;
img(4:5, 4:5, 4:5) = 19;

[b3, labels3] = imSurfaceArea(img, 3);

assertEqual(testCase, 8, length(b3));
assertEqual(testCase, 8, length(labels3));
assertEqual(testCase, labels3, [2 3 5 7 11 13 17 19]');

function test_Labels2_D13(testCase)

img = zeros([5 5 5]);
img(1:3, 1:3, 1:3) = 2;
img(4:5, 1:3, 1:3) = 3;
img(1:3, 4:5, 1:3) = 5;
img(4:5, 4:5, 1:3) = 7;
img(1:3, 1:3, 4:5) = 11;
img(4:5, 1:3, 4:5) = 13;
img(1:3, 4:5, 4:5) = 17;
img(4:5, 4:5, 4:5) = 19;

[b13, labels13] = imSurfaceArea(img, 13);

assertEqual(testCase, 8, length(b13));
assertEqual(testCase, 8, length(labels13));
assertEqual(testCase, labels13, [2 3 5 7 11 13 17 19]');


function column_num = file_column_count ( input_file_name )

%*****************************************************************************80
%
%% FILE_COLUMN_COUNT counts the columns in the first line of a file.
%
%  Discussion:
%
%    The file is assumed to be a simple text file.
%
%    Most lines of the file are presumed to consist of COLUMN_NUM words,
%    separated by spaces.  There may also be some blank lines, and some
%    comment lines, which have a "#" in column 1.
%
%    The routine tries to find the first non-comment non-blank line and
%    counts the number of words in that line.
%
%    If all lines are blanks or comments, it goes back and tries to analyze
%    a comment line.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILE_NAME, the name of the file.
%
%    Output, integer COLUMN_NUM, the number of columns in the file.
%
  FALSE = 0;
  TRUE = 1;
%
%  Open the file.
%
  input_unit = fopen ( input_file_name );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_COLUMN_COUNT - Error!\n' );
    fprintf ( 1, '  Could not open the file "%s".\n', input_file_name );
    error ( 'FILE_COLUMN_COUNT - Error!' );
  end
%
%  Read one line, but skip blank lines and comment lines.
%  Use FGETL so we drop the newline character!
%
  got_one = FALSE;

  while ( 1 )

    line = fgetl ( input_unit );

    if ( line == -1 )
      break;
    end

    if ( s_len_trim ( line ) == 0 )

    elseif ( line(1) == '#' )

    else
      got_one = TRUE;
      break;
    end

  end

  fclose ( input_unit );

  if ( got_one == FALSE )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_COLUMN_COUNT - Warning!\n' );
    fprintf ( 1, '  The file does not seem to contain any data.\n' );
    column_num = -1;
    return
  end

  column_num = s_word_count ( line );

  return
end


function x = rosser1_null_right ( )

%*****************************************************************************80
%
%% ROSSER1_NULL_RIGHT returns a right null vector of the ROSSER1 matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real X(8,1), the null vector.
%
  x = [ ...
    1.0; ...
    2.0; ...
   -2.0; ...
   -1.0; ...
   14.0; ...
   14.0; ...
    7.0; ...
    7.0 ];

  return
end


function title = p40_title ( )

%*****************************************************************************80
%
%% P40_TITLE returns a title for problem 40.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = 'The Bohachevsky Function #3';

  return
end


function [flag] = IsRow(v,n)
% Default setting
flag = false;

% Get vector dimensions
[a,b] = size(v);

% Check it is a column
if a == 1 && nargin == 1
    flag = true;
    return;
end

% Otherwise check its length against n
if b == n           % Is not same length
    flag = true;
    return
end
end


function seed(new_seed)
%SEED Set new seed for function RANDOM0
% Function SEED sets a new seed for function
% RANDOM0.  The new seed should be a positive
% integer.

% Define variables:
%   iseed    -- Random number seed (global)
%   new_seed -- New seed
%
%  Record of revisions:
%      Date       Programmer          Description of change
%      ====       ==========          =====================
%    02/04/07    S. J. Chapman        Original code

% Declare global values
global iseed            % Seed for random number generator

% Check for a legal number of input arguments.
msg = nargchk(1,1,nargin);
error(msg);

% Save seed
new_seed = round(new_seed);
iseed = abs(new_seed);


% PQ_SIZE returns the number of elements in the priority queue
%
% SYNTAX
% sz = pq_size(pq)
%
% INPUT PARAMETERS
%   pq: a pointer to the priority queue
%
% OUTPUT PARAMETERS
%   sz:  the number of elements in the priority queue
%
% DESCRIPTION
% Queries the priority queue for the number of elements that it contains.
% This number is not the "capacity" or the maximum number of elements which
% is possible to insert but rather the number of elements CURRENTLY in the
% priority queue
%
% See also:
% PQ_DEMO, PQ_CREATE, PQ_PUSH, PQ_POP, PQ_SIZE, PQ_TOP, PQ_DELETE
%
% References:
% Gormen, T.H. and Leiserson, C.E. and Rivest, R.L., "introduction to
% algorithms", 1990, MIT Press/McGraw-Hill, Chapter 6.

% Copyright (c) 2008 Andrea Tagliasacchi
% All Rights Reserved
% email: andrea.tagliasacchi@gmail.com
% $Revision: 1.0$  Created on: May 22, 2009


function write_filter(weight, file_name);
[filter_len, N_ch] = size(weight);
FID = fopen(file_name,'w');

fprintf(FID, '%f\n',filter_len);
fprintf(FID, '%f\n',N_ch);

for i=1:N_ch,
    for j=1:filter_len
        fprintf(FID, '%f ',weight(j,i));
    end
    fprintf(FID,'\n');
end
fclose(FID);


function p23_default ( dim_num )

%*****************************************************************************80
%
%% P23_DEFAULT sets default values for problem 23.
%
%  Discussion:
%
%    If a problem uses vector parameters, then the spatial dimension
%    DIM_NUM is needed as input, so that the vector parameters can be
%    properly dimensioned.
%
%    Every problem keeps a count of the number of function calls.  Calling
%    this routine causes that count to be reset to 0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the problem.
%
  i4 = 0;
  p23_i4 ( 'D', '*', i4 );

  r8 = 0.0;
  p23_r8 ( 'D', '*', r8 );

  i4vec = [];
  p23_i4vec ( 'D', '*', dim_num, i4vec );

  return
end


function fd1d_display ( prefix )

%*****************************************************************************80
%
%% FD1D_DISPLAY displays data for a 1D finite difference function.
%
%  Discussion:
%
%    The function is represented as the sum of piecewise linear functions.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Usage:
%
%    fd1d_display ( 'prefix' )
%
%    where
%
%    'prefix_nodes.txt'    contains the point coordinates;
%    'prefix_values.txt'   contains the point values.
%
%  Parameters:
%
%    Input, string PREFIX, the prefix of the input files.
%
  fprintf ( 1, '\n' );
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_DISPLAY\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read files defining a finite difference computatation,\n' );
  fprintf ( 1, '  involving a set of nodes, and values of one or more\n' );
  fprintf ( 1, '  functions at those nodes.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Plot the functions in a MATLAB graphics window.\n' );
%
%  First argument is the file prefix.
%
  if ( nargin < 1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FD1D_DISPLAY:\n' );
    prefix = input ( '  Enter the common prefix of the files (in ''quotes''!).\n' );
  end
%
%  Get the node coordinates.
%
  node_filename = strcat ( prefix, '_nodes.txt' );
  node_x = load ( node_filename );
%
%  Get the function data.
%
  value_filename = strcat ( prefix, '_values.txt' );
  node_value = load ( value_filename );
%
%  Make the plot.
%
  clf

  plot ( node_x, node_value )
  hold on
  plot ( node_x, node_value, '*' )

  grid

  title_string = s_escape_tex ( prefix );
  title ( title_string );
  xlabel ( 'X axis' );
  ylabel ( 'Function values' );

  hold off
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FD1D_DISPLAY\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function s2 = s_escape_tex ( s1 )

%*****************************************************************************80
%
%% S_ESCAPE_TEX de-escapes TeX escape sequences.
%
%  Discussion:
%
%    In particular, every occurrence of the characters '\', '_',
%    '^', '{' and '}' will be replaced by '\\', '\_', '\^',
%    '\{' and '\}'.  A TeX interpreter, on seeing these character
%    strings, is then likely to return the original characters.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 January 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S1, the string to be de-escaped.
%
%    Output, string S2, a copy of the string, modified to avoid TeX escapes.
%
  s1_length = length ( s1 );

  s1_pos = 0;
  s2_pos = 0;
  s2 = [];

  while ( s1_pos < s1_length )

    s1_pos = s1_pos + 1;

    if ( s1(s1_pos) == '\' | ...
         s1(s1_pos) == '_' | ...
         s1(s1_pos) == '^' | ...
         s1(s1_pos) == '{' | ...
         s1(s1_pos) == '}' )
      s2_pos = s2_pos + 1;
      s2 = strcat ( s2, '\' );
    end

    s2_pos = s2_pos + 1;
    s2 = strcat ( s2, s1(s1_pos) );

  end

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


%% Reference Frame Alignment
%
%%
% The most important difference between MTEX and many other EBSD software
% is that in MTEX the Euler angle reference is always the map reference
% frame. This mean the $x$ and $z$ axes of the map are exactly the rotation
% axes of the Euler angles.
%
% In case the map coordinates and the Euler angles in your data are with
% respect to different reference frames it is highly recommended to correct
% for this while importing the data into MTEX. This section explains in
% detail how to do this.
%
%% On Sreen Orientation of the EBSD Map
%
% Many people are concerned when the images produced by MTEX are not
% aligned exactly as they are in their commercial software. It is indeed
% very important to understand exactly the alignment of your data. However,
% the important point is not whether a map is upside down on your screen or
% not. The important point is how your map aligns with the specimen, as we
% want to use the map to describe properties of the specimen.
%
% There are basically two components in an EBSD data set that refer to the
% specimen reference frame: the spatial coordinates $x$, $y$ and the Euler
% angles $\phi_1$, $\Phi$, $\phi_2$. To explain the difference have a look
% at the EDAX export dialog
%
% <<edax_coordinate_systems.png>>
%
% Here we have the axes $x$ and $y$ which describe how the map coordinates
% needs to be interpreted and the axes $A_1$, $A_2$, $A_3$ which describe
% how the Euler angles, and in consequence, the pole figures needs to be
% interpreted. We see that in none of these settings the map reference
% system coincides with the Euler angle reference frame.
%
% This situation is not specific to EDAX but occurs as well with EBSD data
% from Oxford or Bruker, all of them using different reference system
% alignments. For that reason MTEX strongly recommends to transform the data
% such that both map coordinates and Euler angles refer to the same
% coordinate system.
%
% Doing this we have two choices:
%
% # transform everything to the reference system $x$, $y$ using the option
% |'convertEuler2SpatialReferenceFrame'|. This will keep the map
% coordinates while changing the Euler angles
% # transform everything to the reference system $A_1$, $A_2$, $A_3$ using
% the option |'convertSpatial2EulerReferenceFrame'|. This will keep the
% Euler angles while changing the map coordinates.
%
% In the case of EDAX data imported from an |*.ang| file we still need to
% specify the export option used by the EDAX software. This is done by the
% options |'setting 1'|, |'setting 2'|, |'setting 3'| or |'setting 4'|.
%
% Since setting 2 is default for most EDAX exports a typical command for
% importing data from an ang file would look like this

ebsd = EBSD.load([mtexEBSDPath filesep 'olivineopticalmap.ang'],...
  'convertEuler2SpatialReferenceFrame','setting 2')

plot(ebsd('olivine'),ebsd('olivine').orientations,'coordinates','on')

%%
% The plot does not yet fit the alignment of the map in the EDAX software
% as it plots the x-axis be default to east and the z-axis into the plane.
% This is only a plotting convention and can be set in MTEX by

plotx2east
plotzIntoPlane

plot(ebsd('olivine'),ebsd('olivine').orientations,'coordinates','on')

%%
% Other plotting conventions are |plotx2north|, |plotx2west|, |plotx2south|
% and |plotzOutOfPlane|. Note that these options only alter the orientation
% of the EBSD map and the pole figures on the screen but does not change
% any data.
%
%% Verify the reference system
% One way of verifying the reference systems is to visualize crystal shapes
% on top of the orientation map. To do this we proceed as follows

% reconstruct grains
grains = calcGrains(ebsd('indexed'));

% chose the correct crystal shape (cubic, hex are generic forms)
cS = crystalShape.olivine;

% select only large grains
largeGrains = grains(grains.grainSize>500)

% and plot the crystal shapes
hold on
plot(largeGrains,cS)
hold off

%%
% It may also be helpful to inspect pole figures

h = Miller({1,0,0},{0,1,0},{0,0,1},ebsd('O').CS);
plotPDF(ebsd('O').orientations,h,'contourf')

%%
% As pole figures display data relative to the specimen reference frame
% MTEX automatically aligns them on the screen exactly as the spatial map
% above, i.e., according to our last definition with x pointing towards
% east and y to the south.
%
%% Change the map reference system
% In order to manually change the map reference frame one may apply a
% rotation to the map coordinates only. E.g. to flip the map left to right
% while preserving the Euler angles one can do

rot = rotation.byAxisAngle(yvector,180*degree);
ebsd_rot = rotate(ebsd,rot,'keepEuler');

% reconstruct grains
grains = calcGrains(ebsd_rot('indexed'));

% select only large grains
largeGrains = grains(grains.grainSize>500);

plot(ebsd_rot('olivine'),ebsd_rot('olivine').orientations,'coordinates','on')

% and plot the crystal shapes
hold on
plot(largeGrains,cS)
hold off

%% Change the Euler angle reference system
% Analogously we may change the Euler angle reference frame while keeping
% the map coordinates

ebsd_rot = rotate(ebsd,rot,'keepXY');

% reconstruct grains
grains = calcGrains(ebsd_rot('indexed'));

% select only large grains
largeGrains = grains(grains.grainSize>500);

plot(ebsd_rot('olivine'),ebsd_rot('olivine').orientations,'coordinates','on')

% and plot the crystal shapes
hold on
plot(largeGrains,cS)
hold off

%% Changing both reference system simultaneously
%
% Sometimes it is necessary to relate the EBSD data to a different external
% reference frame, or to  change the external reference frame from one to
% the other, e.g. if one wants to concatenate several ebsd data sets where
% the mounting was not done in perfect coincidence. In these cases the data
% has to be rotated or shifted by the commands <EBSD.rotate.html rotate>
% and <EBSD.shift.html shift>. The following commands rotate both reference
% frames of the entire data set by 5 degree about the z-axis.

% define a rotation
rot = rotation.byAxisAngle(zvector,5*degree);

% rotate the EBSD data
ebsd_rot = rotate(ebsd,rot);

% reconstruct grains
grains = calcGrains(ebsd_rot('indexed'));

% select only large grains
largeGrains = grains(grains.grainSize>500);

plot(ebsd_rot('olivine'),ebsd_rot('olivine').orientations,'coordinates','on')

% and plot the crystal shapes
hold on
plot(largeGrains,cS)
hold off


function r = isfinite(a)
%ISFINITE     Array of 1's for finite components
%
%   r = isfinite(a)
%

% written  04/04/04     S.M. Rump
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  r = reshape( isfinite(a.x(:)') & all(isfinite(a.dx),1) & all(isfinite(a.hx),1) , size(a.x) );


function imagescg(im)
% imagescg(im)
% Uses colormap('gray') for the imagecs
imagesc(im)
colormap('gray')


function test_suite = test_midPoint
% One-line description here, please.
%   output = testMidPoint(input)
%
%   Example
%   testMidPoint
%
%   See also
%
%
% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2009-04-22,    using Matlab 7.7.0.471 (R2008b)
% Copyright 2009 INRA - Cepia Software Platform.

test_suite = functiontests(localfunctions);

function test_twoPoints(testCase) %#ok<*DEFNU>

p1 = [10 20];
p2 = [30 40];
exp = [20 30];
mid = midPoint(p1, p2);
testCase.assertEqual(exp, mid);

function test_twoPointArrays(testCase)

p1 = [ ...
    10 20 ; ...
    30 40 ; ...
    50 60 ; ...
    ];
p2 = [ ...
    30 40; ...
    50 60; ...
    70 80];
exp = [...
    20 30; ...
    40 50; ...
    60 70];

mid = midPoint(p1, p2);
testCase.assertEqual(exp, mid);

function test_pointArray(testCase)

p1 = [30 40];
p2 = [ ...
    30 40; ...
    50 60; ...
    70 80];
exp = [...
    30 40; ...
    40 50; ...
    50 60];

mid = midPoint(p1, p2);
testCase.assertEqual(exp, mid);

function test_arrayPoint(testCase)

p1 = [ ...
    10 20 ; ...
    30 40 ; ...
    50 60 ; ...
    ];
p2 = [30 40];
exp = [...
    20 30; ...
    30 40; ...
    40 50];

mid = midPoint(p1, p2);
testCase.assertEqual(exp, mid);

function test_returnTwoOutputs(testCase)

p1 = [ ...
    10 20 ; ...
    30 40 ; ...
    50 60 ; ...
    ];
p2 = [30 40];

expX = [20 ; 30 ; 40];
expY = [30 ; 40 ; 50];

[x, y] = midPoint(p1, p2);
testCase.assertEqual(expX, x);
testCase.assertEqual(expY, y);

function test_edge(testCase)

edge = [10 20 30 40];
exp = [20 30];
mid = midPoint(edge);
testCase.assertEqual(exp, mid);

function test_edgeArray(testCase)

edge = [10 20 30 40; 30 40 50 60; 50 60 70 80];
exp = [20 30;40 50; 60 70];
mid = midPoint(edge);
testCase.assertEqual(exp, mid);


function[]=xlin
% XLIN   Sets x-axis scale to linear.
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2004--2015 J.M. Lilly --- type 'help jlab_license' for details

set(gca,'xscale','linear')

%Update for compatibility with ZOOL
if isappdata(gcf,'xlimitslock')
   if getappdata(gcf,'xlimitslock')
      h=gca;
      hall=axeshandles;
      for i=1:length(hall)
         axes(hall(i))
         set(gca,'xscale','linear')
      end
      axes(h)
   end
end


function[h]=vlines(x,sty)
%VLINES   Add vertical lines to a plot.
%
%   VLINES(X,STYLE) puts vertical lines at locations X having style
%   described by the string STYLE.  VLINES draws the lines to fit the
%   current axis.
%
%   The SYTLE strings follow the format specified in LINESTYLE.  Thus
%   STYLE='2b--' draws blue dotted lines of width 2.
%
%   VLINES(X) uses the default STYLE='g--', a green dashed line.
%
%   H=VLINES(...) returns an array of handles H to the lines.
%
%   See also HLINES, DLINES.
%   __________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2000--2016 J.M. Lilly --- type 'help jlab_license' for details

if strcmpi(x,'--t')
    return
end

if nargin==1
	sty='g--';
end
hold on

x=x(:)';
ax=axis;
y1=ax(3)*ones(size(x));
y2=ax(4)*ones(size(x));
x=[x;x];
y=[y1;y2];
y(y==0)=1e-16;
h=plot(x,y);
linestyle(h,sty);
axis(ax)

if nargout==0
   clear h
end


function expInfo = exportInfo(guifile)
%EXPORTINFO     Extract useful info from a CHEBGUI object for exporting.
%
% Calling sequence
%
%   EXPINFO = EXPORTINFO(GUIFILE)
%
% where
%
%   GUIFILE:    A CHEBGUI object
%   EXPINFO:    A struct, containing fields with information for exporting to an
%               .m-file.

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

% Extract information from the GUI fields
dom = guifile.domain;
deInput = guifile.DE;
bcInput = guifile.BC;
initInput = guifile.init;

% Wrap all input strings in a cell (if they're not a cell already)
if ( isa(deInput, 'char') )
     deInput = cellstr(deInput);
end

if ( isa(bcInput, 'char') )
     bcInput = cellstr(bcInput);
end

if ( isa(initInput, 'char') )
     initInput = cellstr(initInput);
end

% Obtain useful strings describing the differential equation part:
[deString, allVarString, indVarNameDE, dummy, dummy, dummy, allVarNames] = ...
    setupFields(guifile, deInput, 'DE');

% Do some error checking before we do further printing. Check that independent
% variable name match.

% Ensure that no EIG specific variables appear:
eigNames = {'lambda'; 'lam'; 'l'};
eigMatch = zeros(size(allVarNames));

for eigNameCounter = 1:length(eigNames);
    eigMatch = eigMatch + strcmp(allVarNames, eigNames{eigNameCounter});
end

assert(~any(eigMatch), 'CHEBFUN:CHEBGUIEXPORTER:exportInfo:eig', ...
    ['Problem appears to be an eigenvalue problem. \n Please make sure ' ...
    '''l'', ''lam'' or ''lambda'' do not appear in appear in input.']);

% Obtain the independent variable name appearing in the initial condition:
useLatest = strcmpi(initInput{1}, 'Using latest solution');
if ( ~isempty(initInput{1}) && ~useLatest )
    [dummy, dummy, indVarNameInit] = ...
        setupFields(guifile, initInput, 'INIT', allVarString);
else
    indVarNameInit = {''};
end

% Make sure we don't have a discrepency in indVarNames
if ( ~isempty(indVarNameInit{1}) && ~isempty(indVarNameDE{1}) )
    if ( strcmp(indVarNameDE{1}, indVarNameInit{1}) )
        indVarNameSpace = indVarNameDE{1};
    else
        error('CHEBFUN:CHEBGUIEXPORTERBVP:exportInfo:SolveGUIbvp', 'Independent variable names do not agree')
    end
elseif ( ~isempty(indVarNameInit{1}) && isempty(indVarNameDE{1}) )
    indVarNameSpace = indVarNameInit{1};
elseif ( isempty(indVarNameInit{1}) && ~isempty(indVarNameDE{1}) )
    indVarNameSpace = indVarNameDE{1};
else
    indVarNameSpace = 't'; % Default value for IVPs
end

% Replace the 'DUMMYSPACE' variable in the DE field
deString = strrep(deString, 'DUMMYSPACE', indVarNameSpace);
deString = chebguiExporter.prettyPrintFevalString(deString, allVarNames);

% Do we want to solve the problem globally, or with timestepping?
timeSteppingSolver = ~isempty(strfind(guifile.options.ivpSolver, 'ode'));

% Add spaces to DOM and ALLVARSTRING so it looks nices once we export
dom = strrep(dom, ',', ', ');
allVarString = strrep(allVarString, ',', ', ');

%% Fill up the expInfo struct
expInfo.dom = dom;
expInfo.deInput = deInput;
expInfo.bcInput = bcInput;
expInfo.initInput = initInput;
expInfo.deString = deString;
expInfo.allVarString = allVarString;
expInfo.allVarNames = allVarNames;
expInfo.numVars = length(allVarNames);
expInfo.indVarNameSpace = indVarNameSpace;
expInfo.useLatest = useLatest;
expInfo.timeSteppingSolver = timeSteppingSolver;

%Information related to options set-up
expInfo.tol = guifile.tol;
expInfo.dampingOn = guifile.options.damping;
expInfo.discretization = guifile.options.discretization;
expInfo.plotting = guifile.options.plotting;
expInfo.ivpSolver = guifile.options.ivpSolver;
end


% unique_bc - unique backward compatible with Matlab versions prior to 2013a

function [C,IA,IB] = unique_bc(A,varargin);

errorFlag = error_bc;

v = version;
indp = find(v == '.');
v = str2num(v(1:indp(2)-1));
if v > 7.19, v = floor(v) + rem(v,1)/10; end;

if nargin > 2
    ind = strmatch('legacy', varargin);
    if ~isempty(ind)
        varargin(ind) = [];
    end;
end;

if v >= 7.14
    [C,IA,IB] = unique(A,varargin{:},'legacy');
    if errorFlag
        [C2,IA2] = unique(A,varargin{:});
        if ~isequal(C, C2) || ~isequal(IA, IA2) || ~isequal(IB, IB2)
            warning('backward compatibility issue with call to unique function');
        end;
    end;
else
    [C,IA,IB] = unique(A,varargin{:});
end;


function point_num = xyz_example_size ( )

%*****************************************************************************80
%
%% XYZ_EXAMPLE_SIZE sizes an example XYZ dataset.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 January 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer POINT_NUM, the number of points.
%
  point_num = 101;

  return
end


function r8mat_print ( m, n, a, title )

%*****************************************************************************80
%
%% R8MAT_PRINT prints an R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows in A.
%
%    Input, integer N, the number of columns in A.
%
%    Input, real A(M,N), the matrix.
%
%    Input, string TITLE, a title to be printed.
%
  r8mat_print_some ( m, n, a, 1, 1, m, n, title );

  return
end


function [ y, j, ierror ] = yj_check_hebrew ( y, j )

%*****************************************************************************80
%
%% YJ_CHECK_HEBREW checks a Hebrew YJ date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y, J, the YJ date.
%
%    Output, integer IERROR, is 0 if no serious error was found in
%    the date, and 1 otherwise.
%

%
%  Check the year.
%
  [ y, ierror ] = y_check_hebrew ( y );

  if ( ierror ~= 0 )
    return
  end
%
%  Make sure J is not too small or too big.
%
  [ y, j ] = j_borrow_hebrew ( y, j );

  [ y, j ] = j_carry_hebrew ( y, j );

  return
end