%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Jellyfish Example Courtesy of Alexander P. Hoover, PhD
%
% Converted from IBAMR: 1/16/2018 by NAB.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Make_Jelly_Geometry()

close all;
clear all;
L = 8;                              % height of computational domain (m) for keeping desired resolution
Lh = 10;                            % actual height of computational domain (m) (MATCHES INPUT2D)
Lw = 3;                             % width of computational domain (m) (MATCHES INPUT2D)
N = 96;                            % number of Cartesian grid meshwidths at the finest level of the AMR grid
dx = L/N;                           % Cartesian mesh width (m)
ds = dx/2;

a=.5;                               % bell radius (semi-minor axis, horizontal axis, note width=2a)
b=.75;                              % bell semi-major axis
d=-0.25;
factor_a=.8;

F=1e5; %5e0

theta=zeros(1000,1);
theta_lim=asin(d/b);
theta_test=pi/2;

x_points=zeros(1000,1);
z_points=zeros(1000,1);
id_points=zeros(1000,1);
offset = 0;

kappa_spring = 1e7; %1e5               % spring constant (Newton)
kappa_beam = 2.5e5; %1e5    %5e3              % beam stiffness constant (Newton m^2)
%kappa_beam_flexible = kappa_beam/5;   % beam stiffness constant (Newton m^2)
kappa_target = kappa_spring;           % target point penalty spring constant (Newton)

c=0;
while(theta_test<(pi-theta_lim))
    c=c+1;
    theta(c)=theta_test;

    x_points(c)=a*cos(theta(c));
    z_points(c)=b*sin(theta(c));
    id_points(c)=c-1;

    theta_test=ds/((a*sin(theta(c)))^(2)+(b*cos(theta(c)))^(2))^(.5)+theta(c);

end

c_stiff=c;

npts=2*c-1;
npts_wing=floor(npts/2);
npts_musc=floor(npts_wing/4);

for j=(c+1):(npts)
    x_points(j)=-1*x_points(j-c+1);
    z_points(j)=z_points(j-c+1);
    id_points(j)=j-1;
end

mesh_name = 'jelly';
xShift = 1.5;
yShift = 2;

x_points=x_points(1:npts)+xShift;
z_points=z_points(1:npts)+yShift;
it_points=id_points(1:npts);

plot(x_points(:),z_points(:),'*'); hold on;
axis([0 8 0 8])

% Lag Pts to Mess up Flow At Edge
xBlock = ds:4*ds:Lw-ds;
yBlock = (Lh-5*ds)*ones(1,length(xBlock))+ds;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Print .vertex information
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

vertex_fid = fopen([mesh_name num2str(N) '.vertex'], 'w');

    fprintf(vertex_fid, '%d\n', npts + npts_musc*2 + length(xBlock));
    lag_ct = 0;

    %
    % bell
    %
    for j=1:npts
        fprintf(vertex_fid, '%1.16e %1.16e\n', x_points(j), z_points(j));
        lag_ct = lag_ct + 1;
    end

    %
    % muscles
    %
    for s = 1:npts_musc
        fprintf(vertex_fid, '%1.16e %1.16e\n', x_points(npts_wing+1-npts_musc+s), z_points(npts_wing+1-npts_musc+s));
        plot(x_points(npts_wing+1-npts_musc+s),z_points(npts_wing+1-npts_musc+s),'r*'); hold on;
        lag_ct = lag_ct + 1;
    end
    for s = 1:npts_musc
        fprintf(vertex_fid, '%1.16e %1.16e\n', x_points(npts-npts_musc+s), z_points(npts-npts_musc+s));
        plot(x_points(npts-npts_musc+s),z_points(npts-npts_musc+s),'r*'); hold on;
        lag_ct = lag_ct + 1;
    end

    for ii=1:length(xBlock)
        fprintf(vertex_fid, '%1.16e %1.16e\n', xBlock(ii), yBlock(ii));
    end

fclose(vertex_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Print .spring information
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

spring_fid = fopen([mesh_name num2str(N) '.spring'], 'w');

    npts_spring_type1=npts-1;

    fprintf(spring_fid, '%d\n', npts-1 + npts_musc);

    fprintf('\nNumber of springs before muscles: %d \n\n',npts-1)

    factor = 1;%ds^2/ds;

    %
    % bell
    %
    for s = 1:c-1
        resting=sqrt((x_points(s)-x_points(s+1))^(2)+(z_points(s)-z_points(s+1))^(2));
        fprintf(spring_fid, '%d %d %1.16e %1.16e %d\n', id_points(s)+1, id_points(s+1)+1, kappa_spring*ds/(ds^2)*factor, resting, 1);
    end
    for s = c+1:npts-1
        resting=sqrt((x_points(s)-x_points(s+1))^(2)+(z_points(s)-z_points(s+1))^(2));
        fprintf(spring_fid, '%d %d %1.16e %1.16e %d\n', id_points(s)+1, id_points(s+1)+1, kappa_spring*ds/(ds^2)*factor, resting, 1);
    end
    resting=sqrt((x_points(1)-x_points(c+1))^(2)+(z_points(1)-z_points(c+1))^(2));
    fprintf(spring_fid, '%d %d %1.16e %1.16e %d\n', id_points(1)+1, id_points(c+1)+1, kappa_spring*ds/(ds^2)*factor, resting, 1);

    %
    % muscles
    %
    for s = 1:npts_musc
        fprintf(spring_fid, '%d %d %1.16e %1.16e %d\n',npts+s-1+1, npts+s+npts_musc-1+1, F, 0, 1);
    end

    fclose(spring_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Print .nonInv_beam information
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

beam_fid = fopen([mesh_name num2str(N) '.nonInv_beam'], 'w');

    fprintf(beam_fid, '%d\n', npts-2);

    factor=1;% = (ds^4)/ds;

    for s = 2:c-1
        C1 = x_points(s-1)+x_points(s+1)-2*x_points(s);
        C2 = z_points(s-1)+z_points(s+1)-2*z_points(s);
        fprintf(beam_fid, '%d %d %d %1.16e %1.16e %1.16e\n', id_points(s-1)+1, id_points(s)+1, id_points(s+1)+1, kappa_beam*ds/(ds^4)*factor, C1, C2);
    end
    for s = c+2:npts-1
        C1 = x_points(s-1)+x_points(s+1)-2*x_points(s);
        C2 = z_points(s-1)+z_points(s+1)-2*z_points(s);
        fprintf(beam_fid, '%d %d %d %1.16e %1.16e %1.16e\n', id_points(s-1)+1, id_points(s)+1, id_points(s+1)+1, kappa_beam*ds/(ds^4)*factor, C1, C2);
    end

    C1 = x_points(c+2)+x_points(1)-2*x_points(c+1);
    C2 = z_points(c+2)+z_points(1)-2*z_points(c+1);
    fprintf(beam_fid, '%d %d %d %1.16e %1.16e %1.16e\n', id_points(c+2)+1, id_points(c+1)+1, id_points(1)+1, kappa_beam*ds/(ds^4)*factor, C1, C2);

    C1 = x_points(c+1)+x_points(2)-2*x_points(1);
    C2 = z_points(c+1)+z_points(2)-2*z_points(1);
    fprintf(beam_fid, '%d %d %d %1.16e %1.16e %1.16e\n', id_points(c+1)+1, id_points(1)+1, id_points(2)+1, kappa_beam*ds/(ds^4)*factor, C1, C2);

    fclose(beam_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PRINT TARGET POINTS!!!
%
% print target points (flow blocker along edge)
k_Target = 2.5e6;
nBefore = lag_ct; % Counts pts in jellyfish for bookkeeping for .target file
struct_name = ['jelly' num2str(N)];
print_Lagrangian_Target_Pts(xBlock,k_Target,struct_name,nBefore)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: prints TARGET points to a file called 'struct_name'.target
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Lagrangian_Target_Pts(xLag,k_Target,struct_name,nBefore)

    N = length(xLag);
    Nstart = nBefore+1;
    Nend = nBefore+N;

    target_fid = fopen([struct_name '.target'], 'w');

    fprintf(target_fid, '%d\n', N );

    %Loops over all Lagrangian Pts.
    for s = Nstart:Nend
        fprintf(target_fid, '%d %1.16e\n', s, k_Target);
    end

    fclose(target_fid);


function lam_msg = CPD_to_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
% CPD_TO_LAMBDA_MSG Compute lambda message (gaussian)
% lam_msg = compute_lambda_msg(CPD, msg_type, n, ps, msg, p, evidence)
% Pearl p183 eq 4.52

switch msg_type
 case 'd',
  error('gaussian_CPD can''t create discrete msgs')
 case 'g',
  cps = ps(CPD.cps);
  cpsizes = CPD.sizes(CPD.cps);
  self_size = CPD.sizes(end);
  i = find_equiv_posns(p, cps); % p is n's i'th cts parent
  psz = cpsizes(i);
  if all(msg{n}.lambda.precision == 0) % no info to send on
    lam_msg.precision = zeros(psz, psz);
    lam_msg.info_state = zeros(psz, 1);
    return;
  end
  [m, Q, W] = gaussian_CPD_params_given_dps(CPD, [ps n], evidence);
  Bmu = m;
  BSigma = Q;
  for k=1:length(cps) % only get pi msgs from cts parents
    pk = cps(k);
    if pk ~= p
      %bk = block(k, cpsizes);
      bk = CPD.cps_block_ndx{k};
      Bk = W(:, bk);
      m = msg{n}.pi_from_parent{k};
      BSigma = BSigma + Bk * m.Sigma * Bk';
      Bmu = Bmu + Bk * m.mu;
    end
  end
  % BSigma = Q + sum_{k \neq i} B_k Sigma_k B_k'
  %bi = block(i, cpsizes);
  bi = CPD.cps_block_ndx{i};
  Bi = W(:,bi);
  P = msg{n}.lambda.precision;
  if (rcond(P) > 1e-3) | isinf(P)
    if isinf(P) % Y is observed
      Sigma_lambda = zeros(self_size, self_size); % infinite precision => 0 variance
      mu_lambda = msg{n}.lambda.mu; % observed_value;
    else
      Sigma_lambda = inv(P);
      mu_lambda = Sigma_lambda * msg{n}.lambda.info_state;
    end
    C = inv(Sigma_lambda + BSigma);
    lam_msg.precision = Bi' * C * Bi;
    lam_msg.info_state = Bi' * C * (mu_lambda - Bmu);
  else
    % method that uses matrix inversion lemma to avoid inverting P
    A = inv(P + inv(BSigma));
    C = P - P*A*P;
    lam_msg.precision = Bi' * C * Bi;
    D = eye(self_size) - P*A;
    z = msg{n}.lambda.info_state;
    lam_msg.info_state = Bi' * (D*z - D*P*Bmu);
  end
end


% Test file for singfun/flipud.m

function pass = test_flipud(pref)

% Get preferences.
if ( nargin < 1 )
    pref = chebfunpref();
end

% Generate a few random points to use as test values.
seedRNG(6178);
d = 10;
x = 2*(1-10^(-d)) * rand(100, 1) - (1-10^(-d));

% The order of the exponents:
a = 0.64;
b = -0.64;
c = 1.28;
d = -1.28;

%%
% Spot-check derivatives for a couple of functions.

% fractional root at the left endpoint
data.exponents = [a 0];
data.singType = {'root', 'none'};
f = singfun(@(x) (1+x).^a.*exp(x), data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) (1-x).^a.*exp(-x);
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(1) = (norm(err, inf) < 1e1*eps*norm(vals_exact, inf));

% fractional pole at the left endpoint
data.exponents = [d 0];
data.singType = {'sing', 'none'};
f = singfun(@(x) (1+x).^d.*sin(x), data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) -(1-x).^d.*sin(x);
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(2) = (norm(err, inf) < 10*eps*norm(vals_exact, inf));

% fractional root at the right endpoint
data.exponents = [0 c];
data.singType = {'none', 'root'};
f = singfun(@(x) (1-x).^c.*cos(x), data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) (1+x).^c.*cos(x);
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(3) = (norm(err, inf) < 1e1*eps*norm(vals_exact, inf));

% fractional pole at the right endpoint
data.exponents = [0 b];
data.singType = {'none', 'sing'};
f = singfun(@(x) (1-x).^b.*(x.^5), data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) -(1+x).^b.*(x.^5);
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(4) = (norm(err, inf) < 1e1*eps*norm(vals_exact, inf));

% a combination of fractional pole and fractional root
data.exponents = [b c];
data.singType = {'sing', 'root'};
f = singfun(@(x) (1+x).^b.*sin(x).*(1-x).^c, data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) -(1-x).^b.*sin(x).*(1+x).^c;
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(5) = (norm(err, inf) < 1e1*eps*norm(vals_exact, inf));

%%
% Verify that calling flipud() gives the reasonably accurate answer as direct
% construction.

data.exponents = [b b];
data.singType = {'sing', 'sing'};
f = singfun(@(x) (1+x).^b.*sin(2*x).*(1-x).^b, data, pref);
g = flipud(f);
vals_df = feval(g, x);
flip_exact = @(x) -(1-x).^b.*sin(2*x).*(1+x).^b;
vals_exact = feval(flip_exact, x);
err = vals_df - vals_exact;
pass(6) = (norm(err, inf) < 1e1*eps*norm(vals_exact, inf));

%%
% Check higher-order derivatives.

data.exponents = [a b];
data.singType = {'root', 'sing'};
f = singfun(@(x) (1+x).^a.*sin(x).*(1-x).^b, data, pref);
df2 = flipud(f);
vals_df2 = feval(df2, x);
df2_exact = @(x) -(1-x).^a.*sin(x).*(1+x).^b;
vals_exact = feval(df2_exact, x);
err = vals_df2 - vals_exact;
pass(7) = (norm(err, inf) < 5*eps*norm(vals_exact, inf));

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% SPHARM-MAT is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
% Rotate around x, y, z (counterclockwise when looking towards the origin)
%

function R = rotate_mat(x, y, z)
% It is assumed that this matrix is muplied from the hind, rotating objects
% along x-axis, y-axis, and z-axis in this order.

Rx = [      1       0       0; ...
            0  cos(x) -sin(x); ...
            0  sin(x)  cos(x)];

Ry = [ cos(y)       0  sin(y); ...
            0       1       0; ...
      -sin(y)       0  cos(y)];

Rz = [ cos(z) -sin(z)       0; ...
       sin(z)  cos(z)       0; ...
            0      0        1];

R = Rz*Ry*Rx;

return;


function tfplot(imp);

% tfplot(imp);
%
% Plot the transfer function of the filter whose impulse response is imp.
%
% Multiple transfer functions can be plotted simultaneously where each
% impulse response represents one row of imp.

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

error(nargchk(1,1,nargin));
%error(chk_param(imp,'imp','vector'));

n_pts_min=4096;
if (isvector(imp))
  n_pts=max(n_pts_min,length(imp));
else
  n_pts=max(n_pts_min,size(imp,2));
end

f=linspace(0,2,n_pts+1);
f=f(1:end-1);
f(f>=1)=f(f>=1)-2;
f=fftshift(f);
m=transpose(fftshift(fft(transpose(imp),n_pts)));
plot(f,db20(abs(m)));

xlabel('Frequency/(fs/2)');
ylabel('Power gain (dB)');
title('Transfer function');
zgo;


clear all
    % Generarea matricei A
A=[11,12,13,14;21,22,23,24;31,32,33,34;41,42,43,44]
    % Manipulari cu matricea A
B=A(2,2:4)
C=A(2,:)
D=A(1:2:3,:)
E(:,[3,5,7])=A(:,2:4)
F=A(:,[1 3 2 4])
    % Utilizarea filtrelor logice
Filt=zeros(size(A));
Filt(1,3)=1; Filt(2,4)=1; Filt(4,4)=1;
    % Transforarea matricei numerice in matrice logica
Filt=logical(Filt)
A_filtrat=A(Filt)'
    % Stergerea unei coloane din matricea A
A(:,2)=[ ]


function [Qout,fcount] = quadgui_adaptive(F,a,b,tol,varargin)
%QUADGUI  Demonstrate numerical evaluation of a definite integral.
%   Q = QUADGUI(F,A,B) shows the steps in approximating the integral
%   of F(x) from A to B by adaptive extrapolated Simpson's quadrature.
%
%   The shaded area shows the integral over the current subinterval.
%   The color switches to green when the desired accuracy is obtained.
%
%   Q = QUADGUI(F,A,B,tol) uses the given tolerance instead of 1.e-4.
%
%   The first argument, F, is a function handle or an anonymous function
%   that defines F(x).
%   Arguments beyond the first four, Q = QUADGUI(F,a,b,tol,p1,p2,...),
%   are passed on to the integrand, F(x,p1,p2,..).
%
%   [Q,fcount] = QUADGUI(F,...) also counts the number of evaluations
%   of F(x).
%
%   Examples:
%        F                      a     b       tol(optional)
%      humps(x)                 0     1
%      humps(x)                 0     1       1.e-6
%      humps(x)                -1     2
%      sin(x)                   0     pi      1.e-8
%      cos(x)                   0     9*pi/2  1.e-6
%      sqrt(x)                  0     1       1.e-8
%      -sqrt(x)*log(x)          eps   1       1.e-8
%      1/(3*x-1)                0     1
%      t^(8/3)*(1-t)^(10/3)     0     1       1.e-8
%      tan(sin(x))-sin(tan(x))  0     pi
%
%      quadgui(@(x)F,a,b)
%
%   See also QUADTX, QUAD, QUADL, DBLQUAD.

%   Copyright 2014 Cleve Moler
%   Copyright 2014 The MathWorks, Inc.

shg
clf reset
set(gcf,'menubar','none','numbertitle','off','name','Quad gui')

% Default tolerance
if nargin < 4 | isempty(tol)
   tol = 1.e-4;
end

% Default function and interval.
if nargin < 3
   F = @humps;
   a = 0;
   b = 1;
end

% Initialization
c = (a + b)/2;
fa = F(a,varargin{:});
fc = F(c,varargin{:});
fb = F(b,varargin{:});

% Scale the plot
h = b - a;
x = [a c b];
y = [fa fc fb];
maxy = max(y);
miny = min(y);
for k = 1:63
   v = F(a+k*h/64,varargin{:});
   maxy = real(max(maxy,v));
   miny = real(min(miny,v));
end
set(gcf,'userdata',0)
hold on
p(1) = fill(a,fa,'k');
p(2) = fill(b,fb,'k');
p(3) = plot(x,y,'.','markersize',16);
hold off
s = (maxy - miny)/20;
axis([a b miny-s maxy+s])
q(1) = uicontrol('string','step', ...
   'units','normal','pos',[.65 .02 .08 .06], ...
   'callback','set(gcf,''userdata'',1)');
q(2) = uicontrol('string','auto', ...
   'units','normal','pos',[.75 .02 .08 .06], ...
   'callback','set(gcf,''userdata'',2)');
q(3) = uicontrol('string','quit', ...
   'units','normal','pos',[.85 .02 .08 .06], ...
   'callback','set(gcf,''userdata'',3)');

% Recursive call
[Q,k] = quadguistep(F, a, b, tol, fa, fc, fb, varargin{:});
fcount = k + 3;

% Finish
title(sprintf('Q = %8.4f, fcount = %4.0f',Q,fcount))
delete(p(1:2));
delete(q(1:2));
set(q(3),'string','close','callback','close(gcf)')
if nargout > 0, Qout = Q; end

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

function [Q,fcount] = quadguistep(F,a,b,tol,fa,fc,fb,varargin)

% Recursive subfunction used by quadtx.

h = b - a;
c = (a + b)/2;
d = (a + c)/2;
e = (c + b)/2;
fd = F(d,varargin{:});
fe = F(e,varargin{:});
Q1 = h/6 * (fa + 4*fc + fb);
Q2 = h/12 * (fa + 4*fd + 2*fc + 4*fe + fb);

u1 = a:h/64:c;
v1 = polyinterp([a d c],[fa fd fc],u1);
u1 = [a u1 c];
v1 = [0 v1 0];
u2 = c:h/64:b;
v2 = polyinterp([c e b],[fc fe fb],u2);
u2 = [c u2 b];
v2 = [0 v2 0];
if (abs(Q2 - Q1) <= tol)
   color = [0 2/3 0];
else
   color = [.6 .6 .6];
end
p = flipud(get(gca,'child'));
x = [get(p(3),'xdata') d e];
y = [get(p(3),'ydata') fd fe];
set(p(1),'xdata',u1,'ydata',v1,'facecolor',color)
set(p(2),'xdata',u2,'ydata',v2,'facecolor',color)
set(p(3),'xdata',x,'ydata',y)
set(gca,'xtick',sort(x),'xticklabel',[]);
title(num2str(length(x)))
pause(.25)
while get(gcf,'userdata') == 0
   pause(.25)
end
if get(gcf,'userdata') == 1
   set(gcf,'userdata',0)
end

if (abs(Q2 - Q1) <= tol) | (get(gcf,'userdata') == 3)
   Q  = Q2 + (Q2 - Q1)/15;
   fcount = 2;
else
   [Qa,ka] = quadguistep(F, a, c, tol, fa, fd, fc, varargin{:});
   [Qb,kb] = quadguistep(F, c, b, tol, fc, fe, fb, varargin{:});
   Q  = Qa + Qb;
   fcount = ka + kb + 2;
end


function lev = QLmaxlev(sizeX, filtername)
%-----------------------------------------------------------------------------
% QLmaxlev
% This function determines the maximum level possible for the QL-schemes.
%
% Syntax: lev = QLmaxlev(sizeX, filtername)
%
% QLmaxlev is a utility for the lifting scheme decomposition. It helps one to
% avoid silly values for the maximum level in the lifting scheme decomposition.
%
% lev is the integer outcome.
%
% sizeX is an integer row vector of dimension 2. Usually it will be the size of
% an image.
%
% filtername must be a string from the set:
% {Neville2, Neville4, Neville6, Neville8, MaxMin, MinMin, MaxMax}
%
% See also: QLiftDec2, QLiftRec2, wmaxlev
%
% Design and implementation by:
% Dr. Paul M. de Zeeuw <Paul.de.Zeeuw@cwi.nl>  http://homepages.cwi.nl/~pauldz/
% Last Revision: February 17, 2003.
% (c) 1999-2003 Stichting CWI, Amsterdam
%-----------------------------------------------------------------------------
%Firstly, check input data
if nargin ~= 2
  error(' QLmaxlev - number of arguments should be 2 ');
end
if ~ischar(filtername)
  error(' QLmaxlev - format of filtername should be character array ');
end
%
switch lower(filtername)
 case 'neville2'
   diam =  3;
 case 'neville4'
   diam =  5;
 case 'neville6'
   diam =  7;
 case 'neville8'
   diam = 11;
 case 'maxmin'
   diam =  3;
 case 'maxmax'
   diam =  3;
 case 'minmax'
   diam =  3;
 case 'minmin'
   diam =  3;
 otherwise
   error(' QLmaxlev - unknown filter ')
end
%
if isempty(sizeX)
  lev = [];
  return;
else
  lev=0;
  n=min(sizeX);
  z=2*diam-1;
  while z<=n
    lev=lev+2;
    z=2*z-1;
  end
end
%-----------------------------------------------------------------------------


function s = volumeVisualization(x,y,z,v)
%volumeVisualization Engine for choosing y-z planes to view.
%   s = volumeVisualization(X,Y,Z,V) returns a structure
%   containing information about the visualization of volume
%   data described by X,Y,Z,V.  The fields are:
%          addSlicePlane -- function handle to add a slice
%                           plane at location x
%   deleteLastSlicePLane -- function handle to delete the
%                           last slice plane added
%                   xMin -- minimum x location for a plane
%                   xMax -- maximum x location for a plane
%
%      Example:
%      [x,y,z,v] = flow;
%      s = volumeVisualization(x,y,z,v);
%      s.addSlicePlane(3.7)
%      s.addSlicePlane(7.5)
%      pause
%      s.deleteLastSlicePlane()
%      pause
%      s.deleteLastSlicePlane()

%   Copyright 2007 The MathWorks, Inc.

%% Store handles to the various planes
%initialize handle to axis
%initialize handle to slice plane
hAxis = [];
hSlicePlanes = [];

%% Create data for generic slice through yz-plane
[yd,zd] = meshgrid(linspace(min(y(:)),max(y(:)),100), ...
    linspace(min(z(:)),max(z(:)),100));

%% Plot the volume initially
initDisplay()

%% Nested Functions
    function addSlicePlane(xLoc)
    %addSlicePlane   Add a slice plane xLoc.
        xd            = xLoc*ones(size(yd));
        newSlicePlane = slice(hAxis, x, y, z, v, xd, yd, zd);
        hSlicePlanes   = [ hSlicePlanes, newSlicePlane ];
        set(newSlicePlane,'FaceColor'      ,'interp',...
                          'EdgeColor'      ,'none'  ,...
                          'DiffuseStrength',.8       );
    end

    function deleteLastSlicePlane()
    %deleteLastSlicePlane Delete the last slice plane added.
        if ~isempty(hSlicePlanes)
            delete(hSlicePlanes(end));
            hSlicePlanes = hSlicePlanes(1:end-1);
        end
    end

    function initDisplay()
    %initDisplay  Initialize Display.

        % Draw back and bottom walls
        if isempty(hAxis) || ~ishandle(hAxis)
            hAxis = gca;
            hold on;
        end
        hx = slice(hAxis, x, y, z, v, ...
            max(x(:)),       [],       []) ;
        hy = slice(hAxis, x, y, z, v, ...
            [],       max(y(:)),       []) ;
        hz = slice(hAxis, x, y, z, v, ...
            [],              [],min(z(:))) ;

        % Make everything look nice
        set([hx hy hz],'FaceColor','interp',...
            'EdgeColor','none')
        set(hAxis,'FontSize',18,'FontWeight','Bold');
        xlabel('X');ylabel('Y');zlabel('Z')
        daspect([1,1,1])
        axis tight
        box on
        view(-38.5,16)
        colormap (jet(128))
    end

s.addSlicePlane = @addSlicePlane;
s.deleteLastSlicePlane = @deleteLastSlicePlane;
s.xMin = min(x(:));
s.xMax = max(x(:));

end


function solplotl(sol,xy,x,y,fig)
%solplotl   plots nodal data on L-shaped domain
%   solplotl(sol,xy,x,y,fig);
%   input
%          sol        nodal solution vector
%          xy         nodal coordinate vector
%          x          vector of x-axis interpolation points
%          y          vector of y-axis interpolation points
%          fig        figure number
%
%   IFISS function: DJS; 30 March 2005.
% Copyright (c) 2005 D.J. Silvester, H.C. Elman, A. Ramage
fprintf('plotting solution... ')
% interpolate to a cartesian product mesh
[X,Y]=meshgrid(x,y);
xysol = griddata(xy(:,1),xy(:,2),sol,X,Y);
[II,JJ]=find(X<0 & Y<0); xysol(II,JJ)=nan;
figure(fig)
subplot(121),contour(X,Y,xysol,20),axis('square')
axis('off'),
if all([min(x),max(x),min(y),max(y)] == [-1,1,-1,1]), ellx, end
subplot(122),mesh(X,Y,xysol),axis('square')
view(330,30)
fprintf('done\n')
return


classdef RMMEDA_F6 < PROBLEM
% <multi> <real> <large/none>
% Benchmark MOP for testing RM-MEDA

%------------------------------- Reference --------------------------------
% Q. Zhang, A. Zhou, and Y. Jin, RM-MEDA: A regularity model-based
% multiobjective estimation of distribution algorithm, IEEE Transactions on
% Evolutionary Computation, 2008, 12(1): 41-63.
%------------------------------- 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".
%--------------------------------------------------------------------------

    methods
        %% Default settings of the problem
        function Setting(obj)
            obj.M = 2;
            if isempty(obj.D); obj.D = 30; end
            obj.lower    = zeros(1,obj.D);
            obj.upper    = ones(1,obj.D);
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,X)
            g = 1 + 9*mean((X(:,2:end).^2-repmat(X(:,1),1,size(X,2)-1)).^2,2);
            PopObj(:,1) = sqrt(X(:,1));
            PopObj(:,2) = g.*(1-(PopObj(:,1)./g).^2);
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R(:,1) = linspace(0,1,N)';
            R(:,2) = 1 - R(:,1).^2;
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            R = obj.GetOptimum(100);
        end
    end
end


function [vals, locs] = minandmax3(f)
%MINANDMAX3   returns the global minimum and maximum value of a CHEBFUN3.
%   VALS = minandmax3(F) returns the global minimum and maximum value of a
%   CHEBFUN3 object F over its domain. VALS is a vector of length 2 such
%   that Y(1) = min3(F(x,y,z)) and Y(2) = max3(F(x,y,z)).
%
%   [VALS, LOCS] = minandmax3(F) also returns the position of the global
%   minimum and maximum.
%
% See also CHEBFUN3/MAX, CHEBFUN3/MAX2, CHEBFUN3/NORM.

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

% check for empty CHEBFUN3.
if ( isempty(f) )
    vals = [];
    locs = [];
    return
end

doNewton = 1;   % Newton polishing?

% Extract low rank representation of f:
[fCore, fCols, fRows, fTubes] = tucker(f);
dom = f.domain;

% Is f the zero function?
if ( iszero(f) )
    locs = [(dom(1) + dom(2))/2  (dom(3) + dom(4))/2  (dom(5) + dom(6))/2];
    locs = [locs; locs];
    vals = [0; 0];
end

[m, n, p] = length(f);
if ( ndf(f) > 5e4 )
    m = min(m, 129);
    n = min(n, 129);
    p = min(p, 129);
end

% We seek a fast initial guess. So we first discretize the object.
xpts = chebpts(m, fCols.domain);
ypts = chebpts(n, fRows.domain);
zpts = chebpts(p, fTubes.domain);
colVals = feval(fCols, xpts);
rowVals = feval(fRows, ypts);
tubeVals = feval(fTubes, zpts);
T = chebfun3.txm(chebfun3.txm(chebfun3.txm(fCore,colVals,1), rowVals,2), ...
    tubeVals,3);

% Minimum entry in the sample:
[ignored, ind] = min(T(:));
[col, row, tub] = ind2sub(size(T), ind);
loc(1,1) = xpts(col);
loc(1,2) = ypts(row);
loc(1,3) = zpts(tub);
vals(1) = feval(f, loc(1, 1), loc(1, 2), loc(1, 3));

% Maximum entry in the sample:
[ignored, ind] = max(T(:));
[col, row, tub] = ind2sub(size(T), ind);
loc(2,1) = xpts(col);
loc(2,2) = ypts(row);
loc(2,3) = zpts(tub);
vals(2) = feval(f, loc(2, 1), loc(2, 2), loc(2, 3));

% Get more digits with optimisation algorithms.
lb = [dom(1); dom(3); dom(5)];
ub = [dom(2); dom(4); dom(6)];

if ( ~isempty(ver('optim')) )
% Matlab's Optimization Toolbox is available. So, use fmincon command.
    options = optimset('Display', 'none', 'TolFun', eps, 'TolX', eps, ...
        'algorithm', 'active-set');
    [minLoc, vals(1)] = fmincon(@(x) feval(f, x(1), x(2), x(3)), ...
        loc(1, :), [], [], [], [], lb, ub, [], options);

    [maxLoc, vals(2)] = fmincon(@(x) -feval(f, x(1), x(2), x(3)), ...
        loc(2,:), [], [], [], [], lb, ub, [], options);
    vals(2) = -vals(2);
    loc(1,:) = minLoc;
    loc(2,:) = maxLoc;
    locs = loc;
else
    try
        % Use core Matlab fminsearch command by converting to an
        % unconstrained optimization problem.
        % Maps from [-1, 1] to dom(1:2), dom(3:4), and dom(5:6)
        % respectively.
        map1 = bndfun.createMap(dom(1:2));
        map2 = bndfun.createMap(dom(3:4));
        map3 = bndfun.createMap(dom(5:6));

        % Unconstrained initial guesses:
        loc(:, 1) = asin(map1.Inv(loc(:, 1)));
        loc(:, 2) = asin(map2.Inv(loc(:, 2)));
        loc(:, 3) = asin(map3.Inv(loc(:, 3)));

        % Maps from R to dom(1:2), dom(3:4), and dom(5:6) respectively.
        map1 = @(x) map1.For(sin(x));
        map2 = @(x) map2.For(sin(x));
        map3 = @(x) map3.For(sin(x));

        % Set options:
        options = optimset('Display', 'off', 'TolFun', eps, 'TolX', eps);
        warnstate = warning;
        warning('off'); % Disable verbose warnings from fminsearch.
        f_mapped = @(x) feval(f, map1(x(1)), map2(x(2)),map3(x(3)));

        [minLoc, vals(1)] = fminsearch(@(x) f_mapped(x), loc(1, :), options);
        [maxLoc, vals(2)] = fminsearch(@(x) -f_mapped(x), loc(2, :), options);

        vals(2) = -vals(2);
        loc(1:2, 1) = map1([minLoc(1); maxLoc(1)]);
        loc(1:2, 2) = map2([minLoc(2); maxLoc(2)]);
        loc(1:2, 3) = map3([minLoc(3); maxLoc(3)]);
        warning(warnstate);
        locs = loc;

    catch
        % Nothing is going to work. So we will have to go with initial
        % guesses.
    end
end

if ( doNewton )
    % Store values before applying any Newton iterations to restore if
    % Newton was diverging.
    locsOld = locs;
    valsOld = vals;

    % If the global max or min is already on the edge or out of domain,
    % do NOT apply Newton iteration:
    if ( isOutOfDomain(locs, dom) )
        return
    end

    % A few steps of Newton for optimization (involves computing Hessian)
    H = Hessian(f);
    gradF = grad(f);
    gradF = @(x,y,z) gradF(x,y,z);

    % Disable verbose warnings from Newton step if e.g., the Hessian
    % matrix is singular which happens e.g., if a 2D function is passed to
    % minandmax3.
    warning_state = warning('off','MATLAB:singularMatrix');
	% Use try-catch to guarantee original warning state is restored.
    try
        lastwarn('')
        k = 1; % k Newton iterations:
        for iter = 1:k
            locs(1,:) = newton_opt(locs(1,:), H, gradF);
            vals(:,1) = feval(f, locs(1, 1), locs(1, 2), locs(1, 3));

            locs(2,:) = newton_opt(locs(2, :), H, gradF);
            vals(:,2) = feval(f,locs(2, 1), locs(2, 2), locs(2, 3));
        end
        [ignored, last_warn] = lastwarn;
        if strcmp(last_warn,'MATLAB:singularMatrix')
            % Return the old value if the Hessian matrix was singular.
            locs = locsOld;
            vals = valsOld;
            return
        end
        warning(warning_state)
    catch err
        warning(warning_state)
        rethrow(err)
    end

    % If Newton's method moved us outside of the domain, then return old
    % value.
    if ( isOutOfDomain(locs, dom) )
        locs = locsOld;
        vals = valsOld;
    end

end

end

%%
function H = Hessian(f)
% Forms the Hessian matrix of a CHEBFUN3 object f

H11 = diff(f, 2, 1);
H12 = diff(diff(f, 1, 2), 1, 1);
H13 = diff(diff(f, 1, 3), 1, 1);

H21 = diff(diff(f, 1, 1), 1, 2);
H22 = diff(f, 2, 2);
H23 = diff(diff(f, 1, 3), 1, 2);

H31 = diff(diff(f, 1, 1), 1, 3);
H32 = diff(diff(f, 1, 2), 1, 3);
H33 = diff(f, 2, 3);
H = @(x,y,z) [feval(H11, x, y, z)  feval(H12, x, y, z)  feval(H13, x, y, z);
              feval(H21, x, y, z)  feval(H22, x, y, z)  feval(H23, x, y, z);
              feval(H31, x, y, z)  feval(H32, x, y, z)  feval(H33, x, y, z)];
end

%%
function sol = newton_opt(init, H, gradF)
% Perform one step of multivariate optimization using Newton's method.
x = init(1);
y = init(2);
z = init(3);
rhs = -gradF(x, y, z);
h = H(x,y,z)\rhs;
sol = init.' + h;
end

%%
function check = isOutOfDomain(locs, dom)
% Check whether both points in the rows of LOCS are inside the cuboid DOM.
if ( locs(1, 1) <= dom(1) || locs(1, 1) >=dom(2) || ...
         locs(1, 2) <= dom(3) || locs(1, 2)>=dom(4) || ...
         locs(1, 3) <= dom(5) || locs(1, 3)>=dom(6) )
     check = true;
elseif ( locs(2, 1) <= dom(1) || locs(2, 1) >= dom(2) || ...
             locs(2, 2) <= dom(3) || locs(2, 2) >= dom(4) || ...
             locs(2, 3) <= dom(5) || locs(2, 3) >= dom(6) )
         check = true;
else
    check = false;
end
end
%%


function [x_guess Iter] = VMPCM(ode,tau,x_guess,omega1,omega2,errTol,varargin)
%Purpose:
%Generic Function wrapper for the Vectorized Picard Chebyshev Method
%-------------------------------------------------------------------------%
%                                                                         %
% Inputs:                                                                 %
%--------
%ode                    object                          function name to
%                                                       evaluate i.e.
%                                                       @jatForces
%
%tau                    [N x 1]                         transformed time
%                                                       domain vector
%
%x_guess                [N x M]                         Initial Guess of
%                                                       solution values for
%                                                       the Picard
%                                                       Chebyshev Method
%
%omega1                 double                          First Omega Term
%
%omega2                 double                          Second Omega Term
%
%errTol                 double                          Error Tolerance of
%                                                       solution
%
%varargin                                                Additional inputs
%                                                       which are needed to
%                                                       be passed to the
%                                                       evaluation function
%                                                       ode
%
% Outputs:
%---------                                                                %
%x_guess                  [N x M]                        Refined solution
%                                                        meeting the error
%                                                        tolerances defined
%                                                        by errTol
%
%--------------------------------------------------------------------------
% Programmed by Darin Koblick 03-04-2012                                  %
%--------------------------------------------------------------------------
tau = tau(:)';
N = numel(tau)-1;
err1 = Inf;
err2 = Inf;
Iter = 0;
MaxIter = 300;
%disp('Running The Picard Chebyshev Algorithm')
tic;
%Initialize Constant Matricies up front so we don't have to recompute them
%which would slow down the iterative process
%--------------------------------------------------------------------------
T = ChebyshevPolynomial((0:N+1)',tau);
V = ones(1,length(tau))./N;
V(2:end-1) = V(2:end-1).*2;
TV1 = bsxfun(@times,T(1:N,:),V);
TV2 = bsxfun(@times,T(3:N+2,:),V);
TV = bsxfun(@rdivide,(TV1-TV2),(2.*(1:N))');
TV(end,:) = TV1(end,:)./(2*N)';
S = 2.*((-1).^((1:N)+1));
Cx = T(1:N+1,1:N+1)';
Cx(:,1) = Cx(:,1)./2;
%--------------------------------------------------------------------------
while (any(errTol < err1 ) || any(errTol < err2)) && Iter < MaxIter
    Iter = Iter + 1;
    %disp(['-------- Iteration # ',num2str(Iter),' -----------']);
    input = {omega2.*tau+omega1,x_guess,varargin{:}};
    F = ode(input{:}).*omega2;
    if size(F,2) == 1 || size(F,1) == 1
       F = F';
    end
    Beta_r = NaN(size(TV,1),size(F,2));
    Beta_k = NaN(size(TV,1) + 1, size(F,2));
    x_new = Beta_k;
    %Matrix Multiply
    for i=1:size(F,2)
        Beta_r(:,i) = TV*F(:,i);
        Beta_k(:,i) = [S*Beta_r(:,i) + 2.*x_guess(1,i); Beta_r(:,i)];
        x_new(:,i) = (Cx*Beta_k(:,i));
    end
    if any(size(x_new) ~= size(F))
       x_new = x_new';
    end
    err2 = err1;
    err1 = max(abs(x_new - x_guess),[],2);
    disp(['Max Error Is found to be: ', num2str(max(err1))]);
    x_guess = x_new;
end
end

function Tk = ChebyshevPolynomial(k,tau)
%The Chebyshev polynomial,T, corresponding to degree k
Tk = cos(bsxfun(@times,k,acos(tau)));
end


%% Clear and Close Figures
clear ; close all; clc

correctPredictedSpam = 85
incorrectPredictedSpam = 890
correctPredictedNoSpam = 10
incorrectPredictedNoSpam = 15

total = correctPredictedSpam + incorrectPredictedSpam + correctPredictedNoSpam + incorrectPredictedNoSpam

accuracy = ( correctPredictedSpam + correctPredictedNoSpam ) / total
precision = correctPredictedSpam / (correctPredictedSpam + incorrectPredictedSpam)
recall = correctPredictedSpam / (correctPredictedSpam + incorrectPredictedNoSpam)
F1 = (2 * precision * recall) / (precision + recall)
F1


function toms655_test ( )

%*****************************************************************************80
%
%% TOMS655_TEST tests the TOMS655 library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TOMS655_PRB\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the TOMS655 library.\n' );

  test01 ( );
  test02 ( );
  test03 ( );
  test04 ( );
  test05 ( );
  test06 ( );
  test07 ( );
  test08 ( );
  test09 ( );
%
%  Compute 15 points of an example of each rule.
%
  for kind = 1 : 9
    nt = 15;
    if ( kind == 8 )
      alpha = 1.0;
      beta = - alpha - 2 * nt - 2;
    else
      alpha = 0.0;
      beta = 0.0;
    end
    test10 ( nt, kind, alpha, beta );
  end
%
%  Compute 15 points of an example of each rule using nondefault A, B.
%
  for kind = 1 : 9

    nt = 15;

    if ( kind == 1 )
      alpha = 0.0;
      beta = 0.0;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 2 )
      alpha = 0.0;
      beta = 0.0;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 3 )
      alpha = 1.0;
      beta = 0.0;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 4 )
      alpha = 1.5;
      beta = 0.5;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 5 )
      alpha = 1.0;
      beta = 0.0;
      a = 1.0;
      b = 1.0;
    elseif ( kind == 6 )
      alpha = 1.0;
      beta = 0.0;
      a = 0.0;
      b = 0.5;
    elseif ( kind == 7 )
      alpha = 1.0;
      beta = 0.0;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 8 )
      alpha = 1.0;
      beta = - alpha - 2 * nt - 2;
      a = 0.0;
      b = 1.0;
    elseif ( kind == 9 )
      alpha = 0.0;
      beta = 0.0;
      a = 0.0;
      b = 1.0;
    end

    test11 ( nt, kind, alpha, beta, a, b );

  end
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TOMS655_PRB\n' );
  fprintf ( 1, '  Normal end of TOMS655 tests.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function test01 ( )

%*****************************************************************************80
%
%% TEST01 tests CIQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST01\n' );
  fprintf ( 1, '  Test CIQFS.\n' );
%
%  Number of knots.
%
  nt = 5;
%
%  Set the knots in the default interval [-1,+1].
%
  t = zeros ( nt, 1 );
  for i = 1 : nt
    t(i) = cos ( ( 2 * i - 1 ) * pi / 2.0 / nt );
  end
%
%  Set the knot multiplicities.
%
  mlt(1:nt) = 2;
%
%  Set the size of the weights array.
%
  nwts = sum ( mlt(1:nt) );
%
%  Because KEY = 1, NDX will be set up for us.
%
  ndx = zeros(nt,1);
%
%  KEY = 1 indicates that the WTS array should hold the weights
%  in the usual order.
%
  key = 1;
%
%  Request Legendre weight function.
%
  kind = 1;
%
%  ALPHA, BETA not used in Legendre weight function but set anyway.
%
  alpha = 0.0;
  beta  = 0.0;
%
%  LU controls printing.
%  A positive value requests that we compute and print weights, and
%  conduct a moments check.
%
  lu = 6;

  [ wts, ndx ] = ciqfs ( nt, t, mlt, nwts, ndx, key, kind, alpha, beta, lu );

  return
end
function test02 ( )

%*****************************************************************************80
%
%% TEST02 tests CIQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST02\n' );
  fprintf ( 1, '  Test CIQF, CIQFS, CGQF and CGQFS\n' );
  fprintf ( 1, '  with all classical weight functions.\n' );
%
%  Try all weight functions.
%
  for kind = 1 : 9
%
%  Number of knots.
%
    nt = 5;
%
%  Set parameters ALPHA and BETA.
%
    alpha = 0.5;
    if ( kind ~= 8 )
      beta  = 2.0;
    else
      beta = - 16.0;
    end
%
%  Set A and B.
%
    lo = 6;
    a = - 0.5;
    b = 2.0;
%
%  Have CGQF compute the knots and weights.
%
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Knots and weights of Gauss quadrature formula\n' );
    fprintf ( 1, '  computed by CGQF.\n' );
    [ t, wts ] = cgqf ( nt, kind, alpha, beta, lo, a, b );
%
%  Now compute the weights for the same knots by CIQF.
%
%  Set the knot multiplicities.
%
    mlt = zeros(nt,1);
    mlt(1:nt) = 2;
%
%  Set the size of the weights array.
%
    nwts = sum ( mlt(1:nt) );
%
%  Because KEY = 1, NDX will be set up for us.
%
    ndx = zeros(nt,1);
%
%  KEY = 1 indicates that the WTS array should hold the weights
%  in the usual order.
%
    key = 1;
%
%  LU controls printing.
%  A positive value requests that we compute and print weights, and
%  conduct a moments check.
%
    lu = 6;

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Weights of Gauss quadrature formula computed from the\n' );
    fprintf ( 1, '  knots by CIQF.\n' );

    wts = ciqf ( nt, t, mlt, nwts, ndx, key, kind, alpha, beta, a, b, lu );

  end

  return
end
function test03 ( )

%*****************************************************************************80
%
%% TEST03 tests CEIQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST03\n' );
  fprintf ( 1, '  Test CEIQFS.\n' );
%
%  Number of knots.
%
  nt = 5;
%
%  Set the knots in the default interval [-1,+1].
%
  t = zeros ( nt, 1 );

  for i = 1 : nt
    t(i) = cos ( ( 2 * i - 1 ) * pi / 2.0 / nt );
  end
%
%  Set the knot multiplicities.
%
  mlt = zeros ( nt, 1 );
  mlt(1:nt) = 2;
%
%  Set KIND to the Legendre weight function.
%
  kind = 1;
%
%  ALPHA, BETA not used in Legendre weight function but set anyway.
%
  alpha = 0.0;
  beta  = 0.0;
%
%  Call CEIQFS to set up the quadrature formula and evaluate it on F.
%
  qfsum = ceiqfs ( nt, t, mlt, kind, alpha, beta, @f );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Integral of sin(x) on -1, 1 by Fejer type rule\n' );
  fprintf ( 1, '  with %d points of multiplicity 2.\n', nt );
  fprintf ( 1, '  Quadrature formula: %24.16f\n', qfsum );

  qfsx = cos ( - 1.0 ) - cos ( 1.0 );
  fprintf ( 1, '  Exact value       : %24.16f\n', qfsx );
  fprintf ( 1, '  Error             : %e\n', abs ( qfsum - qfsx ) );

  return
end
function test04 ( )

%*****************************************************************************80
%
%% TEST04 tests CEIQF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST04\n' );
  fprintf ( 1, '  Test CEIQF.\n' );
%
%  Number of knots.
%
  nt = 5;
%
%  Set the knots in the default interval [-1,+1].
%
  t = zeros ( nt, 1 );

  for i = 1 : nt
    t(i) = cos ( ( 2 * i - 1 ) * pi / 2.0 / nt );
  end
%
%  Set the knot multiplicities.
%
  mlt = zeros ( nt, 1 );
  mlt(1:nt) = 2;
%
%  Set KIND to the Legendre weight function.
%
  kind = 1;
%
%  ALPHA, BETA not used in Legendre weight function but set anyway.
%
  alpha = 0.0;
  beta  = 0.0;
%
%  Set nonstandard interval A, B.
%
  a = - 0.5;
  b = 2.0;
%
%  Shift knots from [-1,1] to [A,B].
%
  for i = 1 : nt
    t(i) = ( ( b - a ) * t(i) + ( a + b ) ) / 2.0;
  end
%
%  Call CEIQF to set up the quadrature formula and evaluate it on F.
%
  qfsum = ceiqf ( nt, t, mlt, kind, alpha, beta, a, b, @f );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Integral of sin(x) from %f to %f by Fejer type rule\n', a, b );
  fprintf ( 1, '  with %d points of multiplicity 2.\n', nt );
  fprintf ( 1, '  Quadrature formula: %24.16f\n', qfsum );

  qfsx = cos ( a ) - cos ( b );
  fprintf ( 1, '  Exact value       : %24.16f\n', qfsx );
  fprintf ( 1, '  Error             : %e\n', abs ( qfsum - qfsx ) );

  return
end
function test05 ( )

%*****************************************************************************80
%
%% TEST05 tests CLIQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST05\n' );
  fprintf ( 1, '  Test CLIQFS.\n' );
%
%  Number of knots.
%
  nt = 5;
%
%  Set the knots in the default interval [-1,+1].
%
  t = zeros(nt,1);

  for i = 1 : nt
    t(i) = cos ( ( 2 * i - 1 ) * pi / ( 2 * nt ) );
  end
%
%  Request Legendre weight function.
%
  kind = 1;
%
%  ALPHA, BETA not used in Legendre weight function but set anyway.
%
  alpha = 0.0;
  beta  = 0.0;
%
%  LU controls printing.
%  A positive value requests that we compute and print weights, and
%  conduct a moments check.
%
  lu = 6;
%
%  This call returns the WTS array.
%
  wts = cliqfs ( nt, t, kind, alpha, beta, lu );

  return
end
function test06 ( )

%*****************************************************************************80
%
%% TEST06 tests CLIQF and EIQFS..
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST06\n' );
  fprintf ( 1, '  Test CLIQF and EIQFS.\n' );
%
%  Number of knots.
%
  nt = 5;
%
%  Set the knots in the default interval [-1,+1].
%
  t = zeros(nt,1);

  for i = 1 : nt
    t(i) = cos ( ( 2 * i - 1 ) * pi / ( 2 * nt ) );
  end
%
%  Set KIND to the Legendre weight function.
%
  kind = 1;
%
%  ALPHA, BETA not used in Legendre weight function but set anyway.
%
  alpha = 0.0;
  beta  = 0.0;
%
%  Set nonstandard interval A, B.
%
  a = - 0.5;
  b = 2.0;
%
%  Shift knots from [-1,1] to [A,B].
%
  for i = 1 : nt
    t(i) = ( ( b - a ) * t(i) + ( a + b ) ) / 2.0;
  end
%
%  LU controls printout.
%
  lu = 6;
%
%  Call CLIQF to set up the quadrature formula.
%
  wts = cliqf ( nt, t, kind, alpha, beta, a, b, lu );
%
%  Call EIQFS to evaluate the quadrature formula.
%
  qfsum = eiqfs ( nt, t, wts, @f );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Integral of sin(x) from %f to %f\n', a, b );
  fprintf ( 1, '  by Fejer type rule with %d points\n', nt );
  fprintf ( 1, '  of multiplicity 1.\n' );
  fprintf ( 1, '  Quadrature formula: %24.16f\n', qfsum );

  qfsx = cos ( a ) - cos ( b );
  fprintf ( 1, '  Exact value       : %24.16f\n', qfsx );
  fprintf ( 1, '  Error             : %e\n', abs ( qfsum - qfsx ) );

  return
end
function test07 ( )

%*****************************************************************************80
%
%% TEST07 tests CEGQF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1, '  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST07\n' );
  fprintf ( 1, '  Test CEGQF.\n' );
%
%  Number of knots.
%
  nt = 12;
%
%  Request exponential weight function.
%
  kind = 7;
%
%  Set ALPHA and BETA.
%
  alpha = 1.0;
  beta  = 0.0;
%
%  Set interval [A,B].
%
  a = - 0.5;
  b = 2.0;
%
%  Call CEGQF to compute and evaluate the Gauss quadrature formula.
%
  qfsum = cegqf ( nt, kind, alpha, beta, a, b, @f );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Integral of x*sin(x) from %f to %f\n', a, b );
  fprintf ( 1, '  by Gauss-exponential rule with %d points\n', nt );
  fprintf ( 1, '  Quadrature formula: %24.16f\n', qfsum );

  qfsx = ( b - a ) * 0.5 * ( cos ( a ) - cos ( b ) ) ...
    + sin ( b ) + sin ( a ) - 2.0 * sin ( ( a + b ) / 2.0 );

  fprintf ( 1, '  Exact value       : %24.16f\n', qfsx );
  fprintf ( 1, '  Error             : %e\n', abs ( qfsum - qfsx ) );

  return
end
function test08 ( )

%*****************************************************************************80
%
%% TEST08 tests CEGQFS.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
  fprintf ( 1,'  ----------------------------------------\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST08\n' );
  fprintf ( 1, '  Test CEGQFS.\n' );
%
%  Number of knots.
%
  nt = 12;
%
%  Request exponential weight function.
%
  kind = 7;
%
%  Set ALPHA and BETA.
%
  alpha = 1.0;
  beta  = 0.0;
%
%  Call CEGQFS to compute and evaluate the Gauss quadrature formula.
%
  qfsum = cegqfs ( nt, kind, alpha, beta, @f );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Integral of x*sin(x) from -1 to +1\n' );
  fprintf ( 1, '  by Gauss-exponential rule with %d points.\n', nt )
  fprintf ( 1, '  Quadrature formula: %24.16f\n', qfsum );

  qfsx = cos ( -1.0 ) - cos ( +1.0 );

  fprintf ( 1, '  Exact value       : %24.16f\n', qfsx );
  fprintf ( 1, '  Error             : %e\n', abs ( qfsum - qfsx ) );

  return
end
function test09 ( )

%*****************************************************************************80
%
%% TEST09 calls CGQFS to compute and print generalized Gauss-Hermite rules.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 January 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST09\n' );
  fprintf ( 1, '  Call CGQFS for a generalized Gauss Hermite rule.\n' );

  nt = 15;
  kind = 6;
  alpha = 1.0;
  beta = 0.0;
  io = - 6;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  NT = %d\n', nt );
  fprintf ( 1, '  ALPHA = %f\n', alpha );

  [ t, wts ] = cgqfs ( nt, kind, alpha, beta, io );

  return
end
function test10 ( nt, kind, alpha, beta )

%*****************************************************************************80
%
%% TEST10 calls CDGQF to compute a quadrature formula.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 January 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST10\n' );
  fprintf ( 1, '  Call CDGQF to compute a quadrature formula.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  KIND = %d\n', kind );
  fprintf ( 1, '  ALPHA = %f\n', alpha );
  fprintf ( 1, '  BETA  = %f\n', beta );

  [ t, wts ] = cdgqf ( nt, kind, alpha, beta );

  fprintf ( 1, '\n' );
  fprintf ( 1, ' Index     Abscissas                 Weights\n' );
  fprintf ( 1, '\n' );
  for i = 1 : nt
    fprintf ( 1, '  %4d  %24.16e  %24.16e\n', i, t(i), wts(i) );
  end

  return
end
function test11 ( nt, kind, alpha, beta, a, b )

%*****************************************************************************80
%
%% TEST11 calls CGQF to compute a quadrature formula.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST11\n' );
  fprintf ( 1, '  Call CGQF to compute a quadrature formula\n' );
  fprintf ( 1, '  with nondefault values of A and B.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  KIND = %d\n', kind );
  fprintf ( 1, '  ALPHA = %f\n', alpha );
  fprintf ( 1, '  BETA  = %f\n', beta );
  fprintf ( 1, '  A     = %f\n', a );
  fprintf ( 1, '  B     = %f\n', b );

  lo = 0;
  [ t, wts ] = cgqf ( nt, kind, alpha, beta, lo, a, b );

  fprintf ( 1, '\n' );
  fprintf ( 1, ' Index     Abscissas                 Weights\n' );
  fprintf ( 1, '\n' );
  for i = 1 : nt
    fprintf ( 1, '  %4d  %24.16e  %24.16e\n', i, t(i), wts(i) );
  end

  return
end
function value = f ( x, i )

%*****************************************************************************80
%
%% F returns values of the integrand or its derivatives.
%
%  Discussion:
%
%    This function is an example of an integrand function.
%
%    The package can generate quadrature formulas that use derivative
%    information as well as function values.  Therefore, this routine is
%    set up to provide derivatives of any order as well as the function
%    value.  In an actual application, the highest derivative needed
%    is of order one less than the highest knot multiplicity.
%
%    In other words, in the usual case where knots are not repeated,
%    this routine only needs to return function values, not any derivatives.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
%    MATLAB version by John Burkardt.
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Input, integer I, the order of the derivative of F to
%    be evaluated.
%
%    Output, real VALUE, the value of the I-th derivative of F at X.
%
  l = mod ( i, 4 );

  if ( l == 0 )
    value = sin ( x );
  elseif ( l == 1 )
    value = cos ( x );
  elseif ( l == 2 )
    value = - sin ( x );
  elseif ( l == 3 )
    value = - cos ( x );
  end

  return
end


function varargout = information(R, opts, varargin)

%INFORMATION Computes mutual information using different methods and
% different bias correction procedures.
%
%   ------
%   SYNTAX
%   ------
%       [...] = information(R, opts, output list...)
%
%   ---------
%   ARGUMENTS
%   ---------
%   R           - Response matrix.
%   opts        - Options structure.
%   output list - List of strings specifying what to compute.
%
%   -------------------
%   THE RESPONSE MATRIX
%   -------------------
%   L-dimensional responses to S distinct stimuli are stored in a response
%   matrix R of size L-by-T-by-S, T being the maximum number of trials
%   available for any of the stimuli. Emtpy trials, i.e., elements of R not
%   corresponding to a recorded response, can take any value.
%
%   ---------------------
%   THE OPTIONS STRUCTURE
%   ---------------------
%   The options structure can include any the following fields:
%
%   opts.nt
%   -------
%       This field specifies the number of trials (responses) recorded for
%       each stimulus. It can be either a scalar (for constant number of
%       trials per stimulus) or an array of length S.
%
%       NT must satisfy the following two conditions:
%       - max(nt) = T
%       - length(nt) = S (if nt is an array)
%
%   opts.method
%   -----------
%       This field specifies which estimation method to use and can be one
%       of the following strings:
%
%       --------------------------
%       | 'dr' | Direct method   |
%       | 'gs' | Gaussian method |
%       --------------------------
%
%       IMPORTANT!
%       ==========
%       The direct method requires the response values to be discretized
%       into non-negative integer values (this is meant only in a numerical
%       sense, the MATLAB variable still needs to be of type double). See
%       function BINR.M for instruction on how to discretize the responses.
%       Failing to properly discretizing the response will result in Matlab
%       crashing.
%
%   opts.bias
%   ---------
%       This field specifies the bias correction procedure. It can be one
%       of the following strings:
%
%       -------------------------------------
%       | 'qe'    | Quadratic EXtrapolation |
%       | 'pt'    | Panzeri & Treves 1996   |
%       | 'gsb'   | Gaussian bias           |
%       | 'naive' | Biased naive estimates  |
%       -------------------------------------
%
%   opts.btsp (optional)
%   --------------------
%       This field must be a (non-negative) scalar specifying how many
%       bootstrap estimates to compute.
%
%       Bootstrap estimates are performed by means of pairing stimuli and
%       responses at random and computing the entropy quantities for these
%       random pairings; each estimate corresponds to a different random
%       pairing configuration.
%
%       See the examples below for additional information on how to use
%       this option.
%
%       DEFAULT: 0.
%
%   opts.verbose (optional)
%   -----------------------
%       If this field exists and is set to true a summary of the selected
%       options is displayed and additional checks are performed on the
%       input variables. No warnings are displayed unless this options is
%       enabled.
%
%       This feature is useful to check whether INFORMATION is being called
%       correctly. It is therefore highly reccomended for new users or when
%       first running of the program with new input options. However, keep
%       in mind that these checks drammatically increases computation time
%       and are thus not reccommended for computationally intensive
%       session.
%
%       DEFAULT: false.
%
%   ---------------
%   THE OUTPUT LIST
%   ---------------
%   To specify which IT quantities need to compute, one or more of the
%   following strings has to be specified:
%
%       =================================================================
%       | Option  | Description       | Expression (in terms of ENTROPY |
%       |         |                   | output options)                 |
%       =================================================================
%       | 'I'     | I(R;S)            | I     = HR - HRS                |
%       | 'Ish'   | I(R;S) shuffle    | Ish   = HR - HiRS + HshRS - HRS |
%       |---------------------------------------------------------------|
%       | 'IX'    | I(R)              | IX    = HlR - HR                |
%       |---------------------------------------------------------------|
%       | 'ILIN'  | I_lin(S;R)        | ILIN  = HlR - HiRS              |
%       |---------------------------------------------------------------|
%       | 'SYN'   | Syn               | SYN   = HR - HRS - HlR + HiRS   |
%       | 'SYNsh' | Syn shuffle       | SYNsh = HR + HshRS - HRS - HlR  |
%       |---------------------------------------------------------------|
%       | 'ISS'   | I_sig_sim         | ISS   = HiR - HlR               |
%       |---------------------------------------------------------------|
%       | 'IC'    | I_cor             | IC    = HR - HRS + HiRS - HiR   |
%       | 'ICsh'  | I_cor shuffle     | ICsh  = HR + HshRS - HRS - HiR  |
%       |---------------------------------------------------------------|
%       | 'ICI'   | I_cor_ind         | ICI   = ChiR - HiR              |
%       |---------------------------------------------------------------|
%       | 'ICD'   | I_cor_dep         | ICD   = HR - HRS - ChiR + HiRS  |
%       | 'ICDsh' | I_cor_dep shuffle | ICDsh = HR + HshRS - HRS - ChiR |
%       |---------------------------------------------------------------|
%       | 'ILB1'  | I_LB1             | ILB1  = HR - HiRS               |
%       |---------------------------------------------------------------|
%       | 'ILB2'  | I_LB2             | ILB2  = ChiR - HiRS             |
%       =================================================================
%
%   Outputs are returned IN THE SAME ORDER as that specified in the output
%   list.
%
%   IMPORTANT: Not all combinations of method, bias and output options are
%   possible. For example, bias correction 'pt' can only be used together
%   with method 'dr'. The allowed combinations of method, bias and output
%   options are summarized in the following tables:
%
%       =============================================
%       | DIRECT METHOD                             |
%       =============================================
%       |         | 'naive' | 'qe'  | 'pt'  | 'gsb' |
%       |-------------------------------------------|
%       | 'I'     |    X    |   X   |   X   |   -   |
%       | 'Ish'   |    X    |   X   |   X   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'IX'    |    X    |   X   |   X   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ILIN'  |    X    |   X   |   X   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'SYN'   |    X    |   X   |   X   |   -   |
%       | 'SYNsh' |    X    |   X   |   X   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ISS'   |    X    |   X   |   -   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'IC'    |    X    |   X   |   -   |   -   |
%       | 'ICsh'  |    X    |   X   |   -   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ICI'   |    X    |   X   |   -   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ICD'   |    X    |   X   |   -   |   -   |
%       | 'ICDsh' |    X    |   X   |   -   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ILB1'  |    X    |   X   |   X   |   -   |
%       |---------|---------|-------|-------|-------|
%       | 'ILB2'  |    X    |   X   |   -   |   -   |
%       =============================================
%
%   Legend: X: combination available
%           -: combination NOT permitted
%
%
%       =============================================
%       | GAUSSIAN METHOD                           |
%       =============================================
%       |         | 'naive' | 'qe'  | 'pt'  | 'gsb' |
%       |-------------------------------------------|
%       | 'I'     |    X    |  n.r. |   -   |   X   |
%       | 'Ish'   |    X    |  n.r. |   -   |   X   |
%       |---------|---------|-------|-------|-------|
%       | 'IX'    |    X    |  n.r. |   -   |   X   |
%       |---------|---------|-------|-------|-------|
%       | 'ILIN'  |    X    |  n.r. |   -   |   X   |
%       |---------|---------|-------|-------|-------|
%       | 'SYN'   |    X    |  n.r. |   -   |   X   |
%       | 'SYNsh' |    X    |  n.r. |   -   |   X   |
%       |---------|---------|-------|-------|-------|
%       | 'ISS'   |   NaN   |  NaN  |   -   |  NaN  |
%       |---------|---------|-------|-------|-------|
%       | 'IC'    |   NaN   |  NaN  |   -   |  NaN  |
%       | 'ICsh'  |   NaN   |  NaN  |   -   |  NaN  |
%       |---------|---------|-------|-------|-------|
%       | 'ICI'   |   NaN   |  NaN  |   -   |  NaN  |
%       |---------|---------|-------|-------|-------|
%       | 'ICD'   |   NaN   |  NaN  |   -   |  NaN  |
%       | 'ICDsh' |   NaN   |  NaN  |   -   |  NaN  |
%       |---------|---------|-------|-------|-------|
%       | 'ILB1'  |    X    |  n.r. |   -   |   X   |
%       |---------|---------|-------|-------|-------|
%       | 'ILB2'  |   NaN   |  NaN  |   -   |  NaN  |
%       =============================================
%
%   Legend: X   : combination available
%           -   : combination NOT permitted
%           n.r.: combination available but not recommended
%           NaN : NaN returned
%
%   --------
%   EXAMPLES
%   --------
%   In the following examples, we assume R to be a 2-by-10-by-3 matrix
%   i.e., R stores 2-dimensional responses to 3 different stimuli. We also
%   assume that, while 10 trials are available for stimulus 1 and 2, only 7
%   trials have been recorded for stimulus 3.
%
%   - Estimate I(S;R) using the direct method and no bias corrections
%
%       opts.nt = [10 10 7];
%       opts.method = 'dr';
%       opts.bias = 'naive';
%       X = information(R, opts, 'I');
%
%   - Estimate I(S;R) and I_shuffle(S;R) using direct method and the
%     quadratic extrapolation bias correction
%
%       opts.nt = [10 10 7];
%       opts.method = 'dr';
%       opts.bias = 'gsb';
%       [X, Y] = information(R, opts, 'Ish', 'I');
%
%     where the estimate of I_shuffle(S;R) is stored in the X and that of
%     I(S;R) in Y.
%
%   - Compute gaussian naive estimate of I(S;R) together with 20 bootstrap
%     estimates:
%
%       opts.nt = [10 10 7];
%       opts.method = 'gs';
%       opts.bias = 'naive';
%       opts.btsp = 20;
%       X = information(R, opts, 'I');
%
%     Note that, in this case, Y is an array of size 21-by-1: Y(1) gives
%     the estimate for I(S;R) computed using the input matrix R; Y(2:21)
%     are are 20 distinct bootstrap estimates of I(S;R).
%
%   -------
%   REMARKS
%   -------
%   - Field-names in the option structure are case-sensitive
%
%   - Ouput options are case INsensitive
%
%   - It is more efficient to call INFORMATION with several output options
%     rather than calling the function repeatedly. For example:
%
%         [X, Y] = information(R, opts, 'I', 'Ish');
%
%     is faster than
%
%         X = information(R, opts, 'I');
%         Y = information(R, opts, 'Ish');
%
%   - Some MEX files in the toolbox create static arrays which are used
%     to store computations performed in previous calls to the routines.
%     This memory is freed automatically when Matlab is quitted. However,
%     consider using
%
%         clear mex;
%
%     when needing to free all of Matlab's available memory.

% NOTE:
% The function also computes IXS and IXSsh according to the following
% equations:
%
%       =================================================================
%       | Option  | Description       | Expression (in terms of ENTROPY |
%       |         |                   | output options)                 |
%       =================================================================
%       | 'IXS'   | I(R|S)            | IXS   = HiRS - HRS              |
%       | 'IXSsh' | I(R|S) shuffle    | IXSsh = HshRS - HRS             |
%       =================================================================
%
% However, since this quantity is meaningful only for L=2, this feature
% is kept hidden. The combination tables for this quantity are
% as follows:
%
%       =============================================
%       | DIRECT METHOD                             |
%       =============================================
%       |         | 'naive' | 'qe'  | 'pt'  | 'gsb' |
%       |-------------------------------------------|
%       | 'IXS'   |    X    |   X   |   X   |   -   |
%       | 'IXSsh' |    X    |   X   |   X   |   -   |
%       =============================================
%
%   Legend: X: combination available
%           -: combination NOT available
%
%
%       =============================================
%       | GAUSSIAN METHOD                           |
%       =============================================
%       |         | 'naive' | 'qe'  | 'pt'  | 'gsb' |
%       |-------------------------------------------|
%       | 'IXS'   |    X    |  n.r. |   -   |   X   |
%       | 'IXSsh' |    X    |  n.r. |   -   |   X   |
%       =============================================
%
%   Legend: X   : combination available
%           -   : combination NOT available
%           n.r.: combination available but not recommended

%   Copyright (C) 2009 Cesare Magri
%   Version: 1.0.5

% -------
% LICENSE
% -------
% This software is distributed free under the condition that:
%
% 1. it shall not be incorporated in software that is subsequently sold;
%
% 2. the authorship of the software shall be acknowledged and the following
%    article shall be properly cited in any publication that uses results
%    generated by the software:
%
%      Magri C, Whittingstall K, Singh V, Logothetis NK, Panzeri S: A
%      toolbox for the fast information analysis of multiple-site LFP, EEG
%      and spike train recordings. BMC Neuroscience 2009 10(1):81;
%
% 3.  this notice shall remain in place in each source file.

% NOTE:
% In this function HiRS is indeed output option 'HiRS' of function
% entropy.m, thus corresponding to the variable HlRS in the same function.

whereI     = strcmpi(varargin, 'i');
whereIsh   = strcmpi(varargin, 'ish');
whereIX    = strcmpi(varargin, 'ix');
whereIXS   = strcmpi(varargin, 'ixs');
whereIXSsh = strcmpi(varargin, 'ixssh');
whereILIN  = strcmpi(varargin, 'ilin');
whereSYN   = strcmpi(varargin, 'syn');
whereSYNsh = strcmpi(varargin, 'synsh');
whereISS   = strcmpi(varargin, 'iss');
whereIC    = strcmpi(varargin, 'ic');
whereICsh  = strcmpi(varargin, 'icsh');
whereICI   = strcmpi(varargin, 'ici');
whereICD   = strcmpi(varargin, 'icd');
whereICDsh = strcmpi(varargin, 'icdsh');
whereILB1  = strcmpi(varargin, 'ilb1');
whereILB2  = strcmpi(varargin, 'ilb2');

whereuvar  = strcmpi(varargin, 'uvar');
if sum(whereuvar)
  Runit = varargin{find(whereuvar)+1};
  sel = find(whereuvar);
  sel = [sel sel+1];
  varargin(sel) = [];
end

doI     = any(whereI);
doIsh   = any(whereIsh);
doIX    = any(whereIX);
doIXS   = any(whereIXS);
doIXSsh = any(whereIXSsh);
doILIN  = any(whereILIN);
doSYN   = any(whereSYN);
doSYNsh = any(whereSYNsh);
doISS   = any(whereISS);
doIC    = any(whereIC);
doICsh  = any(whereICsh);
doICI   = any(whereICI);
doICD   = any(whereICD);
doICDsh = any(whereICDsh);
doILB1  = any(whereILB1);
doILB2  = any(whereILB2);

% Checks ------------------------------------------------------------------
specifiedOutputOptsVec = ...
    [doI doIsh doIX doIXS doIXSsh doILIN doSYN doSYNsh doISS doIC doICsh doICI doICD doICDsh doILB1 doILB2];
NspecifiedOutputOpts = sum(specifiedOutputOptsVec);
lengthVarargin = length(varargin);
if NspecifiedOutputOpts~=lengthVarargin
    msg = 'Unknown selection or repeated option in output list.';
    error('information:unknownOutputOpt', msg);
end

% Restrictions on possible combinantions ----------------------------------
if strcmpi(opts.method, 'dr')
    % Can't apply bias-correction gsb with method dr:
    if strcmpi(opts.bias, 'gsb')
        msg = 'Bias correction ''gsb'' can only be used in conjunction with method ''gs''.';
        error('Information:drMethodAndGsbBias', msg);
    end

    % Can't compute ISS, IC, ICsh, ICI, ICD, ICDsh or ILB2 for
    % bias-correction pt
    if strcmpi(opts.bias, 'pt') && (doISS || doIC || doICsh || doICI || doICD || doICDsh || doILB2)
        msg = 'One or more of the selected output options are not available for bias correction ''pt''.';
        error('information:ptBiasAndNonAvailableOutputOpt', msg);
    end
end

% Default verbose value:
if ~isfield(opts, 'verbose')
    opts.verbose = false;
end;

isGaussianMethod = false;
if strcmpi(opts.method, 'gs')
    isGaussianMethod = true;

    % Gaussian and QE is not recommended:
    if opts.verbose && strcmpi(opts.bias, 'qe')
        msg = 'Usage of bias correction ''qe'' in conjunction with gaussian method is not recommended.';
        warning('Information:gsMethodAndQeBias', msg);
    end

    % Gaussian and PT is not allowed:
    if strcmpi(opts.bias, 'pt')
        msg = 'Bias correction ''pt'' can only be used in conjunction with method ''dr''.';
        error('Information:gsMethodAndPtBias', msg);
    end
end

allOutputOpts = {'HR' 'HRS' 'HlR' 'HiR' 'HiRS' 'ChiR' 'HshRS'};
positionInOuputOptsList = 0;

% What needs to be computed by ENTTROPY -----------------------------------
% Need to compute H(R)?
doHR = false;
if doI || doIsh || doIX || doSYN || doSYNsh || doIC || doICsh || doICD || doICDsh || doILB1
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHR = positionInOuputOptsList;
    doHR = true;
end

% Need to compute H(R|S)?
doHRS = false;
if doI || doIsh || doIXS || doIXSsh || doSYN || doSYNsh || doIC || doICsh || doICD || doICDsh
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHRS = positionInOuputOptsList;
    doHRS = true;
end

% Need to compute H_lin(R)?
doHlR = false;
if doIX || doSYN || doILIN || doSYNsh || doISS
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHlR = positionInOuputOptsList;
    doHlR = true;
end

% Need to compute H_ind(R)?
doHiR = false;
if (doISS || doIC || doICsh || doICI) && ~isGaussianMethod
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHiR = positionInOuputOptsList;
    doHiR = true;
end

% Need to compute H_ind(R|S)?
doHiRS = false;
if doIsh || doIXS || doILIN || doSYN || doIC || doICD || doILB1 || doILB2
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHiRS = positionInOuputOptsList;
    doHiRS = true;
end

% Need to compute Chi(R)?
doChiR = false;
if (doICI || doICD || doICDsh || doILB2) && ~isGaussianMethod
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereChiR = positionInOuputOptsList;
    doChiR = true;
end

% Need to compute H_sh(R|S)?
doHshRS = false;
if doIsh || doIXSsh || doSYNsh || doICsh || doICDsh
    positionInOuputOptsList = positionInOuputOptsList + 1;
    whereHshRS = positionInOuputOptsList;
    doHshRS = true;
end

% Computing information theoretic quantities ------------------------------
outputOptsList = allOutputOpts([doHR doHRS doHlR doHiR doHiRS doChiR doHshRS]);

H = cell(positionInOuputOptsList, 1);
if ~exist('Runit', 'var')
  [H{:}] = entropy(R, opts, outputOptsList{:});
else
  [H{:}] = entropy(R, opts, outputOptsList{:}, 'uvar', Runit);
end

% Assigning output --------------------------------------------------------
varargout = cell(length(varargin),1);

% I = HR - HRS
if doI
    varargout(whereI) = {H{whereHR} - H{whereHRS}};
end

% Ish = HR - HiRS + HshRS - HRS
if doIsh
    varargout(whereIsh) = {H{whereHR} - H{whereHiRS} + H{whereHshRS} - H{whereHRS}};
end

% IX = HlR - HR
if doIX
    varargout(whereIX) = {H{whereHlR} - H{whereHR}};
end

% IXS = HiRS - HRS
if doIXS
    varargout(whereIXS) = {H{whereHiRS} - H{whereHRS}};
end

% IXSsh = HshRS - HRS
if doIXSsh
    varargout(whereIXSsh) = {H{whereHshRS} - H{whereHRS}};
end

% ILIN = HlR - HiRS
if doILIN
    varargout(whereILIN) = {H{whereHlR} - H{whereHiRS}};
end

% SYN = HR - HRS - HlR + HiRS
if doSYN
    varargout(whereSYN) = {H{whereHR} - H{whereHRS} - H{whereHlR} + H{whereHiRS}};
end

% SYNsh = HR + HshRS - HRS - HlR
if doSYNsh
    varargout(whereSYNsh) = {H{whereHR} + H{whereHshRS} - H{whereHRS} - H{whereHlR}};
end

% ISS = HiR - HlR
if doISS
    if ~isGaussianMethod
        varargout(whereISS) = {H{whereHiR} - H{whereHlR}};
    else
        varargout(whereISS) = {NaN};
    end
end

% IC = HR - HRS + HiRS - HiR
if doIC
    if ~isGaussianMethod
        varargout(whereIC) = {H{whereHR} - H{whereHRS} + H{whereHiRS} - H{whereHiR}};
    else
        varargout(whereIC) = {NaN};
    end
end

% ICsh  = HR + HshRS - HRS - HiR
if doICsh
    if ~isGaussianMethod
        varargout(whereICsh) = {H{whereHR} + H{whereHshRS} - H{whereHRS} - H{whereHiR}};
    else
        varargout(whereICsh) = {NaN};
    end
end

% ICI= ChiR - HiR
if doICI
    if ~isGaussianMethod
        varargout(whereICI) = {H{whereChiR} - H{whereHiR}};
    else
        varargout(whereICI) = {NaN};
    end
end

% ICD = HR - HRS - ChiR + HiRS
if doICD
    if ~isGaussianMethod
        varargout(whereICD) = {H{whereHR} - H{whereHRS} - H{whereChiR} + H{whereHiRS}};
    else
        varargout(whereICD) = {NaN};
    end
end

% ICDsh = HR + HshRS - HRS - ChiR
if doICDsh
    if ~isGaussianMethod
        varargout(whereICDsh) = {H{whereHR} + H{whereHshRS} - H{whereHRS} - H{whereChiR}};
    else
        varargout(whereICDsh) = {NaN};
    end
end

% ILB1 = HR - HiRS
if doILB1
    varargout(whereILB1) = {H{whereHR} - H{whereHiRS}};
end

% ILB2 = ChiR - HiRS
if doILB2
    if ~isGaussianMethod
        varargout(whereILB2) = {H{whereChiR} - H{whereHiRS}};
    else
        varargout(whereILB2) = {NaN};
    end
end


function PlotMesh(coordinates,nodes)
%--------------------------------------------------------------------------
% Code written by : Siva Srinivas Kolukula                                |
%                   Senior Research Fellow                                |
%                   Structural Mechanics Laboratory                       |
%                   Indira Gandhi Center for Atomic Research              |
%                   India                                                 |
% E-mail : allwayzitzme@gmail.com                                         |
%          http://sites.google.com/site/kolukulasivasrinivas/             |
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% Purpose:
%         To plot the Finite Element Method Mesh
% Synopsis :
%           PlotMesh(coordinates,nodes)
% Variable Description:
%           coordinates - The nodal coordinates of the mesh
%           -----> coordinates = [node X Y]
%           nodes - The nodal connectivity of the elements
%           -----> nodes = [node1 node2......]
%--------------------------------------------------------------------------

nel = length(nodes) ;                  % number of elements
nnode = length(coordinates) ;          % total number of nodes in system
nnel = size(nodes,2);                % number of nodes per element
%
% Initialization of the required matrices
X = zeros(nnel,nel) ;
Y = zeros(nnel,nel) ;

for iel=1:nel
     for i=1:nnel
     nd(i)=nodes(iel,i);         % extract connected node for (iel)-th element
     X(i,iel)=coordinates(nd(i),1);    % extract x value of the node
     Y(i,iel)=coordinates(nd(i),2);    % extract y value of the node
     end
end

% Plotting the FEM mesh, diaplay Node numbers and Element numbers
     f1 = figure ;
     set(f1,'name','Mesh','numbertitle','off') ;
     plot(X,Y,'k')
     fill(X,Y,'w')

     title('Finite Element Mesh') ;
     axis off ;
     k = nodes(:,1:end);
     nd = k' ;
    for i = 1:nel
     text(X(:,i),Y(:,i),int2str(nd(:,i)),'fontsize',8,'color','k');
     text(sum(X(:,i))/4,sum(Y(:,i))/4,int2str(i),'fontsize',10,'color','r') ;
    end


function Solution = GhiaSolution
%GhiaSolution returns a benchmark solution for lid-driven cavity flow
%   The data is taken from:
%     Ghia, U. K. N. G., Kirti N. Ghia, and C. T. Shin.
%     "High-Re solutions for incompressible flow using the Navier-Stokes
%     equations and a multigrid method."
%     Journal of computational physics 48.3 (1982): 387-411.

Solution.Re=[100 400 1000];

Solution.y = [1.0000,...
              0.9766,...
              0.9688,...
              0.9609,...
              0.9531,...
              0.8516,...
              0.7344,...
              0.6172,...
              0.5000,...
              0.4531,...
              0.2813,...
              0.1719,...
              0.1016,...
              0.0703,...
              0.0625,...
              0.0547,...
              0.0000];
% Re=100
Solution.u{1}=   [1.0000,...
                  0.84123,...
                  0.78871,...
                  0.73722,...
                  0.68717,...
                  0.23151,...
                  0.00332,...
                 -0.13641,...
                 -0.20581,...
                 -0.21090,...
                 -0.15662,...
                 -0.10150,...
                 -0.06434,...
                 -0.04775,...
                 -0.04192,...
                 -0.03717,...
                  0.00000];
% Re=400
Solution.u{2}=   [1.00000,...
                  0.75837,...
                  0.68439,...
                  0.61756,...
                  0.55892,...
                  0.29093,...
                  0.16256,...
                  0.02135,...
                 -0.11477,...
                 -0.17119,...
                 -0.32726,...
                 -0.24299,...
                 -0.14612,...
                 -0.10338,...
                 -0.09266,...
                 -0.08186,...
                  0.00000];
%Re=1000
Solution.u{3}=   [1.0000,...
                  0.65928,...
                  0.57492,...
                  0.51117,...
                  0.46604,...
                  0.33304,...
                  0.18719,...
                  0.05702,...
                 -0.06080,...
                 -0.10648,...
                 -0.27805,...
                 -0.38289,...
                 -0.29730,...
                 -0.22220,...
                 -0.20196,...
                 -0.18109,...
                  0.00000];

Solution.x = [1.0000,...
              0.9688,...
              0.9609,...
              0.9531,...
              0.9453,...
              0.9063,...
              0.8594,...
              0.8047,...
              0.5000,...
              0.2344,...
              0.2266,...
              0.1563,...
              0.0938,...
              0.0781,...
              0.0703,...
              0.0625,...
              0.0000];
%Re=100
Solution.v{1}=[0.00000,...
              -0.05906,...
              -0.07391,...
              -0.08864,...
              -0.10313,...
              -0.16914,...
              -0.22445,...
              -0.24533,...
               0.05454,...
               0.17527,...
               0.17507,...
               0.16077,...
               0.12317,...
               0.10890,...
               0.10091,...
               0.09233,...
               0.00000];
% Re=400
Solution.v{2}=[0.00000,...
              -0.12146,...
              -0.15663,...
              -0.19254,...
              -0.22847,...
              -0.23827,...
              -0.44993,...
              -0.38598,...
               0.05186,...
               0.30174,...
               0.30203,...
               0.28124,...
               0.22965,...
               0.20920,...
               0.19713,...
               0.18360,...
               0.00000];
%Re=1000
Solution.v{3}=[0.00000,...
              -0.21388,...
              -0.27669,...
              -0.33714,...
              -0.39188,...
              -0.51550,...
              -0.42665,...
              -0.31966,...
               0.02526,...
               0.32235,...
               0.33075,...
               0.37095,...
               0.32627,...
               0.30353,...
               0.29012,...
               0.27485,...
               0.00000];

end


function life3D(action)
%LIFE3D   MATLAB's version of Conway's Game of Life.
%   "Life" is a cellular automaton invented by John
%   Conway that involves live and dead cells in a
%   rectangular, two-dimensional universe. In
%   MATLAB, the universe is a sparse matrix that
%   is initially all zero.
%
%   Whether cells stay alive, die, or generate new
%   cells depends upon how many of their eight
%   possible neighbors are alive. By using sparse
%   matrices, the calculations required become
%   astonishingly simple. We use periodic (torus)
%   boundary conditions at the edges of the
%   universe. Pressing the "Start" button
%   automatically seeds this universe with several
%   small random communities. Some will succeed
%   and some will fail.
%
%   Expanded to 3D by:
%       Leandro Barajas 06-20-2002 L.G.Barajas@ieee.org
%
%   C. Moler, 7-11-92, 8-7-92.
%   Adapted by Ned Gulley, 6-21-93
%

%   Copyright 1984-2001 The MathWorks, Inc.
%   $Revision: 5.9 $  $Date: 2001/04/15 12:03:02 $

% Possible actions:
% initialize
% start

% Information regarding the play status will be held in
% the axis user data according to the following table:
play= 1;
stop=-1;

if nargin<1,
   action='initialize';
end;

if strcmp(action,'initialize'),
   figNumber=figure( ...
      'Name','Life3D: Conway''s Game of Life in 3-Dimesions', ...
      'NumberTitle','off', ...
      'DoubleBuffer','on', ...
      'Visible','off', ...
      'Color','white', ...
      'BackingStore','off');
   axes( ...
      'Units','normalized', ...
      'Position',[0.05 0.05 0.75 0.90], ...
      'Visible','off', ...
      'DrawMode','fast', ...
      'Color','none',...
      'NextPlot','add');
%      'NextPlot','replace' );

   text(0,0,{'Press the "Start" button to see the Game of Life demo' 'Use the slider to change the number of initial cells.'}, ...
      'HorizontalAlignment','center');
   axis([-1 1 -1 1]);

   %===================================
   % Information for all buttons
   labelColor=[0.8 0.8 0.8];
   yInitPos=0.90;
   xPos=0.85;
   btnLen=0.10;
   btnWid=0.10;
   % Spacing between the button and the next command's label
   spacing=0.05;

   %====================================
   % The CONSOLE frame
   frmBorder=0.02;
   yPos=0.05-frmBorder;
   frmPos=[xPos-frmBorder yPos btnLen+2*frmBorder 0.9+2*frmBorder];
   h=uicontrol( ...
      'Style','frame', ...
      'Units','normalized', ...
      'Position',frmPos, ...
      'BackgroundColor',[0.50 0.50 0.50]);

   %====================================
   % The START button
   btnNumber=1;
   yPos=0.90-(btnNumber-1)*(btnWid+spacing);
   labelStr='Start';
   cmdStr='start';
   callbackStr='life3D(''start'');';

   % Generic button information
   btnPos=[xPos yPos-spacing btnLen btnWid];
   startHndl=uicontrol( ...
      'Style','pushbutton', ...
      'Units','normalized', ...
      'Position',btnPos, ...
      'String',labelStr, ...
      'Interruptible','on', ...
      'Callback',callbackStr);

   %====================================
   % The STOP button
   btnNumber=2;
   yPos=0.90-(btnNumber-1)*(btnWid+spacing);
   labelStr='Stop';
   % Setting userdata to -1 (=stop) will stop the demo.
   callbackStr='set(gca,''Userdata'',-1)';

   % Generic button information
   btnPos=[xPos yPos-spacing btnLen btnWid];
   stopHndl=uicontrol( ...
      'Style','pushbutton', ...
      'Units','normalized', ...
      'Position',btnPos, ...
      'Enable','off', ...
      'String',labelStr, ...
      'Callback',callbackStr);

   %====================================
   % The NumberOfCell Slider
   labelStr='# Cells';

   callbackStr='h=findobj(gcf,''Tag'',''StartCells'');set(h,''Tooltip'',sprintf(''Initial Cells: %4d'',floor(get(h,''Value''))));';
   infoHndl=uicontrol( ...
      'Style','slider', ...
      'Units','normalized', ...
      'Position',[xPos btnWid+btnWid*2+0.05 btnLen/4 0.10*3], ...
      'String',labelStr, ...
      'SliderStep',[.01 .1], ...
      'Max',100, ...
      'Min',1, ...
      'Value',20, ...
      'Tooltip','Initial Cells:  20',...
      'Tag','StartCells', ...
      'Callback',callbackStr);

  %====================================
   % The INFO button
   labelStr='Info';
   callbackStr='life3D(''info'')';
   infoHndl=uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[xPos 0.20 btnLen 0.10], ...
      'String',labelStr, ...
      'Callback',callbackStr);

   %====================================
   % The CLOSE button
   labelStr='Close';
   callbackStr='close(gcf)';
   closeHndl=uicontrol( ...
      'Style','push', ...
      'Units','normalized', ...
      'Position',[xPos 0.05 btnLen 0.10], ...
      'String',labelStr, ...
      'Callback',callbackStr);

   % Uncover the figure
   hndlList=[startHndl stopHndl infoHndl closeHndl];
   set(figNumber,'Visible','on', ...
      'UserData',hndlList);

   view(3);
   StartCells = 20;
   m = 19;
   colormap(jet(m));
   colorbar;

elseif strcmp(action,'start'),
   objh=findobj(gcf,'Tag','StartCells');
   StartCells = get(objh,'Value');
   m = 19;
   cla;
   axHndl=gca;
   figNumber=gcf;
   hndlList=get(figNumber,'Userdata');
   startHndl=hndlList(1);
   stopHndl=hndlList(2);
   infoHndl=hndlList(3);
   closeHndl=hndlList(4);
   set([startHndl closeHndl infoHndl],'Enable','off');
   set(stopHndl,'Enable','on');

   % ====== Start of Demo
   set(axHndl, ...
      'UserData',play, ...
      'DrawMode','fast', ...
      'Visible','on');
   box off

   X = zeros(m,m,m);

   p = -1:1;
   for count=1:StartCells,
      kx=floor(rand*(m-4))+2;
      ky=floor(rand*(m-4))+2;
      kz=floor(rand*(m-4))+2;
      X(kx+p,ky+p,kz+p)=(rand(3,3,3)>0.5);
   end;

   % The following statements plot the initial configuration.
   % The "find" function returns the indices of the nonzero elements.
   plothandle=[];
   figure(gcf);
   hold on
   colour=jet(m);
   for k=1:m
       [i,j] = find(X(:,:,k));
%       kd = sub2ind(size(X(i,j,k)),i,j)
       kd = k(ones(size(i)));
       if isempty(i)
           i = 1;
           j = 1;
           kd = NaN;
       end
       plothandle(k) = line(i,j,kd);
       set(plothandle(k),'linestyle','none',...
                      'Marker','.',...
                      'MarkerSize',20*2,...
                      'MarkerFaceColor',colour(k,:),...
                      'MarkerEdgeColor',colour(k,:),...
                      'EraseMode','normal');

   end
   drawnow
   axis([0 m+1 0 m+1 0 m+1]);

   hold off

   % Whether cells stay alive, die, or generate new cells depends
   % upon how many of their eight possible neighbors are alive.
   % Here we generate index vectors for four of the eight neighbors.
   % We use periodic (torus) boundary conditions at the edges of the universe.

   n = [m 1:m-1];
   e = [2:m 1];
   s = [2:m 1];
   w = [m 1:m-1];
   u = [m 1:m-1];
   d = [2:m 1];

   rotate3d on
   while get(axHndl,'UserData')==play,
    % How many of eight+5+5 neighbors are alive. (only the ones that share at least one border
    %      N = X(n,:,:) + X(s,:,:) + X(:,e,:) + X(:,w,:) + ...
    %          X(n,e,:) + X(n,w,:) + X(s,e,:) + X(s,w,:);

    % 3D Version

    % Use Euclidean distance
    d1 = 1/1;           % Adjacent cells (Share 4 vertix)
    d2 = 1/sqrt(2);     % Diagonal cells (Share 2 vertix)
    d3 = 1/sqrt(3);     % Double Diagonal cells (Share 1 vertix)

    % How many of 9+9+8 neighbors are alive. (Only the ones that share at least one vertix)
      N = X(n,:,:)*d1 + X(s,:,:)*d1 + X(:,e,:)*d1 + X(:,w,:)*d1 + ...
          X(n,e,:)*d2 + X(n,w,:)*d2 + X(s,e,:)*d2 + X(s,w,:)*d2 + ...
          X(n,:,u)*d2 + X(s,:,u)*d2 + X(:,e,u)*d2 + X(:,w,u)*d2 + ...
          X(n,:,d)*d2 + X(s,:,d)*d2 + X(:,e,d)*d2 + X(:,w,d)*d2 + ...
          X(n,e,u)*d3 + X(s,e,u)*d3 + X(s,w,u)*d3 + X(n,w,u)*d3 + ...
          X(n,e,d)*d3 + X(s,e,d)*d3 + X(s,w,d)*d3 + X(n,w,d)*d3 + ...
          X(:,:,u)*d1 + X(:,:,d)*d1;

      % A live cell with two live neighbors, or any cell with three
      % neigbhors, is alive at the next time step.
      Xold = X;

      CL = 3.0;             % Minimun # cells to create a new one
      CH = 4.0;             % Maximum # cells to create a new one
      KL = 4.0;             % Minimun # cells to kill one

      X = ( (    ((N >= CL) & (N <= CH)) ) &...    % Create cells
         ~(  X & ((N >  KL)           )) ) ;       % Kill cells by overpopulation

      Xsum = sum(X(:));
      if (Xsum>prod(size(X))/8);
         X = ( X & (rand(size(X))>0.1) ); % Expontaneous cell annihilation
      end

      if Xold==X   % if no change the exit
         break;
      end

      % Update plot.
      for k=1:m
          [i,j] = find(X(:,:,k));
          set(plothandle(k),'xdata',i,'ydata',j,'zdata',k(ones(size(i))));
      end

      set(plothandle,'Visible','on');
      box on
      title( sprintf('Total Cells: %d',Xsum))
      xlabel(sprintf('Density: %5.2f%%',mean(X(:))*100))
      ylabel(sprintf('Rate: %5.2f%%',(mean(X(:))-mean(Xold(:)))*100))

      drawnow
      pause(0.2)
   end

   % ====== End of Demo

   set([startHndl closeHndl infoHndl],'Enable','on');
   set(stopHndl,'Enable','off');

elseif strcmp(action,'info');
   helpwin(mfilename);

end;    % if strcmp(action, ...


function stroud_test27 ( )

%*****************************************************************************80
%
%% TEST27 tests SIMPLEX_ND.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 April 2009
%
%  Author:
%
%    John Burkardt
%
  global FUNC_ND_INDEX;

  num = function_nd_num ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST27\n' );
  fprintf ( 1, '  SIMPLEX_ND approximates integrals inside an\n' );
  fprintf ( 1, '    arbitrary simplex in ND.\n' );
  fprintf ( 1, '\n' );

  for n = 2 : 4

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Spatial dimension N = %d\n', n );
%
%  Restore values of simplex.
%
    v = setsim ( n );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Simplex vertices:\n' );
    fprintf ( 1, '\n' );

    for i = 1 : n+1
      for j = 1 : n
        fprintf ( 1, '  %4f', v(i,j) );
      end
      fprintf ( 1, '\n' );
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  F(X)    SIMPLEX_ND\n' );
    fprintf ( 1, '\n' );

    for i = 1 : num

      FUNC_ND_INDEX = i;

      result = simplex_nd ( 'function_nd', n, v );

      fname = function_nd_name ( i );

      fprintf ( 1, '  %s  %14f\n', fname, result );

      v = setsim ( n );

    end

  end

  return
end


function x = project_box(v, l, u)
% PROJECT_BOX    Project a point onto a box (hyper-rectangle).
%
%   project_box(v,l,u) is the projection of v onto
%   the set { x | l <= x <= u }.

    x = max(l, min(v, u));
end


function nMC=grMinEdgeCover(E)
% Function nMC=grMinEdgeCover(E) solve the minimal edge cover problem.
% Input parameter:
%   E(m,2) or (m,3) - the edges of graph and their weight;
%     1st and 2nd elements of each row is numbers of vertexes;
%     3rd elements of each row is weight of edge;
%     m - number of edges.
%     If we set the array E(m,2), then all weights is 1.
% Output parameter:
%   nMC - the list of the numbers of edges included
%     in the minimal (weighted) edge cover.
% Uses the reduction to integer LP-problem.
% Required the Optimization Toolbox v.3.0.1 or over.
% Author: Sergiy Iglin
% e-mail: siglin@yandex.ru
% personal page: http://iglin.exponenta.ru

% ============= Input data validation ==================
if nargin<1,
  error('There are no input data!')
end
[m,n,E] = grValidation(E); % E data validation

% ============= Parameters of integer LP problem ==========
A=zeros(n,m); % for incidence matrix
A(E(:,1:2)+repmat(([1:m]'-1)*n,1,2))=1; % we fill the incidence matrix
options=optimset('bintprog'); % the default options
options.Display='off'; % we change the output

% ============= We solve the integer LP problem ==========
xmin=bintprog(E(:,3),-A,-ones(n,1),[],[],[],options);
nMC=find(round(xmin)); % the answer - numbers of edges
return