% [covmatrix] = covfunc(theta)
% [covmatrix, theta] = rand_theta(theta, covmatrix, Y, covfunc,
%                                 logposterior)
% [rand_y] = get_randfunc_y(covmatrix)
% Y = rand_y(covmatrix, Y, I)
% [y, dy] = logprior_theta(theta)
% [y, dy] = loglikelihood_theta(Y, covmatrix)

% COVMATRIX:
% L1/LD1
% L2/LD2
% linsolve1
% linsolve2
% K1
% K2
% logdet1
% logdet2

function res = test_gp_kron(N1,N2,N_samples,seed)

%
% DATA
%

%randn('state', 10)
%rand('state', 10)

if nargin == 0
  N1 = 200;
  N2 = 300;
end
if nargin < 3
  N_samples = 100;
end
if nargin >= 4
  randn('state', seed);
  rand('state', seed);
else
  randn('state', 10);
  rand('state', 10);
end

% Inputs
x1 = 1:N1;
x2 = 1:N2;

% Covariance models

d1 = sqrt(sq_dist(x1(1), x1));
covfunc1 = gp_cov_pp(d1,1);
covfunc1 = gp_cov_toeplitz(covfunc1);
theta1 = 10;
K1 = covfunc1(theta1);

d2 = sqrt(sq_dist(x2(1), x2));
covfunc2 = gp_cov_pp(d2,1);
covfunc2 = gp_cov_toeplitz(covfunc2);
theta2 = 10;
K2 = covfunc2(theta2);

% $$$ nz1 = nnz(K1)
% $$$ nz2 = nnz(K2)
% $$$ K = kron(K1,K2);
% $$$ whos
% $$$ t = cputime();
% $$$   LD = ldlchol(K);
% $$$   ldlsolve(LD,randn(N1*N2,1));
% $$$ time = cputime() - t
% $$$ return

% $$$ % Plot gradients
% $$$ [K1, dK1] = covfunc1(theta1);
% $$$ figure
% $$$ subplot(3,1,1)
% $$$ imagesc(K1)
% $$$ subplot(3,1,2)
% $$$ imagesc(dK1{1})
% $$$ subplot(3,1,3)
% $$$ imagesc(dK1{2})
% $$$ return

disp('Generate data..')

% Generate noisy data
a = 1;
s = 1;
Y = a * kronprod(lchol(K1), lchol(K2), randn(N2,N1));
% $$$ Y = a * (lchol(K2) * randn(N2,N1) * lchol(K1)');
save('Y_noiseless', 'Y');
Y = Y + s*randn(N2,N1);
save('Y_noisy', 'Y');

% Missing values
pmv = 0.5;
%Imv = randperm(N2*N1);
%Imv = Imv(1:floor(pmv*(N2*N1)));
Imv = rand(N2,N1) < pmv;
%Imv = (rand(N2,N1) < 0.2);
ind1 = ceil(N1/2) + (1:(2*theta1));
ind2 = ceil(N2/2) + (1:(2*theta2));
Imv(ind2,ind1) = true;
Y(Imv) = nan;

%
% INFERENCE
%

a = 1e-3;
b = 1e-3;
logprior_theta = @(theta) sum(gamma_logpdf(theta, a, b));
dlogprior_theta = @(theta) gamma_dlogpdf(theta, a, b);

% Gibbs sampling for Y(missing) and covariance parameters
burnin = floor(N_samples/2);

% Initial guess for covariance parameters
theta_init = [2.0        ... % total magnitude
              2.0*theta1 ... % 1) length scale
              0.5*theta2 ... % 2) length scale
              2.0]';         % noise magnitude

res = gp_kron(Y, covfunc1, covfunc2, N_samples, theta_init, ...
              logprior_theta, dlogprior_theta, burnin)

save(sprintf('/home/jluttine/matlab/gp/results_test_gp_kron_%s', ...
             datestr(now,'yyyymmdd')), ...
     '-struct', 'res');

cl = max(abs(Y(:))) + 0.1;
clim = [-cl cl];

Y(Imv) = cl;

figure()
clf

subplot(2,3,1)
imagesc(Y,clim)

load('Y_noiseless')

subplot(2,3,4)
imagesc(Y,clim)
title('true')

subplot(2,3,5)
imagesc(res.F,clim)
title('mean')

subplot(2,3,6)
F_var = sqrt(res.FF - res.F.*res.F);
clim_var = [0, max(F_var(:))];
imagesc(F_var,clim_var)
title('std')

map_colormap();
cm = colormap();
cm(end,:) = [0.5 0.5 0.5];
colormap(cm);

rmse_F = rmse(Y,res.F)

subplot(2,3,2)
semilogy(res.theta');

subplot(2,3,3)
%lag = 200;
plot(acorr(res.theta(:,burnin:end)'));

figure()
plot_scatterhist(res.theta(:,burnin:end)');


function triangulation_test026 ( )

%*****************************************************************************80
%
%% TEST026 tests DIAEDG.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 June 2009
%
%  Author:
%
%    John Burkardt
%
  node_num = 4;
  triangle_num = 2;
  triangle_order = 3;
  seed = 123456789;
  test_num = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST026\n' );
  fprintf ( 1, '  DIAEDG determines whether two triangles\n' );
  fprintf ( 1, '  with a common edge need to "swap" diagonals.\n' );
  fprintf ( 1, '  If swapping is indicated, then ALPHA_MIN should increase.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Swap   ALPHA_MIN   ALPHA_MIN\n' );
  fprintf ( 1, '         Unswapped   Swapped\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
%
%  Generate a random quadrilateral (1,2,3,4).
%
    [ node_xy, seed ] = quad_convex_random ( seed );
%
%  Does it need swapping?
%
    value = diaedg ( ...
      node_xy(1,1), node_xy(2,1), ...
      node_xy(1,2), node_xy(2,2), ...
      node_xy(1,3), node_xy(2,3), ...
      node_xy(1,4), node_xy(2,4) );

    if ( value == 1 )
      swap = 0;
    else
      swap = 1;
    end
%
%  Compute ALPHA_MIN unswapped.
%
    triangle_node(1:3,1) = [ 1, 2, 3 ]';
    triangle_node(1:3,2) = [ 1, 3, 4 ]';

    [ alpha_min_unswapped, alpha_ave, alpha_area ] = alpha_measure ( ...
      node_num, node_xy, triangle_order, triangle_num, triangle_node );
%
%  Compute ALPHA_MIN swapped.
%
    triangle_node(1:3,1) = [ 1, 2, 4 ]';
    triangle_node(1:3,2) = [ 2, 3, 4 ]';

    [ alpha_min_swapped, alpha_ave, alpha_area ] = alpha_measure ( ...
      node_num, node_xy, triangle_order, triangle_num, triangle_node );

    if ( 0 )
      r8mat_transpose_print ( 2, node_num, node_xy, '  Quadrilateral' );
    end

    fprintf ( 1, '     %1d  %10f  %10f\n', ...
      swap, alpha_min_unswapped, alpha_min_swapped );

  end

  return
end


function value = r8_round_i4 ( x )

%*****************************************************************************80
%
%% R8_ROUND_I4 rounds an R8 to the nearest integral value, returning an I4.
%
%  Discussion:
%
%    In MATLAB, it is essentially true that there is little difference between
%    this function and R8_ROUND, because we store our integers in what amounts
%    to a real variable.
%
%  Example:
%
%        X        R8_ROUND_I4
%
%      1.3         1
%      1.4         1
%      1.5         1 or 2
%      1.6         2
%      0.0         0
%     -0.7        -1
%     -1.1        -1
%     -1.6        -2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the value.
%
%    Output, integer R8_ROUND_I4, the rounded value.
%
  if ( x < 0.0 )
    value = - floor ( - x + 0.5 );
  else
    value =   floor ( + x + 0.5 );
  end

  return
end


function complete_symmetric_poly_test ( )

%*****************************************************************************80
%
%% COMPLETE_SYMMETRIC_POLY_TEST tests COMPLETE_SYMMETRIC_POLY.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2013
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'COMPLETE_SYMMETRIC_POLY_TEST\n' );
  fprintf ( 1, '  COMPLETE_SYMMETRIC_POLY evaluates a complete symmetric.\n' );
  fprintf ( 1, '  polynomial in a given set of variables X.\n' );

  n = 5;
  x = [ 1.0, 2.0, 3.0, 4.0, 5.0 ];
  r8vec_print ( n, x, '  Variable vector X:' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '   N\\R     0       1       2       3       4       5\n' );
  fprintf ( 1, '\n' );

  for nn = 0 : n
    fprintf ( 1, '  %2d', nn );
    for rr = 0 : 5
      value = complete_symmetric_poly ( nn, rr, x );
      fprintf ( 1, '  %6d', value );
    end
    fprintf ( 1, '\n' );
  end

  return
end


function jac = p40_jac ( neqn, t, y )

%*****************************************************************************80
%
%% P40_JAC evaluates the jacobian for problem p40.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NEQN, the number of equations.
%
%    Input, real T, Y(NEQN), the arguments of the jacobian.
%
%    Output, real JAC(NEQN,NEQN), the jacobian matrix.
%
  jac = zeros ( neqn, neqn );

  e = p40_param ( 'GET', 'E', [] );

  jac(1,1) = ( 2.0 * y(1) - t ) / e;

  return
end


%CentralCamera.visjac_e Visual motion Jacobian for point feature
%
% J = C.visjac_e(E, PL) is the image Jacobian (5x6) for the ellipse
% E (5x1) described by u^2 + E1v^2 - 2E2uv + 2E3u + 2E4v + E5 = 0.  The
% ellipse lies in the world plane PL = (a,b,c,d) such that aX + bY + cZ + d = 0.
%
% The Jacobian gives the rates of change of the ellipse parameters in
% terms of camera spatial velocity.
%
% Reference::
% B. Espiau, F. Chaumette, and P. Rives,
% "A New Approach to Visual Servoing in Robotics",
% IEEE Transactions on Robotics and Automation,
% vol. 8, pp. 313-326, June 1992.
%
% See also CentralCamera.visjac_p, CentralCamera.visjac_p_polar, CentralCamera.visjac_l.

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

function L = visjac_e(cam, A, plane)

    a = -plane(1)/plane(4); b = -plane(2)/plane(4); c = -plane(3)/plane(4);
    L = [
2*b*A(2)-2*a*A(1), 2*A(1)*(b-a*A(2)), 2*b*A(4)-2*a*A(1)*A(3), 2*A(4), 2*A(1)*A(3), -2*A(2)*(A(1)+1)
b-a*A(2), b*A(2)-a*(2*A(2)^2-A(1)), a*(A(4)-2*A(2)*A(3))+b*A(3), -A(3), -(2*A(2)*A(3)-A(4)), A(1)-2*A(2)^2-1
c-a*A(3), a*(A(4)-2*A(2)*A(3))+c*A(2), c*A(3)-a*(2*A(3)^2-A(5)), -A(2), 1+2*A(3)^2-A(5), A(4)-2*A(2)*A(3)
A(3)*b+A(2)*c-2*a*A(4), A(4)*b+A(1)*c-2*a*A(2)*A(4), b*A(5)+c*A(4)-2*a*A(3)*A(4), A(5)-A(1), 2*A(3)*A(4)+A(2), -2*A(2)*A(4)-A(3)
2*c*A(3)-2*a*A(5), 2*c*A(4)-2*a*A(2)*A(5), 2*c*A(5)-2*a*A(3)*A(5), -2*A(4), 2*A(3)*A(5)+2*A(3), -2*A(2)*A(5)
];
    L = L * diag([0.5,0.5,0.5, 1,1,1]);   % not sure why...


                    function ekin
% ***************************************************************
%                   P r o g r a m   EKIN
% ***************************************************************
%
% PURPOSE:
%   Derive differential equation of motion of a mechanical
%   system with one degree of freedom by means of the theo-
%   rem of Kinetic Energy     dEk/dt = N(t,q,qt)
%   Resolve the equation numerically and plots the graphics
%   of the coordinate, velocity and phase plane.
%   If possible, the program could solve the problem analytically.
%
% INPUT DATA:
%   Ek   - expression of the kinetic energy Ek = Ek(q,qt);
%   N    - power of the forces and moments N = N(t,q,qt);
%   q0   - initial value of the coordinate;
%   qt0  - initial value of the velocity;
%   Tend - upper bound of the integration;
%   eps  - precision of the calculations;
%   np   - number of parameters .
%   P{1}, P{2}, ..., P{np} - names of the parameters (array of cells);
%
%  NOTES:
%   1. The coordinate is designed by the symbol 'q' and velocity by 'qt';
%   2. The physical names of the parameters are assigned to the
%      cells of the array P like this: P{1}='m', P{2}='c',...;
%   3. For analytical solution the values of Tend, eps, np and P are not
%      needed.
%   4. Initial values q0, qt0 must to be entered as strings, even though
%      they represent numbers!
%   5. All the data can be input from file or in interactive mode.
%
%  EXAMPLE of DATA FILE:
%   % Data for problem ...
%     Ek   = '1/2*a*qt^2';
%     N    = '-(k*qt + 9.81*sin(q))*qt';
%     q0   = 'q0';  ( or q0  = '0.12';)
%     qt0  = 'qt0'; ( or qt0 = '7.5';)
%     Tend = 20;
%     eps  = 1.e-8;
%     np   = 2;
%     P{1} = 'a';
%     P{2} = 'k';

% ---------------------------------------------------------
%                DATA INPUT OF THE PROBLEM
% =========================================================

 clear
 disp(' ');
 disp(' How will you input the data ?    ');
 disp('     1. From a data file;         ');
 disp('     2. In interactive mode.      ');
 ans = input(' Number of Your choice : '  );
 flag = 0;
 if ans == 1
    while 1
       disp(' ');
       indat = input(' Input the name of the data file :', 's');
       if exist([cd,'\',indat]) % Search only in current directory
          eval(indat);
          flag = 1; break  % Successful
        else               % Unsuccessful
          disp(' ');
          disp([' File ',indat,' not exist!'])
          disp(' You have to:')
          disp(' 1. Enter another DATA file name, or')
          disp(' 2. Input the DATA interactively !')
          ans2 = input(' Your choice, please: ');
          if ans2 == 2, break , end
       end
    end
 end
if flag == 0
    %Input of the data in-line mode
    Ek   = input(' Expression of the kinetic energy Ek : ','s');
    N    = input(' Power of the forces and moments N : ','s'  );
    q0   = input(' Initial value of the coordinate q0 : '     );
    qt0  = input(' Initial value of the velocity qt0 : '      );
    Tend = input(' Upper bound of the integration Tend : '    );
    eps  = input(' Precision of the calculations eps : '      );
    np   = input(' Number of parameters  np : '               );
    % Asigning names of the parameters
    if np > 0
       disp(' ');
       disp(' Enter names of the parameters:')
       for i = 1:np
           ii = num2str(i);
           P{i} = input([' Name of parameter P',ii,': '],'s');
       end
    end
 end

% ---------------------------------------------------------
%             Differential Equation of Motion
% =========================================================

           syms q qt qtt Dq D2q
           dEkdt = diff(Ek,q)*qt + diff(Ek,qt)*qtt;
           deq = (dEkdt - N)/qt;
           deq = subs(deq,{qt,qtt},{Dq,D2q});
           deq = simplify(deq)

% ---------------------------------------------------------
%                  ANALYTICAL SOLUTION
% =========================================================

 disp(' ');
 ans = input(' Would you like analytical solution? (Y/N): ','s');
 if ans =='Y' | ans == 'y'
    if ~isstr(q0) , q0  = num2str(q0) ; end % Repairing user
    if ~isstr(qt0), qt0 = num2str(qt0); end % input errors!
    inicond = ['q(0)=',q0,',Dq(0)=',qt0];
    q = dsolve(char(deq), inicond, 't');
    if ~isempty(q)
        disp(' ');
        disp('   Low of Motion   ');
        disp(' ***************** ');
        disp(' ');
        disp('q = '); pretty(q)
        disp(' ');
        fname = input(' Name of file to write solution: ','s');
        save(fname, 'q');
    end
    disp(' ');
    ans = input(' Would you like numerical solution? (Y/N): ','s');
    if ans == 'N' | ans == 'n', return, end
    q = 'q'; % Clear analitical solution from q !
 end

% ---------------------------------------------------------
%                  NUMERICAL SOLUTION
% =========================================================

% Input the name of the file-function
disp(' ');
fname = input(' Name of the File-function to be generated: ','s');
flag1 = 'Y';
if exist([cd,'\',fname]) % Search only in curent directory!
    disp(' ');
    disp([' A file-function with name ',fname,' already exist !'])
    flag1 = input(' Overwrite it ? (Y/N): ', 's');
end

% ---------------------------------------------------------
%              GENERATING THE FILE-FUNCTION
% ---------------------------------------------------------

if ( flag1 == 'Y' | flag1 == 'y' )
   qtt = solve(deq,'D2q');
   qtt = subs(qtt,{q,Dq},{'y(1)','y(2)'});
% Opening the file to write file-function
   [Fid,mes] = fopen([fname,'.m'],'wt');
% Generating the string with physical parameters: m, c ...
   strpar = '';
   for j = 1:np
      strpar = [strpar,',',P{j}];
   end
   disp(' ');
   titl = input(' Denomination of the Problem: ','s');
%       Writing the headline of the File-function
   fprintf(Fid,['function yt = ',fname,'(t,y',strpar,')\n']);
   fprintf(Fid,['%% ',titl]);
%       Writing the first derivatives
   fprintf(Fid,'\n%% The first derivatives\n');
   fprintf(Fid, '  yt(1) = y(2); \n');
   fprintf(Fid,['  yt(2) = ',char(qtt),'; \n']);
   fprintf(Fid,'  yt = yt''; \n');
   fprintf(Fid,['%% *** End of File-function ',fname,' ***']);
   fclose(Fid);
   edit(fname)
end

% ---------------------------------------------------------
%        INTEGRATION AND VISUALIZATION OF THE REZULTS
% ---------------------------------------------------------

flag2 = 0;
% Initial entering values of the parameters and generating
% the string with parameters 'P{1}, P{2}, ..., P{np}' to be
% passed to the File-function as actual arguments
if np > 0
   PP = P; % Saving the physical names of the parameters in PP
   parameters = ' ';
   disp(' ');
   disp(' Input the numerical values of the parameters: ')
   for i = 1:np
       i = num2str(i);
       eval(['P{',i,'}=input([''   '',P{',i,'},'' = '']);']);
       parameters = [parameters,',P{',i,'}'];
   end
 else
   parameters = [];
end
% Check-up type of q0 and qt0 and correct
% it if needed
if ischar(q0)
    q0 = str2num(q0);
    if isempty(q0), q0 = input(' q0 = '); end
end
if ischar(qt0)
    qt0 = str2num(qt0);
    if isempty(qt0), qt0 = input(' qt0 = '); end
end
while 1
    if flag2 == 1
        disp(' ');
        eps  = input(' Precision of the computations eps: ');
        Tend = input(' Upper bound of the integration Tend: ');
        q0   = input(' Initial coordinate q0: ');
        qt0  = input(' Initial velocity qt0: ');
        if np > 0
          P = PP; % Restoring the names of the parameters !
          disp(' ');
          disp(' Input the numerical values of the parameters: ')
          for i = 1:np
              i = num2str(i);
              eval(['P{',i,'}=input([''   '',P{',i,'},'' = '']);']);
          end
        end
    end
    y0 = [q0 qt0]; % initial conditions
    options = odeset('AbsTol',eps,'RelTol',100*eps);
    % Choosing of the Solver
    disp('                                        ');
    disp('      Choose the proper Solver:         ');
    disp('  -------------------------------       ');
    disp(' A. Non stiff differential equations    ');
    disp('   1. ode45   - middle precision;       ');
    disp('   2. ode23   - low precision;          ');
    disp('   3. ode113  - from low to upper.      ');
    disp('                                        ');
    disp(' B. Stiff differential equations        ');
    disp('   1. ode15s  - from low to upper;      ');
    disp('   2. ode23s  - low precision;          ');
    disp('   3. ode23t  - middle precision;       ');
    disp('   4. ode23tb - low precision.          ');
    disp('                                        ');
    solver = input(' The name of the Solver: ','s');

    % Integration of the Differential Equations

    eval(['[t,y] = feval(solver,eval([''@'',fname]),',...
                  '[0 Tend],y0,options',parameters,');']);
    % Plotting graphs
    tmin  = min(t);
    tmax  = max(t);
    y1min = min(y(:,1));
    y1max = max(y(:,1));
    y2min = min(y(:,2));
    y2max = max(y(:,2));
    dy1   = y1max - y1min;
    dy2   = y2max - y2min;
    xmin  = y1min - 0.1*dy1;
    xmax  = y1max + 0.1*dy1;
    ymin  = y2min - 0.1*dy2;
    ymax  = y2max + 0.1*dy2;
    % Coordinate q = q(t)
    figure % 1
    comet(t,y(:,1))
    plot(t,y(:,1),[tmin tmax],[0 0],'k'), grid on
    axis([tmin, tmax, xmin, xmax]);
    set(gca,'FontName','Arial Cyr','FontSize',12);
    title('Low of motion {\itq} = {\itq}({\itt})')
    xlabel('{\itt}'); ylabel('{\itq}'); pause
    % Velocity qt = qt(t)
    figure % 2
    comet(t,y(:,2))
    plot(t,y(:,2),[tmin tmax],[0 0],'k'), grid on
    axis([tmin, tmax, ymin, ymax]);
    set(gca,'FontName','Arial','FontSize',12);
    title('Velocity {\it qt} = {\it qt}({\itt})')
    xlabel('{\itt}'); ylabel('{\it qt}'); pause
    % Coordinate and Velocity
    figure % 3
    subplot(2,1,1), plot(t,y(:,1),[tmin tmax],[0 0],'k')
    grid on, axis([tmin, tmax, xmin, xmax]);
    set(gca,'FontName','Arial','FontSize',12);
    title('Low of motion {\itq} = {\itq}({\itt})')
    subplot(2,1,2), plot(t,y(:,2),[tmin tmax],[0 0],'k')
    grid on, axis([tmin, tmax, ymin, ymax]);
    set(gca,'FontName','Arial','FontSize',12);
    title('Velocity {\it qt} = {\it qt}({\itt})')
    pause
    % Phase Plane
    figure % 4
    subplot(1,1,1)
    comet(y(:,1),y(:,2))
    plot(y(:,1),y(:,2), [xmin,xmax],[0 0],'k',...
                  [0 0],[ymin,ymax],'k'), grid on
    axis([xmin, xmax, ymin, ymax]);
    set(gca,'FontName','Arial Cyr','FontSize',12);
    title(' Phase Plane {\it qt} = {\it qt}({\itq})')
    xlabel('{\itq}'), ylabel('{\it qt}'), pause
    flag2 = 1;
    close all
    disp(' ');
    ans = input(' Would you like to continue? (Y/N): ','s');
    if ans == 'n' | ans == 'N', break, end
end

%  **************** End of Program EKIN ******************


clc;
clearvars;
close all;
M = 512;
N = 1024;
K = 5;
S = 1000;
L = 2;
Phi = spx.dict.simple.gaussian_mtx(M, N);
G = Phi' * Phi;
X = spx.data.synthetic.SparseSignalGenerator(N, K, S).biGaussian;
Y = Phi * X;
options.verbose = 1;
tstart = tic;
X1 = spx.fast.omp(Phi, Y, K, 1e-3, options);
t1 = toc(tstart);
options.verbose = 1;
options.ls_method = 'chol';
tstart = tic;
X2 =  spx.fast.gomp(Phi, Y, K, L, 1e-3, options);
t2 = toc(tstart);
cmpare = spx.commons.SparseSignalsComparison(X1, X2, K);
cmpare.summarize();

failures = sum(cmpare.support_similarity_ratios() ~= 1);
fprintf('Failed detections %d (%.2f %%)\n', failures, failures* 100 / S);
gain_x = t1/t2;
if t1 > t2
    gain_perc = (t1 - t2) * 100/ t1;
else
    gain_perc = (t1 - t2) * 100/ t2;
end
fprintf('Time: OMP, %.2f s, GOMP: %.2f s, gain: %.2f (%.1f %%)\n', t1, t2, gain_x, gain_perc);


% GLG
%
% Files
%   compute_moments1D       - Compute moments of noise free wavelet coefficients
%   compute_moments2D       - Compute moments of noiseless wavelet coefficients
%   EM_root                 - The EM algorithm for the top level of the GLG model for 1D signals
%   EM_root_exact           - The EM algorithm for the top level of the GLG model for 1D signals
%   EM_tree                 - The EM algorithm for the tree of the GLG model
%   GLG_EM_wrapper          - Fit GLG model to 1D wavelet tree with composite EM algorithms
%   GLG_kld                 - Kullback-Leibler divergence between GLG models
%   GLG_llh                 - Evaluate the (composite) likelihood of data under the estimated GLG model
%   GLG_marginal_density    - Compute the marginal density of wavelet coefs in the GLG model
%   GLG_noise_removal       - Noise removal in the GLG model
%   GLG_noise_removal_exact - Noise removal in the GLG model
%   GLG_simulation          - Simulation from a GLG model
%   hermite_quad            - Find the Gauss-Hermite abscissae and weights.
%   joint_density           - Evaluate the joint density of hidden and observed variables
%   moment_estimation       - Parameter estimates from moment equations
%   noisy_joint_density     - Evaluate the joint density of hidden and observed variables
%   noisy_moment_estimation - Parameter estimates from moment equations


function [sigma2,Sigma,didOverflow]=spherHarmonicCov(CStdDev,SStdDev,point,a,c,scalFactor)
%%SPHERHARMONICCOV Evaluate the variance of a potential or the covariance
%                  matrix of a gradient that one might compute using a
%                  spherical harmonic coefficient model with
%                  spherHarmonicEval. Here, one provides the standard
%                  deviations associated with the coefficients in the
%                  model, such as those obtained using the function
%                  getEGMGravCoeffs for the EGM2008 gravity model.
%
%INPUTS: CStdDev A length (M+2)*(M+1)/2 array holding the standard
%               deviations of the coefficient terms that are multiplied by
%               cosines in the harmonic expansion. The coefficients must be
%               fully normalized using the type of full normalization that
%               is used in the EGM2008 model. Their normalization type can
%               be changed using the changeSpherHarmonicNorm function. If
%               given to a CountingClusterSet class, C(n+1,m+1) is the
%               coefficient of degree n and order m. When a maximum degree
%               of M is used, all C must have values for all n from 0 to M
%               and for all m from 0 to n for each n. If coefficients are
%               not present for certain degrees, then insert a 0. It is
%               assumed that M>=3. For magnetic field models, the units of
%               C should generally be Tesla. For gravitational models, C is
%               generally unitless with the units being determined entirely
%               by the parameters a and c.
%       SStdDev A length (M+2)*(M+1)/2 array holding the standard
%               deviations of the coefficient terms that are multiplied by
%               sines in the harmonic expansion. The requirements on
%               SStdDev are the same as those on CStdDev.
%         point The 3XN set of N points at which the potential and/or
%               gradient should be evaluated given in SPHERICAL, ECEF
%               coordinates consisting of [r;azimuth;elevation]; When
%               evaluating points on a grid, the algorithm will be fastest
%               if the points are provided presorted by range and then by
%               azimuth. This reduces the amount of recomputation of
%               certain values. Alternatively, if C and S are for
%               evaluating terrain heights, then points are 2XN having the
%               format [azimuth;elevation] and it is best if the points are
%               sorted by azimuth.
%             a The numerator in the (a/r)^n term in the spherical harmonic
%               sum. Normally, this is some type of a reference radius. For
%               example, when using most gravitational models, a is the
%               semi-major axis of the reference ellipsoid. If this
%               parameter is omitted, it is assumed that one is using the
%               spherical harmonics with something like the National
%               Geospatial Intelligence Agency's (NGA's) EGM96 or EGM2008
%               models, in which case a=Constants.EGM2008SemiMajorAxis is
%               used unless point is 2D, in which case c=1 is used.
%             c The constant value by which the spherical harmonic series
%               is multiplied. For example, for gravitational potentials,
%               the value is usually GM where G is the universal
%               gravitational constant and M is the mass of the Earth. When
%               using the International Geomagnetic Reference Field (IGRF),
%               the constant is a^2, where a is the same as the numerator
%               in the a/r term. If this parameter is omitted, it is
%               assumed that one is using the spherical harmonics with
%               something like the NGA's EGM96 or EGM2008 models, in which
%               case c=Constants.EGM2008GM is used unless point is 2D, in
%               which case c=1 is used.
%    scalFactor An optional scale factor used in computing the normalized
%               associated Legendre polynomials if fullyNormalized=true.
%               Generally, the default value (is if the scalFactor
%               parameter is omitted) of 2^(-470) is sufficient. When very
%               high-order models are used, this scale factor prevents
%               overflows. However overflows (and a loss of precision) are
%               unavoidable when using the full EGM2008 model. These
%               effects are worse near the poles.
%
%OUTPUTS: sigma2 The NX1 vector of variances (squared standard deviations)
%                of the potential estimate at the given points.
%          Sigma The covariance matrix of the gradient of the potential at
%                the given points.
%    didOverFlow This indicates whether during the computation of sigma2 or
%                Sigma there were any overflow errors leading to term
%                being dropped. Note that this does not indicate potential
%                losses of precision due to underflow errors making terms
%                zero, which becomes more common the smaller scalFactor is.
%                Also, if scaling is extremely bad, it is possible for
%                NaNs or Inf terms to still be returned in sigma2 and
%                Sigma.
%
%The algorithm used here is described in [1].
%
%Since Matlab uses double precision arithmetic, when using high degree and
%order models, such as the full 2190 degree EGM2008 model, the precision of
%Sigma will be reduced as higher-order terms can experience overflow
%problems and are thus discarded to avoid NaNs from occurring. Lower-order
%models will not suffer from the same problem.
%
%EXAMPLE:
%Here, we evaluate the function at a point on the reference ellipsoid and
%then at a point at the pole using the full degree 2190 EGM2008 model. Note
%that the Matlab implementation will bee too slow for this high a degree
%and the C++ implementation should be compiled.
% latLongAlt=[-30*(pi/180);45*(pi/180);0];
% spherLoc=Cart2Sphere(ellips2Cart(latLongAlt));
%
% [C,S,a,c,CStdDev,SStdDev]=getEGMGravCoeffs(2190,false);
% [sigma21,Sigma1,didOverflow1]=spherHarmonicCov(CStdDev,SStdDev,spherLoc,a,c)
% spherLoc(end)=pi/2;%90 degree elevation --the pole.
% [sigma22,Sigma2,didOverflow2]=spherHarmonicCov(CStdDev,SStdDev,spherLoc,a,c)
%One will see that in both instances, finite values are returned, but for
%the point at the pole, overflows are flagged indicating the loss of
%prevision due to some terms being dropped due to overflows. A model with
%fewer spherical harmonic coefficients would not be as susceptible to such
%overflow problems.
%
%REFERENCES:
%[1] D. F. Crouse, "An Overview of Major Terrestrial, Celestial, and
%    Temporal Coordinate Systems for Target Tracking," Formal Report, Naval
%    Research Laboratory, no. NRL/FR/5344--16-10,279, 10 Aug. 2016, 173
%    pages.
%
%April 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<6||isempty(scalFactor))
    scalFactor=2^(-470);
end

if(nargin<5||isempty(c))
    if(size(point,1)==2)
        c=1;
    else
        c=Constants.EGM2008GM;
    end
end

if(nargin<4||isempty(a))
    if(size(point,1)==2)
        a=1;
    else
        a=Constants.EGM2008SemiMajorAxis;
    end
end

M=(1/2)*(sqrt(1+8*length(CStdDev))-1)-1;

if(M<3)
    error('The coefficients must be provided to at least degree 3. To use a lower degree, one can insert zero coefficients.');
end

numPoints=size(point,2);
%If we are evaluating terrain heights.
switch(size(point,1))
    case 2
        point=[ones(1,numPoints);point(1,:);point(2,:)];
    case 3
    otherwise
        error('Invalid point length');
end

CStdDev=CountingClusterSet(CStdDev);
SStdDev=CountingClusterSet(SStdDev);

sigma2=zeros(numPoints,1);
Sigma=zeros(3,3,numPoints);

didOverflow=false;
rPrev=Inf;
thetaPrev=Inf;
for curPoint=1:numPoints
    r=point(1,curPoint);
    thetaCur=point(3,curPoint);

    rChanged=r~=rPrev;
    rPrev=r;

    if(rChanged)
        nCoeff=zeros(M+1,1);
        nCoeff(1)=1;
        for n=1:M
            nCoeff(n+1)=nCoeff(n)*(a/r);
        end
    end

    %The non-singular algorithm of Pines using the fully normalized
    %Helmholtz equations from Fantino and Casotto is used. The algorithm
    %has been slightly modified so that the c/r term is out front and the
    %fully normalized Helmholtz polynomials can be scaled. Also, lumped
    %coefficients are not used. The Pines algorithm can suffer a loss of
    %precision near the equator. However, it is simple to just square the
    %terms in the sum.
    CartPoint=spher2Cart(point(:,curPoint));

    x=CartPoint(1);
    y=CartPoint(2);
    z=CartPoint(3);

    %Get the direction cosines used by Pines' algorithm.
    s=x/r;
    t=y/r;
    u=z/r;

    %Compute the fully normalized Helmholtz polynomials.
    if(thetaPrev~=thetaCur)
        [HBar,dHBardu]=normHelmholtz(u,M,scalFactor);
        thetaPrev=thetaCur;
    end

    %Recursively compute the rm and im terms for the sums.
    rm=zeros(M+1,1);
    im=zeros(M+1,1);
    rm(0+1)=1;
    im(0+1)=0;
    for m=1:M
        %These are equation 49 in the Fantino and Casotto paper.
        rm(m+1)=s*rm(m-1+1)-t*im(m-1+1);
        im(m+1)=s*im(m-1+1)+t*rm(m-1+1);
    end

    %Perform the sum for the potential from Equation 44 in the Fantino and
    %Casotto paper, but square all of the terms to represent a sigma.
    %All cross terms are expected to be zero, so the sum is very similar to
    %the sum for the potential in spherHarmonicEval.
    sigma2(curPoint)=0;
    for n=0:M
        innerTerm=0;
        for m=0:n
            innerTerm=innerTerm+(CStdDev(n+1,m+1)*rm(m+1)*HBar(n+1,m+1))^2+(SStdDev(n+1,m+1)*im(m+1)*HBar(n+1,m+1))^2;
        end
        if(isfinite(innerTerm))
            sigma2(curPoint)=sigma2(curPoint)+nCoeff(n+1)^2*innerTerm;
        else
            didOverflow=true;
        end
    end

    sigma2(curPoint)=(c/r)^2*sigma2(curPoint)/scalFactor^2;

    %Now, compute the cosigma matrix of the gradient, if requested.
    if(nargout>1)
        a11=0;
        a22=0;
        a33=0;
        a44=0;
        a12=0;
        a13=0;
        a14=0;
        a23=0;
        a24=0;
        a34=0;

        %The equations in these loops are from Table 10.
        for n=0:M
            a11Loop=0;
            a22Loop=0;
            a12Loop=0;
            a13Loop=0;
            a14Loop=0;
            a23Loop=0;
            a24Loop=0;

            %The m=0 case only applies to a3 and a4, so that means only to
            %a33, a34, and a44.
            m=0;
            HVal=HBar(n+1,m+1);
            dHVal=dHBardu(n+1,m+1);
            CProdMN=CStdDev(n+1,m+1)^2*rm(m+1)^2+SStdDev(n+1,m+1)^2*im(m+1)^2;
            Lmn=(n+m+1)*HVal+u*dHVal;%Defined in Table 14.

            a33Loop=CProdMN*dHVal^2;
            a44Loop=CProdMN*Lmn^2;
            a34Loop=-CProdMN*Lmn*dHVal;

            for m=1:n
                HVal=HBar(n+1,m+1);
                dHVal=dHBardu(n+1,m+1);

                CProdMN=CStdDev(n+1,m+1)^2*rm(m+1)^2+SStdDev(n+1,m+1)^2*im(m+1)^2;
                Lmn=(n+m+1)*HVal+u*dHVal;

                %These if-statements are to deal with numerical precision
                %problems near the poles. We want to avoid 0*Inf terms due
                %to limitations in the valid range of double precision
                %numbers. Of course, the loss of the terms where overflow
                %occurs means that the covariance matrix will be
                %underestimated.
                if(isfinite(HVal))
                    a11Loop=a11Loop+m^2*(CStdDev(n+1,m+1)^2*rm(m-1+1)^2+SStdDev(n+1,m+1)^2*im(m-1+1)^2)*HVal^2;
                    a12Loop=a12Loop+m^2*rm(m-1+1)*im(m-1+1)*(SStdDev(n+1,m+1)^2-CStdDev(n+1,m+1)^2)*HVal^2;
                    a22Loop=a22Loop+m^2*(SStdDev(n+1,m+1)^2*rm(m-1+1)^2+CStdDev(n+1,m+1)^2*im(m-1+1)^2)*HVal^2;
                else
                    didOverflow=true;
                end

                if(isfinite(Lmn))
                    a44Loop=a44Loop+CProdMN*Lmn^2;
                    if(isfinite(HVal))
                        a14Loop=a14Loop-m*(CStdDev(n+1,m+1)^2*rm(m-1+1)*rm(m+1)+SStdDev(n+1,m+1)^2*im(m-1+1)*im(m+1))*HVal*Lmn;
                        a24Loop=a24Loop-m*(-CStdDev(n+1,m+1)^2*im(m-1+1)*rm(m+1)+SStdDev(n+1,m+1)^2*rm(m-1+1)*im(m+1))*HVal*Lmn;
                    end
                    if(isfinite(dHVal))
                        a34Loop=a34Loop-CProdMN*Lmn*dHVal;
                    end
                else
                    didOverflow=true;
                end

                if(isfinite(dHVal))
                    a33Loop=a33Loop+CProdMN*dHVal^2;
                    if(isfinite(HVal))
                        a13Loop=a13Loop+m*(CStdDev(n+1,m+1)^2*rm(m-1+1)*rm(m+1)+SStdDev(n+1,m+1)^2*im(m-1+1)*im(m+1))*HVal*dHVal;
                        a23Loop=a23Loop+m*(-CStdDev(n+1,m+1)^2*im(m-1+1)*rm(m+1)+SStdDev(n+1,m+1)^2*rm(m-1+1)*im(m+1))*HVal*dHVal;
                    end
                else
                    didOverflow=true;
                end
            end

            a11=a11+nCoeff(n+1)^2*a11Loop;
            a22=a22+nCoeff(n+1)^2*a22Loop;
            a33=a33+nCoeff(n+1)^2*a33Loop;
            a44=a44+nCoeff(n+1)^2*a44Loop;
            a12=a12+nCoeff(n+1)^2*a12Loop;
            a13=a13+nCoeff(n+1)^2*a13Loop;
            a14=a14+nCoeff(n+1)^2*a14Loop;
            a23=a23+nCoeff(n+1)^2*a23Loop;
            a24=a24+nCoeff(n+1)^2*a24Loop;
            a34=a34+nCoeff(n+1)^2*a34Loop;
        end

%These are based on squaring the terms in equation 70, removing cross
%terms. However, an additional 1/r (squared) term has been added,
%which the original paper omitted when going from Equation 68 to 70.

        s11=a11+2*s*a14+s^2*a44;
        s12=a12+s*a24+t*a14+s*t*a44;
        s13=a13+s*a34+u*a14+s*u*a44;
        s22=a22+2*t*a24+t^2*a44;
        s23=a23+t*a34+u*a24+t*u*a44;
        s33=a33+2*u*a34+u^2*a44;

        temp=c/(r^2*scalFactor);

        Sigma(:,:,curPoint)=temp*(temp*[s11,s12,s13;
                                        s12,s22,s23;
                                        s13,s23,s33]);
    end

end
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


f = [110*1.3 30*2.0 125*1.56 75*1.8 95*.95 100*2.25 50*1.35];
A = [120 210 150.75 115 186 140 85;
     110 30 125 75 95 100 50;
     1 1 1 1 1 1 1;
     1 -1 0 0 0 0 0;
     0 0 1 0 -2 0 0;
     0 0 0 -1 0 -1 1];
b = [55000;40000;400;0;0;0];
lp = lp_maker(f, A, b, [-1; -1; -1; -1; -1; -1], [10 10 10 10 20 20 20], [100 Inf 50 Inf Inf 250 Inf], [], 1, 0);
solvestat = mxlpsolve('solve', lp)
format bank
obj = mxlpsolve('get_objective', lp)
format short
x = mxlpsolve('get_variables', lp)
mxlpsolve('delete_lp', lp);


function out=janaf(prop, spec,T);
% ---------------------------------------------------------------------
% function out=janaf(prop, spec, T)                 |   Version 1.01
% ---------------------------------------------------------------------
% Calculates JANAF curve fit according to JANAF virial equation
% Output is calculated in SI-units
%
% prop = 'c' for standard state specific heat
%      = 'h' for standard state enthalpy
%      = 's' for standard state entropy
% spec = 'CO2', 'H2O', 'CO', 'H2', 'O2', 'N2'
% T    = Temperature, vector allowed
%
% JANAF.mat required (contains the coefficients)
% ---------------------------------------------------------------------
% Last Change: 2003-07-18           |   (c)2003, Stefan Billig, Delphi

% check for correct syntax
if nargin~=3
    help janaf
    % end function
    return
end

% load coefficient table
load JANAF;
z=1;
% determine molecular weight from table
MWeight=eval(['MolWeight.' spec]);

for i=1:length(T)
    % choose temperature range vector
    if (T(i)>1000 & T(i)<=5000)
        eval(['ai=' spec '(1,:);'])
        out(z)=calc(ai, T(i), prop, MWeight);
        z=z+1;
    elseif (T(i)>=300 & T(i)<=1000)
        eval(['ai=' spec '(2,:);'])
        out(z)=calc(ai, T(i), prop, MWeight);
        z=z+1;
    else
        sprintf(['Temperature ' num2str(T(i)) 'K not between 300K and 5000K!'])
    end
end

%----------------------------------------------------------------------
function out=calc(ai, T, prop, MWeight)

R=8.314;
% calculate standard state value
switch prop
    case 'c'
        out=(ai(1)+ai(2)*T+ai(3)*T.^2+ai(4)*T.^3+ai(5)*T.^4)*R/MWeight;
    case 'h'
        out=(ai(1)+ai(2)/2*T+ai(3)/3*T.^2+ai(4)/4*T.^3+ai(5)/5*T.^4+ai(6)/T).*T*R/MWeight;
    case 's'
        out=(ai(1)*ln(T)+ai(2)*T+ai(3)/2*T.^2+ai(4)/3*T.^3+ai(5)/4*T.^4+ai(7))*R/MWeight;
end


function jed = ymdf_to_jed_gregorian ( y, m, d, f )

%*****************************************************************************80
%
%% YMDF_TO_JED_GREGORIAN converts a Gregorian YMDF date to a JED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Richards,
%    Algorithm E,
%    Mapping Time, The Calendar and Its History,
%    Oxford, 1999, pages 323-324.
%
%  Parameters:
%
%    Input, integer Y, integer M, integer D, real F, the YMDF date.
%
%    Output, real JED, the corresponding JED.
%

%
%  Check the date.
%
  [ y, m, d, ierror ] = ymd_check_gregorian ( y, m, d );

  if ( ierror ~= 0 )
    jed = -1.0;
    return
  end
%
%  Account for the missing year 0 by moving negative years up one.
%
  y2 = y_common_to_astronomical ( y );
%
%  Convert the calendar date to a computational date.
%
%  This frap-dapping formula fails for 1 March 1900!
%
  if ( m == 3 && d == 1 && ~year_is_leap_gregorian ( y2 ) )
    m = m - 1;
    d = 29;
  end

  y_prime = y2 + 4716 - floor ( ( 14 - m ) / 12 );
  m_prime = mod ( m + 9, 12 );
  d_prime = d - 1;
%
%  Convert the computational date to a JED.
%
  j1 = floor ( ( 1461 * y_prime ) / 4 );

  j2 = floor ( ( 153 * m_prime + 2 ) / 5 );

  g = floor ( 3 * floor ( ( y_prime + 184 ) / 100 ) / 4 ) - 38;

  jed = j1 + j2 + d_prime - 1401 - g - 0.5;
  jed = jed + f;

  return
end


function [v, signs] = lnDiffErfs(x1, x2),

% LNDIFFERFS Helper function for computing the log of difference
%   of two erfs.
% FORMAT
% DESC computes the log of the difference of two erfs in a numerically stable manner.
% ARG x1 : argument of the positive erf
% ARG x2 : argument of the negative erf
% RETURN v : log(abs(erf(x1) - erf(x2)))
% RETURN s : sign(erf(x1) - erf(x2))
%
% FORMAT
% DESC computes the log of the difference of two erfs in a numerically stable manner.
% ARG x1 : argument of the positive erf
% ARG x2 : argument of the negative erf
% RETURN v : log(erf(x1) - erf(x2))     (Can be complex)
%
% COPYRIGHT : Antti Honkela, 2007, 2008
%
% MODIFICATIONS : David Luengo, 2009
%
% SEEALSO : gradLnDiffErfs

% NDLUTIL

x1 = real(x1);
x2 = real(x2);

v = zeros(max(size(x1), size(x2)));

if numel(x1) == 1,
  x1 = x1 * ones(size(x2));
end

if numel(x2) == 1,
  x2 = x2 * ones(size(x1));
end

signs = sign(x1 - x2);
I = signs == -1;
swap = x1(I);
x1(I) = x2(I);
x2(I) = swap;

% Case 1: arguments of different signs, no problems with loss of accuracy
I1 = (x1.*x2)<0;
% Case 2: x1 = x2
I2 = x1 == x2;
% Case 3: Both arguments are non-negative
I3 = (x1 > 0) & ~I1 & ~I2;
% Case 4: Both arguments are non-positive
I4 = ~I1 & ~I2 & ~I3;

warnState = warning('query', 'MATLAB:log:logOfZero');
warning('off', 'MATLAB:log:logOfZero');
v(I1) = log( erf(x1(I1)) - erf(x2(I1)) );
v(I2) = -inf;
v(I3) = log(erfcx(  x2(I3)) ...
	    - erfcx(x1(I3)) .* exp(x2(I3).^2 - x1(I3).^2)) ...
	- x2(I3).^2;
v(I4) = log(erfcx(  -x1(I4)) ...
	    - erfcx(-x2(I4)) .* exp(x1(I4).^2 - x2(I4).^2)) ...
	- x1(I4).^2;
warning(warnState.state, 'MATLAB:log:logOfZero');

if nargout < 2,
  v(I) = v(I) + pi*1i;
end


function W = randInitializeWeights(L_in, L_out)
%RANDINITIALIZEWEIGHTS Randomly initialize the weights of a layer with L_in
%incoming connections and L_out outgoing connections
%   W = RANDINITIALIZEWEIGHTS(L_in, L_out) randomly initializes the weights
%   of a layer with L_in incoming connections and L_out outgoing
%   connections.
%
%   Note that W should be set to a matrix of size(L_out, 1 + L_in) as
%   the column row of W handles the "bias" terms
%

% You need to return the following variables correctly
W = zeros(L_out, 1 + L_in);

% ====================== YOUR CODE HERE ======================
% Instructions: Initialize W randomly so that we break the symmetry while
%               training the neural network.
%
% Note: The first row of W corresponds to the parameters for the bias units
%

% =========================================================================

end


function [x_pca, m] = PCAMyself(x)
% Feature extraction by PCA

%------------------------------- 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".
%--------------------------------------------------------------------------

    [COEFF, SCORE, latent]=pca(x);
    answer=0;s1=0;s2=sum(latent);count=1;
    while answer < 0.95
        s1=s1+latent(count);
        answer=s1/s2;
        count=count+1;
    end
    m=COEFF(:,1:count-1);
    x_pca=x*m;
end


function r = uniform_dataset ( m, n, seed )

%*****************************************************************************80
%
%% UNIFORM_DATASET generates a uniform dataset and writes it to a file.
%
%  Discussion:
%
%    UNIFORM_DATASET generates a uniform random data and writes it to a file.
%
%  Usage:
%
%    r = uniform_dataset ( m, n, seed )
%
%    where
%
%    * M, the spatial dimension,
%    * N, the number of points to generate,
%    * SEED, the seed, a positive integer.
%    * R is the M by N array created.
%
%    creates an M by N uniform random dataset and writes it to the
%    file "uniform_M_N.txt".
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 December 2009
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'UNIFORM_DATASET\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Generate a uniform pseudorandom dataset.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The program requests input values from the user:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  * M, the spatial dimension,\n' );
  fprintf ( 1, '  * N, the number of points to generate,\n' );
  fprintf ( 1, '  * SEED, a seed for the random number generator.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The program generates the data and writes it to the file\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    uniform_M_N.txt\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  where "M" and "N" are the numeric values.\n' );
%
%  Get the spatial dimension.
%
  if ( nargin < 1 )
    fprintf ( 1, '\n' );
    m = input ( '  Enter the spatial dimension M: ' );
  else
    m = str2num ( m );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Spatial dimension M = %d\n', m );
%
%  Get the number of points.
%
  if ( nargin < 2 )
    fprintf ( 1, '\n' );
    n = input ( '  Enter the number of points N: ' );
  else
    n = str2num ( n );
  end

  fprintf ( 1, '  Number of points N = %d\n', n );
%
%  Get the seed.
%
  if ( nargin < 3 )
    fprintf ( 1, '\n' );
    seed = input ( '  Enter the seed: ' );
  else
    seed = str2num ( seed );
  end

  fprintf ( 1, '  The seed = %d\n', seed );
%
%  Compute the data.
%
  [ r, seed ] = r8mat_uniform_01 ( m, n, seed );
%
%  Write it to a file.
%
  output_filename = ...
    strcat ( 'uniform_', num2str ( m ), '_', num2str ( n ), '.txt' );

  r8mat_write ( output_filename, m, n, r );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  The data was written to the file "%s".\n', ...
    output_filename );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'UNIFORM_DATASET:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

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

  return
end
function r8mat_write ( output_filename, m, n, table )

%*****************************************************************************80
%
%% R8MAT_WRITE writes an R8MAT file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 August 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the output filename.
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points.
%
%    Input, real TABLE(M,N), the points.
%

%
%  Open the file.
%
  output_unit = fopen ( output_filename, 'wt' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_WRITE - Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'R8MAT_WRITE - Error!' );
    return;
  end
%
%  Write the data.
%
%  For smaller data files, and less precision, try:
%
%     fprintf ( output_unit, '  %14.6f', table(i,j) );
%
  for j = 1 : n
    for i = 1 : m
      fprintf ( output_unit, '  %24.16f', table(i,j) );
    end
    fprintf ( output_unit, '\n' );
  end
%
%  Close the file.
%
  fclose ( output_unit );

  return
end
function [ r, seed ] = r8mat_uniform_01 ( m, n, seed )

%*****************************************************************************80
%
%% R8MAT_UNIFORM_01 returns a unit pseudorandom R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 September 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Linus Schrage,
%    A Guide to Simulation,
%    Second Edition,
%    Springer, 1987,
%    ISBN: 0387964673,
%    LC: QA76.9.C65.B73.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, December 1986, pages 362-376.
%
%    Pierre L'Ecuyer,
%    Random Number Generation,
%    in Handbook of Simulation,
%    edited by Jerry Banks,
%    Wiley, 1998,
%    ISBN: 0471134031,
%    LC: T57.62.H37.
%
%    Peter Lewis, Allen Goodman, James Miller,
%    A Pseudo-Random Number Generator for the System/360,
%    IBM Systems Journal,
%    Volume 8, Number 2, 1969, pages 136-143.
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns in the array.
%
%    Input, integer SEED, the integer "seed" used to generate
%    the output random number.
%
%    Output, real R(M,N), an array of random values between 0 and 1.
%
%    Output, integer SEED, the updated seed.  This would
%    normally be used as the input seed on the next call.
%
  i4_huge = 2147483647;

  if ( seed == 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8MAT_UNIFORM_01 - Fatal error!\n' );
    fprintf ( 1, '  Input SEED = 0!\n' );
    error ( 'R8MAT_UNIFORM_01 - Fatal error!' );
  end

  for j = 1 : n
    for i = 1 : m

      seed = floor ( seed );

      seed = mod ( seed, i4_huge );

      if ( seed < 0 )
        seed = seed + i4_huge;
      end

      k = floor ( seed / 127773 );

      seed = 16807 * ( seed - k * 127773 ) - k * 2836;

      if ( seed < 0 )
        seed = seed + i4_huge;
      end

      r(i,j) = seed * 4.656612875E-10;

    end
  end

  return
end
function timestamp ( )

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

  return
end


function pass = test_constructor2( pref )
% Test the Chebfun2v constructor when performing simple arithmetic
% operations.

if ( nargin < 1 )
    pref = chebfunpref;
end

tol = 100*pref.cheb2Prefs.chebfun2eps;

% check the vectorize flag:
f1 = @(x,y) x.*y;
f2 = @(x,y) x*y;
H1 = chebfun2v(f1, f1);
H2 = chebfun2v(f2, f2, 'vectorize');
pass(1) = norm( H1 - H2 ) < tol;

f1 = @(x,y) x.*y;
f2 = @(x,y) x*y;
H1 = chebfun2v(f1, f1, [-2 3 -1 0]);
H2 = chebfun2v(f2, f2, 'vectorize', [-2 3 -1 0]);
pass(2) = norm( H1 - H2 ) < tol;

f1 = @(x,y) x.*y;
f2 = @(x,y) x*y;
H1 = chebfun2v(f1, f1, f1);
H2 = chebfun2v(f2, f2, f2, 'vectorize');
pass(3) = norm( H1 - H2 ) < tol;

f1 = @(x,y) x.*y;
f2 = @(x,y) x*y;
H1 = chebfun2v(f1, f1, f1, [-2 3 -1 0]);
H2 = chebfun2v(f2, f2, f2, 'vectorize', [-2 3 -1 0]);
pass(4) = norm( H1 - H2 ) < tol;

% Test the constructor with a surface example:
u = chebfun2(@(u,v) u, [0 2*pi -1 1]);
v = chebfun2(@(u,v) v, [0 2*pi -1 1]);
x = (1+0.5*v.*cos(u/2)).*cos(u);
y = (1+0.5*v.*cos(u/2)).*sin(u);
z = 0.5*v.*sin(u/2);
r = [x;y;z];
ru = diff(r,1,1);
rv = diff(r,1,2);
pass(5) = ( norm(ru'*rv,inf) < 10*tol );

V = [sin(5*u);cos(5*v);0];
pass(6) = (V.nComponents == 3);

end


function nv=nodesurfnorm(node,elem)
%  nv=nodesurfnorm(node,elem)
%
%  calculate a nodal norm for each vertix on a surface mesh (surface
%   can only be triangular or cubic)
%
%  author: Qianqian Fang <q.fang at neu.edu>
%  date: 12/12/2008
%
% parameters:
%      node: node coordinate of the surface mesh (nn x 3)
%      elem: element list of the surface mesh (3 columns for
%            triangular mesh, 4 columns for cubic surface mesh)
%      pt: points to be projected, 3 columns for x,y and z respectively
%
% outputs:
%      nv: nodal norms (vector) calculated from nodesurfnorm.m
%          with dimensions of (size(v,1),3)
%
% Please find more information at http://iso2mesh.sf.net/cgi-bin/index.cgi?metch
%
% this function is part of "metch" toobox, see COPYING for license

nn=size(node,1);
ne=size(elem,1);
nedim=size(elem,2);

ev=surfacenorm(node,elem);

nv=zeros(nn,3);
ev2=repmat(ev,1,3);
for i=1:ne
  nv(elem(i,:),:)=nv(elem(i,:),:)+reshape(ev2(i,:),3,3)';
end
nvnorm=sqrt(sum(nv.*nv,2));
idx=find(nvnorm>0);
if(length(idx)<nn)
	warning(['found interior nodes, their norms will be set to zeros; to remove ',...
                'them, please use removeisolatednodes.m from iso2mesh toolbox']);

	nv(idx,:)=nv(idx,:)./repmat(nvnorm(idx),1,3);
else
	nv=nv./repmat(nvnorm,1,3);
end


function [irm,ibm] = idealMasks(st,si,q,a)
%IDEALMASKS Calculate ideal time-frequency masks from STFTs
%
%   IRM = IOSR.BSS.IDEALMASKS(ST,SI) calculates the ideal ratio mask (IRM)
%   using target STFT ST and interferer STFT SI. ST and SI must be the same
%   size; IRM is the same size as ST and SI.
%
%   [IRM,IBM] = IOSR.BSS.IDEALMASKS(...) returns the ideal binary mask
%   (IBM).
%
%   IRM = IOSR.BSS.IDEALMASKS(ST,SI,Q) uses the exponent Q to create an
%   ideal sigmoidal mask by raising each of the time-frequency powers to Q.
%   With Q=1 (default) the mask is the IRM. As Q->Inf the IRM will tend
%   towards a binary mask. As Q->0 the mask will tend towards 0.5.
%
%   [IRM,IBM] = IOSR.BSS.IDEALMASKS(ST,SI,Q,A) uses the threshold A to
%   calculate the IBM. The threshold is in terms of the ratio of time
%   frequency powers. With A=1 (default), the IBM is 1 when the target
%   power is greater than the interferer power. Setting A=2, for example,
%   requires the target power to be 6dB greater than the interference
%   power.
%
%   See also IOSR.BSS.APPLYMASK, IOSR.BSS.APPLYIDEALMASKS.

%   Copyright 2016 University of Surrey.

    %% check input

    assert(isequal(size(st),size(si)), 'iosr:idealMasks:invalidInputs', 'ST and SI must be the same size')

    % check sigmoid
    if nargin<3
        q = 1;
    else
        assert(isscalar(a), 'iosr:idealMasks:invalidQ', 'Q must be an scalar')
    end

    % check threshold
    if nargin<4
        a = 1;
    else
        assert(isscalar(a), 'iosr:idealMasks:invalidA', 'A must be an scalar')
    end

    %% calculate masks

    % powers
    St = abs(st).^2;
    Si = abs(si).^2;

    % ideal ratio mask
    irm = (St.^q)./((St.^q)+(Si.^q));
    irm(isnan(irm)) = 0;

    % ideal binary mask
    if nargout>1
        ibm = +(St./Si>a);
        ibm(isnan(ibm)) = 0;
    end

end


clear, clc;

% This is an example for running the function tree_LeastR
%
%  Problem:
%
%  min  1/2 || A x - y||^2 + z * sum_j w_j ||x_{G_j}||
%
%  G_j's are nodes with tree structure
%
%  The tree structured group information is contained in
%  opts.ind, which is a 3 x nodes matrix, where nodes denotes the number of
%  nodes of the tree.
%
%  opts.ind(1,:) contains the starting index
%  opts.ind(2,:) contains the ending index
%  opts.ind(3,:) contains the corresponding weight (w_j)
%
%  Note:
%  1) If each element of x is a leaf node of the tree and the weight for
%  this leaf node are the same, we provide an alternative "efficient" input
%  for this kind of node, by creating a "super node" with
%  opts.ind(1,1)=-1; opts.ind(2,1)=-1; and opts.ind(3,1)=the common weight.
%
%  2) If the features are well ordered in that, the features of the left
%  tree is always less than those of the right tree, opts.ind(1,:) and
%  opts.ind(2,:) contain the "real" starting and ending indices. That is to
%  say, x( opts.ind(1,j):opts.ind(2,j) ) denotes x_{G_j}. In this case,
%  the entries in opts.ind(1:2,:) are within 1 and n.
%
%
%  If the features are not well ordered, please use the input opts.G for
%  specifying the index so that
%   x( opts.G ( opts.ind(1,j):opts.ind(2,j) ) ) denotes x_{G_j}.
%  In this case, the entries of opts.G are within 1 and n, and the entries of
%  opts.ind(1:2,:) are within 1 and length(opts.G).
%
%% Related papers
%
% [1] Jun Liu and Jieping Ye, Moreau-Yosida Regularization for
%     Grouped Tree Structure Learning, NIPS 2010
%
%%

cd ..
cd ..

root=cd;
addpath(genpath([root '/SLEP']));
                     % add the functions in the folder SLEP to the path

% change to the original folder
cd Examples/tree;

m=50;  n=100;       % The data matrix is of size m x n

%randNum=10;           % a random number

% ---------------------- generate random data ----------------------
%randn('state',(randNum-1)*3+1);
A=randn(m,n);        % the data matrix

%randn('state',(randNum-1)*3+2);
xOrin=full(sprandn(n, 1,1));
xOrin(1:50,:)=0;

%randn('state',(randNum-1)*3+3);
noise=randn(m,1);
y=A*xOrin +...
    noise*0.01;      % the response

%% In this example, the tree is set as:
%
% root, 1:100, with weight 0
% its children nodes, 1:50, and 51:100
%
% For 1:50, its children are 1:20, 21:40, and 41:50
%
% For 51:100, its children are 51:70, and 71:100
%
% These nodes in addition have each individual features (they contain) as
% children nodes.
%
%%

%% One efficient way
% We make use of the fact that the indices of the left nodes of the tree
% are smaller than the right nodes.

%----------------------- Set optional items -----------------------
opts=[];

% Starting point
opts.init=2;        % starting from a zero point

% Termination
opts.tFlag=5;       % run .maxIter iterations
opts.maxIter=100;   % maximum number of iterations

% regularization
opts.rFlag=1;       % use ratio

% Normalization
opts.nFlag=0;       % without normalization

% Group Property
opts.ind=[[-1, -1, 1]',... % leave nodes (each node contains one feature)
    [1, 20, sqrt(20)]', [21, 40, sqrt(20)]',... % the layer above the leaf
    [41, 50, sqrt(10)]', [51, 70, sqrt(20)]', [71,100, sqrt(30)]',...
    [1, 50, sqrt(50)]', [51, 100, sqrt(50)]']; % the higher layer

%----------------------- Run the code tree_LeastR -----------------------
z=0.1;
tic;
[x1, funVal1, ValueL1]= tree_LeastR(A, y, z, opts);
toc;

%% An alternative way
% We make use of the fact that the indices of the left nodes of the tree
% are smaller than the right nodes.
%%

%----------------------- Set optional items -----------------------
opts=[];

% Starting point
opts.init=2;        % starting from a zero point

% Termination
opts.tFlag=5;       % run .maxIter iterations
opts.maxIter=100;   % maximum number of iterations

% regularization
opts.rFlag=1;       % use ratio

% Normalization
opts.nFlag=0;       % without normalization

% Group Property
opts.ind=[[-1, -1, 1]',... % leave nodes (each node contains one feature)
    [1, 20, sqrt(20)]', [21, 40, sqrt(20)]',... % the layer above the leaf
    [41, 50, sqrt(10)]', [51, 70, sqrt(20)]', [71,100, sqrt(30)]',...
    [101, 150, sqrt(50)]', [151, 200, sqrt(50)]']; % the higher layer
opts.G=[1:100, 1:100];

%----------------------- Run the code tree_LeastR -----------------------
z=0.1;
tic;
[x2, funVal2, ValueL2]= tree_LeastR(A, y, z, opts);
toc;


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function price = FFTCOS_UpAndOut(n, Nex,H,Rb, L, c, cp, type, S0, t, r, q, ...
                                    strike, varargin)

% Function FFTCOS_UpAndOut calculates the price of a discretely
% monitored Up-and-Out Call or Put option by use of the Fourier-Cosine
% Series Expansion introduced by Oosterlee & Fang
%------------------------------------------------------------------------

% Nex := number of examination points
% H := Barrier
% Rb := Rebate

dt = t / Nex;                    % time interval
Ngrid = 2 ^ n;                   % Grid points
Nstrike = size(strike,1);        % number of strikes

x = double(log(S0 ./ strike));       % center
h = double(log(H ./ strike));

a = double(c(1) + x - L * sqrt(c(2) + sqrt(c(3))));   % lower trunc
b = double(c(1) + x + L * sqrt(c(2) + sqrt(c(3))));   % upper trunc

Grid_i = repmat((0:Ngrid-1)',1,Nstrike);    % Grid index

% Set up function handles
if cp == 1
    vk = @(x) calcv(Grid_i, x, h, a, b, cp, strike);
    if h >= 0
        V = vk(0);
    end
else
    vk = @(x) calcv(Grid_i, a, x, a, b, cp, strike);
    if h >= 0
        V = vk(0);
    else
        V = vk(h);
    end
end

cv = @(y) cvalue(a, h, a, b, Ngrid, y, type, dt, r, q, varargin{:});

aux = pi * Grid_i * diag(1./(b-a));
G = ((sin(aux * diag(b-a))-sin(aux*diag(h-a)))./aux);
G = exp(-r * dt) * 2 * Rb * [((b-h)./(b-a))';G(2:end,:)]* diag(1./(b-a));

V = V + G;
for m = Nex-1:-1:1              % backward induction
    V = cv(V) + G;
end

cfval = exp(feval(@CF, type,aux, dt,r,q,varargin{:}));

pF = cfval .* exp( 1i * aux * diag(x - a) );
pF(1,:) = 0.5*pF(1,:);
price = exp(-r * dt) * sum(real(pF) .* V) ;  % Option value at t_0

end


% New SVD based initialization strategy for Non-negative Matrix Factorization
% Hanli Qiao

function [W, H] = Qiao_SVD_Init(Z, rank)
    [u, s, v, p] = ChoosingR(Z);
    W = abs(u(:,1:rank));
    H = abs(s(1:rank,:)*v');
end

function [u, s, v, p] = ChoosingR(Z)
    [u,s,v] = svd(Z);
    sum1= sum(s);
    sum2=sum(sum1);
    extract=0;
    p = 0;
    dsum=0;
    while(extract/sum2<0.90)
        p = p + 1;
        dsum=dsum+s(p,p);
        extract=dsum;
    end
end


function [ key, seed, matrix, ierror ] = rcont2 ( nrow, ncol, nrowt, ncolt, ...
  key, seed )

%*****************************************************************************80
%
%% RCONT2 constructs a random two-way contingency table with given sums.
%
%  Discussion:
%
%    It is possible to specify row and column sum vectors which
%    correspond to no table at all.  As far as I can see, this routine does
%    not detect such a case.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 March 2009
%
%  Author:
%
%    Original FORTRAN77 version by WM Patefield.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    WM Patefield,
%    Algorithm AS 159:
%    An Efficient Method of Generating RXC Tables with
%    Given Row and Column Totals,
%    Applied Statistics,
%    Volume 30, Number 1, 1981, pages 91-97.
%
%  Parameters:
%
%    Input, integer NROW, NCOL, the number of rows and columns
%    in the table.  NROW and NCOL must each be at least 2.
%
%    Input, integer NROWT(NROW), NCOLT(NCOL), the row and column
%    sums.  Each entry must be positive.
%
%    Input, logical KEY, a flag that indicates whether data has
%    been initialized for this problem.  Set KEY = .FALSE. before the first
%    call.
%
%    Input, integer SEED, a seed for the random number
%    generator.
%
%    Output, logical KEY, a flag that indicates whether data has
%    been initialized for this problem.  Set KEY = .FALSE. before the first
%    call.
%
%    Output, integer SEED, a seed for the random number
%    generator.
%
%    Output, integer MATRIX(NROW,NCOL), the matrix.
%
%    Output, integer IERROR, an error flag, which is returned
%    as 0 if no error occurred.
%

  persistent fact;
  persistent ntotal;

  ierror = 0;
%
%  On user's signal, set up the factorial table.
%
  if ( ~key )

    key = 1;

    if ( nrow <= 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'RCONT - Fatal error!\n' );
      fprintf ( 1, '  Input number of rows is less than 2.\n' );
      ierror = 1;
      return
    end

    if ( ncol <= 1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'RCONT - Fatal error!\n' );
      fprintf ( 1, '  The number of columns is less than 2.\n' );
      ierror = 2;
      return
    end

    for i = 1 : nrow
      if ( nrowt(i) <= 0 )
        fprintf ( 1, '\n' );
        fprintf ( 1, 'RCONT - Fatal error!\n' );
        fprintf ( 1, '  An entry in the row sum vector is not positive.\n' );
        ierror = 3;
        return
      end
    end

    for j = 1 : ncol
      if ( ncolt(j) <= 0 )
        fprintf ( 1, '\n' );
        fprintf ( 1, 'RCONT - Fatal error!\n' );
        fprintf ( 1, '  An entry in the column sum vector is not positive.\n' );
        ierror = 4;
        return
      end
    end

    if ( sum ( ncolt(1:ncol) ) ~= sum ( nrowt(1:nrow) ) )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'RCONT - Fatal error!\n' );
      fprintf ( 1, '  The row and column sum vectors do not have the same sum.\n' );
      ierror = 6;
      return
    end

    ntotal = sum ( ncolt(1:ncol) );

    fact = zeros(ntotal,1);
%
%  Calculate log-factorials.
%
    x = 0.0;
    fact(1) = 0.0;
    for i = 1 : ntotal
      x = x + log ( i );
      fact(i+1) = x;
    end

  end
%
%  Construct a random matrix.
%
  jwork(1:ncol-1) = ncolt(1:ncol-1);

  jc = ntotal;

  for l = 1 : nrow - 1

    nrowtl = nrowt(l);
    ia = nrowtl;
    ic = jc;
    jc = jc - nrowtl;

    for m = 1 : ncol - 1

      id = jwork(m);
      ie = ic;
      ic = ic - id;
      ib = ie - ia;
      ii = ib - id;
%
%  Test for zero entries in matrix.
%
      if ( ie == 0 )
        ia = 0;
        matrix(l,m:ncol) = 0;
        break
      end
%
%  Generate a pseudo-random number.
%
      [ r, seed ] = r8_uniform_01 ( seed );
%
%  Compute the conditional expected value of MATRIX(L,M).
%
      done1 = 0;

      while ( 1 );

        nlm = floor ( ia * id / ie + 0.5 );
        iap = ia + 1;
        idp = id + 1;
        igp = idp - nlm;
        ihp = iap - nlm;
        nlmp = nlm + 1;
        iip = ii + nlmp;
        x = exp ( fact(iap) + fact(ib+1) + fact(ic+1) + fact(idp) - ...
          fact(ie+1) - fact(nlmp) - fact(igp) - fact(ihp) - fact(iip) );

        if ( r <= x )
          break;
        end

        sumprb = x;
        y = x;
        nll = nlm;
        lsp = 0;
        lsm = 0;
%
%  Increment entry in row L, column M.
%
        while ( ~lsp )

          j = ( id - nlm ) * ( ia - nlm );

          if ( j == 0 )

            lsp = 1;

          else

            nlm = nlm + 1;
            x = x * j / ( nlm * ( ii + nlm ) );
            sumprb = sumprb + x;

            if ( r <= sumprb )
              done1 = 1;
              break
            end

          end

          done2 = 0;

          while ( ~lsm )
%
%  Decrement the entry in row L, column M.
%
            j = nll * ( ii + nll );

            if ( j == 0 )
              lsm = 1;
              break
            end

            nll = nll - 1;
            y = y * j / ( ( id - nll ) * ( ia - nll ) );
            sumprb = sumprb + y;

            if ( r <= sumprb )
              nlm = nll;
              done2 = 1;
              break
            end

            if ( ~lsp )
              break
            end

          end

          if ( done2 )
            break
          end

        end

        if ( done1 )
          break
        end

        if ( done2 )
          break
        end

        [ r, seed ] = r8_uniform_01 ( seed );
        r = sumprb * r;

      end

      matrix(l,m) = nlm;
      ia = ia - nlm;
      jwork(m) = jwork(m) - nlm;

    end

    matrix(l,ncol) = ia;

  end
%
%  Compute the last row.
%
  matrix(nrow,1:ncol-1) = jwork(1:ncol-1);
  matrix(nrow,ncol) = ib - matrix(nrow,ncol-1);

  return
end


function [ y, m, d ] = day_carry_common ( y, m, d )

%*****************************************************************************80
%
%% DAY_CARRY_COMMON carries days to months in a Common date.
%
%  Discussion:
%
%    While ( number of days in M ) < D:
%      decrease the day D by the number of days in the month M;
%      increase M by 1;
%      if necessary, adjust Y.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, integer M, integer D, the YMD date.
%
%    Output, integer Y, integer M, integer D, the YMD date.
%    On output, D is between 1 and the number of days in M.
%

%
%  If the date is in the transition month, deflate it,
%  so we can perform ordinary arithmetic.
%
  [ y, m, d ] = deflate_common ( y, m, d );

  days = month_length_common ( y, m );

  while ( days < d )

    d = d - days;
    m = m + 1;
    days = month_length_common ( y, m );
%
%  Make sure the month isn't too big.
%
    [ y, m ] = month_carry_common ( y, m );

  end
%
%  If the date is in the transition month, inflate it.
%
  [ y, m, d ] = inflate_common ( y, m, d );

  return
end


function [chi, labels] = imEuler3dEstimate(img, varargin)
% Estimate Euler number in a 3D image.
%
%   CHIest = imEuler3dEstimate(IMG)
%   CHIest = imEuler3dEstimate(IMG, CONN)
%   Estimate Euler number in a 3D image, without taking into account the
%   contribution of the voxels located on image border. The result of this
%   function is usually divided by the volume the sampling window to obtain
%   an estimate of Euler number density.
%
%   Example
%     imEuler3dEstimate
%
%   See also
%     imEuler3dDensity, imEuler3d

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

%% Process input arguments

% check image dimension
if ndims(img) ~= 3
    error('first argument should be a 3D image');
end

% in case of a label image, return a vector with a set of results
if ~islogical(img)
    labels = unique(img);
    labels(labels==0) = [];
    chi = zeros(length(labels), 1);
    for i = 1:length(labels)
        chi(i) = imEuler3dEstimate(img==labels(i), varargin{:});
    end
    return;
end

% extract connectivity
conn = 6;
if ~isempty(varargin)
    conn = varargin{1};
end

% determines connectivity to use on faces
conn2d = 4;
if conn == 26
    conn2d = 8;
end

% in case of binary image, compute only one label...
labels = 1;

%% Main processing

% Euler-Poincare Characteristic of the binary structure in image
chi     = imEuler3d(img, varargin{:});

% compute EPC on each of the 12 border edge of image, and keep the average
chix    = mean([ ...
    imEuler1d(img(:,   1,   1)) ...
    imEuler1d(img(:, end,   1)) ...
    imEuler1d(img(:,   1, end)) ...
    imEuler1d(img(:, end, end)) ...
    ]);
chiy    = mean([ ...
    imEuler1d(img(  1, :,   1)) ...
    imEuler1d(img(end, :,   1)) ...
    imEuler1d(img(  1, :, end)) ...
    imEuler1d(img(end, :, end)) ...
    ]);
chiz    = mean([ ...
    imEuler1d(img(  1,   1, :)) ...
    imEuler1d(img(end,   1, :)) ...
    imEuler1d(img(  1, end, :)) ...
    imEuler1d(img(end, end, :)) ...
    ]);

% compute EPC on each of the 6 border faces, and keep the average
chixy    = mean([ ...
    imEuler2d(squeeze(img(:, :,   1)), conn2d) ...
    imEuler2d(squeeze(img(:, :, end)), conn2d) ...
    ]);
chixz    = mean([ ...
    imEuler2d(squeeze(img(:,  1,  :)), conn2d) ...
    imEuler2d(squeeze(img(:, end, :)), conn2d) ...
    ]);
chiyz    = mean([ ...
    imEuler2d(squeeze(img(  1, :, :)), conn2d) ...
    imEuler2d(squeeze(img(end, :, :)), conn2d) ...
    ]);

% compute EPC on each of the 8 corners of image, and keep the average
chixyz   = mean([ ...
    img(  1,   1,   1), ...
    img(end,   1,   1), ...
    img(  1, end,   1), ...
    img(end, end,   1), ...
    img(  1,   1, end), ...
    img(end,   1, end), ...
    img(  1, end, end), ...
    img(end, end, end), ...
    ]);

% estimate EPC in image using mean edge correction
chi = chi - (chix + chiy + chiz) + (chixy + chixz + chiyz) - chixyz;


%% patchPathAngles
% Below is a demonstration of the features of the |patchPathAngles| function

%%
clear; close all; clc;

%% Syntax
% |[indAngles]=patchPathAngles(F,V,ind,isClosedLoop);|

%% Description
% The |patchPathAngles| function computes the angles between adjacent edges
% on a curve on a patch.

%% Examples

%% Example 1: Get angles on a closed path defined on the the boundary of a patch
% Create test data set
w=1;
[X,Y]=ndgrid(linspace(0,w,15));
Z=ones(size(X));
C=tril(Z);
[F,V,C]=surf2patch(X,Y,Z,C);
C=vertexToFaceMeasure(F,C)>0;

logicKeep=C>0;
F=F(logicKeep,:);
C=C(logicKeep,:);
[F,V]=patchCleanUnused(F,V);

%%
% Get boundary curve

Eb=patchBoundary(F);
indBoundaryCurve=edgeListToCurve(Eb);
indBoundaryCurve=indBoundaryCurve(1:end-1)'; %Start=End for closed curve so remove double entry

%%
% Calculate mesh path angles

isClosedPath=1;
[A]=patchPathAngles(F,V,indBoundaryCurve,isClosedPath);

%%

A=180*(A./pi); % Conver to degrees

% Display unique angles in set
unique(A)

%%

cFigure; hold on;
gpatch(F,V,'kw');
plotV(V(indBoundaryCurve,:),'k-','LineWidth',3);
scatterV(V(indBoundaryCurve,:),75,A,'filled');
colormap gjet; colorbar; caxis([0 360]);
axisGeom; view(2);
drawnow;

%% Example 2: Study angles for altered shape

V(:,1)=V(:,1)-V(:,2);

%%
% Calculate mesh path angles

isClosedPath=1;
[A]=patchPathAngles(F,V,indBoundaryCurve,isClosedPath);

%%

A=180*(A./pi); % Conver to degrees

% Display unique angles in set
unique(A)

%%

cFigure; hold on;
gpatch(F,V,'kw');
plotV(V(indBoundaryCurve,:),'k-','LineWidth',3);
scatterV(V(indBoundaryCurve,:),75,A,'filled');
colormap gjet; colorbar; caxis([0 360]);
axisGeom; view(2);
drawnow;

%% Example 3: Get angles on a non-closed path defined on the the boundary of a patch

%%
% Create path segment
indBoundaryCurve=indBoundaryCurve(1:6);

%%
% Calculate mesh path angles
isClosedPath=0;
[A]=patchPathAngles(F,V,indBoundaryCurve,isClosedPath);

%%

A=180*(A./pi); % Conver to degrees

% Display unique angles in set
unique(A(~isnan(A)))

%%

cFigure; hold on;
gpatch(F,V,'kw');
plotV(V(indBoundaryCurve,:),'k-','LineWidth',3);
scatterV(V(indBoundaryCurve,:),75,A,'filled');
colormap gjet; colorbar; caxis([0 360]);
axisGeom; view(2);
drawnow;

%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>

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


%BLUR  Smooths an image using the normalized box filter
%
%     dst = cv.blur(src)
%     dst = cv.blur(src, 'OptionName',optionValue, ...)
%
% ## Input
% * __src__ input image; it can have any number of channels, which are
%   processed independently, but the depth should be `uint8`, `uint16`,
%   `int16`, `single`, or `double`.
%
% ## Output
% * __dst__ output image of the same size and type as `src`.
%
% ## Options
% * __KSize__ blurring kernel size. default [5,5]
% * __Anchor__ Anchor point `[x,y]`. The default value `[-1,-1]` means that
%   the anchor is at the kernel center.
% * __BorderType__ Border mode used to extrapolate pixels outside of the
%   image. See cv.copyMakeBorder. default 'Default'
%
% The function smooths an image using the kernel:
%
%     K = ones(KSize) / prod(KSize)
%
% See also: cv.boxFilter, cv.bilateralFilter, cv.GaussianBlur, cv.medianBlur,
%  imfilter, fspecial
%


function yBin = BF_Binarize(y,binarizeHow)
% BF_Binarize    Converts an input vector into a binarized version

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function 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/>.
% ------------------------------------------------------------------------------

%-------------------------------------------------------------------------------
% Check inputs, set defaults:
%-------------------------------------------------------------------------------
if nargin < 2 || isempty(binarizeHow)
    binarizeHow = 'diff';
end

%-------------------------------------------------------------------------------
% Do the binary transformation:
%-------------------------------------------------------------------------------

switch binarizeHow
    case 'diff'
        % Binary signal: 1 for stepwise increases, 0 for stepwise decreases
        yBin = stepBinary(diff(y));

    case 'mean'
        % Binary signal: 1 for above mean, 0 for below mean
        yBin = stepBinary(y - mean(y));

    case 'median'
        % Binary signal: 1 for above median, 0 for below median
        yBin = stepBinary(y - median(y));

    case 'iqr'
        % Binary signal: 1 if inside interquartile range, 0 otherwise
        iqr = quantile(y,[0.25, 0.75]);
        iniqr = (y > iqr(1) & y <= iqr(2));
        yBin = zeros(length(y),1);
        yBin(iniqr) = 1;

    otherwise
        error('Unknown binary transformation setting ''%s''',binarizeHow)
end

%-------------------------------------------------------------------------------
function Y = stepBinary(X)
    % Transform real values to 0 if <=0 and 1 if >0:
    Y = zeros(size(X),'like',X);
    Y(X > 0) = 1;
end

end


% created: Zoya Bylinskii, March 6
% based on: Kummerer et al.
% (http://www.pnas.org/content/112/52/16054.abstract)

% This finds the information-gain of the saliencyMap over a baselineMap

function score = InfoGain(saliencyMap, fixationMap, baselineMap)
% saliencyMap is the saliency map
% fixationMap is the human fixation map (binary matrix)
% baselineMap is another saliency map (e.g. all fixations from other images)

%%
map1 = imresize(saliencyMap,size(fixationMap));
mapb = imresize(baselineMap,size(fixationMap));
%%
% normalize and vectorize saliency maps
map1 = (map1(:) - min(map1(:)))/(max(map1(:))-min(map1(:)));
mapb = (mapb(:) - min(mapb(:)))/(max(mapb(:))-min(mapb(:)));
%%

% turn into distributions
map1 = map1./sum(map1);
mapb = mapb./sum(mapb);

locs = logical(fixationMap(:));
%%
score = mean(log2(eps+map1(locs))-log2(eps+mapb(locs)));


function [mx,my,mz] = blochsim2(Mi, bx, by, bz, T1, T2, dt)

%	Evolve magnetization field using time-discretized Bloch equation
%	Input
%		Mi [3,dim]	initial X,Y,Z magnetization
%					Note: normalized to magnitude <= Mo=1
%		bx,by,bz [ntime,dim]	effective X,Y,Z applied magnetic field
%					(Tesla), for rotating frame (no Bo)
%		T1	[dim]		spin-lattice relaxation time (msec)
%		T2	[dim]		spin-spin relaxation time (msec)
%		dt	scalar		time interval (msec)
%	Output
%		mx,my,mz [ntime,dim]  X,Y,Z magnetization as a function of time
%
% uses:
% https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula

% constants
gambar = 42.57e3;        % gamma/2pi in kHz/T
gam = 267513; %gambar*2*pi;
% Put Beff into units rotations, T1 and T2 into losses
bx = bx.*(dt*gam);      % rotation angle/step
by = by.*(dt*gam);      % rotation angle/step
bz = bz.*(dt*gam);      % rotation angle/step
% Put relaxations into losses/recovery per step
T1 = (dt ./ T1(:));
T2 = (1 - dt ./ T2(:));

% size checks
if ~isreal(bx) || ~isreal(by) || ~isreal(bz)
    bx = real(bx);
    by = real(by);
    bz = real(bz);
    disp('Warning: B field must be real valued - using only the real part');
end
if (size(bx) ~= size(by)) || (size(bx) ~= size(bz))
    disp('Error: B vectors not the same length')
    return;
end
if (size(Mi,2) ~= size(bx,2))
    disp('Error: Initial magnetization not right size')
    return;
end
if (size(Mi,2) ~= length(T1))
    disp('Error: T1 vector not right size')
    return;
end
if (size(Mi,2) ~= length(T2))
    disp('Error: T2 vector not right size')
    return;
end

nstep = size(bx,1);
%
% Initialize outputs
mx = zeros(size(bx,1)+1,size(bx,2)); % record one more location
my = zeros(size(mx));
mz = zeros(size(mx));
mx(1,:) = Mi(1,:);
my(1,:) = Mi(2,:);
mz(1,:) = Mi(3,:);

% stable bloch equation simulator: rotations are explicitly
% calculated and carried out on the magnetization vector
for lp = 2:nstep+1 % Hao: modified from 2:nstep to 2:nstep+1. This will record the mag. after last pulse point.
  B = [bx(lp-1,:); by(lp-1,:); bz(lp-1,:)]';
  %	Compute sines & cosines of field angles:
  %	Theta = angle w.r.t positive z axis
  %	Phi   = angle w.r.t positive x axis
  %	Psi   = angle w.r.t transformed positive x axis
  %
  Bmag = sqrt(sum(B.^2,2));		% Magnitude of applied field
  Btrans = sqrt(B(:,1).^2 + B(:,2).^2);	% Magnitude of transverse applied field
  ct = ones(size(B,1),1);
  good = Bmag ~= 0;
  if any(good)
	ct(good) = B(good,3) ./ Bmag(good);	% cos(theta)
  end
  st = sqrt(1 - ct.^2);				% sin(theta) > 0

  cphi = ones(size(B,1),1);
  good = Btrans ~= 0;
  if any(good)
	cphi(good) = B(good,1) ./ Btrans(good);	% cos(phi)
  end
  sphi = sqrt(1 - cphi.^2) .* sign(B(:,2));	% sin(phi)

  cpsi = cos(Bmag);			% cos(psi)
  spsi = sin(Bmag);			% sin(psi)

  %
  %	Evolve
  %
  if any(Bmag ~= 0)
    Mx0 = mx(lp-1,:)';
    My0 = my(lp-1,:)';
    Mz0 = mz(lp-1,:)';

    Mx1 = cphi.*(ct.*(cpsi.*(ct.*(sphi.*My0+cphi.*Mx0)-st.*Mz0) ...
    + spsi.*(cphi.*My0-sphi.*Mx0))+st.*(ct.*Mz0+st.*(sphi.*My0+cphi.*Mx0))) ...
    - sphi.*(-spsi.*(ct.*(sphi.*My0+cphi.*Mx0)-st.*Mz0) ...
    + cpsi.*(cphi.*My0-sphi.*Mx0));
    My1 = sphi.*(ct.*(cpsi.*(ct.*(sphi.*My0+cphi.*Mx0)-st.*Mz0) ...
    + spsi.*(cphi.*My0-sphi.*Mx0))+st.*(ct.*Mz0+st.*(sphi.*My0+cphi.*Mx0))) ...
    + cphi.*(-spsi.*(ct.*(sphi.*My0+cphi.*Mx0)-st.*Mz0) ...
    + cpsi.*(cphi.*My0-sphi.*Mx0));
    Mz1 = ct.*(ct.*Mz0+st.*(sphi.*My0+cphi.*Mx0)) ...
    - st.*(cpsi.*(ct.*(sphi.*My0+cphi.*Mx0)-st.*Mz0) ...
    + spsi.*(cphi.*My0-sphi.*Mx0));
  else
    Mx1 = mx(lp-1,:)';
    My1 = my(lp-1,:)';
    Mz1 = mz(lp-1,:)';
  end
  % relaxation effects: "1" in Mz since Mo=1 by assumption
  mx(lp,:) = (Mx1 .* T2)';
  my(lp,:) = (My1 .* T2)';
  mz(lp,:) = (Mz1 + (1- Mz1).* T1)'; % true, since mz = Mo - (Mo-mz)*exp(-dt/T1) ~ Mo - (Mo-mz)(1-dt/T1) = mz + (Mo-mz)*dt/T1

end % end loop through time

% Hao: made the change so my,my,mz will NOT record the initial mag. But record the mag. after last pulse point
  mx(1,:) = [];
  my(1,:) = [];
  mz(1,:) = [];   % true, since mz = Mo - (Mo-mz)*exp(-dt/T1) ~ Mo - (Mo-mz)(1-dt/T1) = mz + (Mo-mz)*dt/T1


function [out] = baseflow_5(p1,p2,S,Smax,dt)
%baseflow_5

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Non-linear scaled outflow from a reservoir
% Constraints:  f <= S/dt
% @(Inputs):    p1   - base outflow rate [mm/d]
%               p2   - exponential scaling parameter [-]
%               S    - current storage [mm]
%               Smax - maximum contributing storage [mm]
%               dt   - time step size [d]

out = min(S/dt,p1*((max(S,0)/Smax)^p2));

end


clear;
x = uiuc_sample;
options.J = 5;
options.M = 2;

Wop = wavelet_factory_3d_pyramid(options, options, options);

Sx = scat(x, Wop);
%%
Sx_renorm = renorm_scat_spatial(Sx);
ssx = mean(mean(format_scat(Sx),2),3);
ssx_rn = mean(mean(format_scat(Sx_renorm),2),3);
plot([ssx(2:end),ssx_rn(2:end)])


classdef DOC3 < PROBLEM
% <multi> <real> <constrained>
% Benchmark MOP with constraints in both decision and objective spaces

%------------------------------- Reference --------------------------------
% Z. Liu and Y. Wang, Handling constrained multiobjective optimization
% problems with constraints in both the decision and objective spaces. IEEE
% Transactions on Evolutionary Computation, 2019, 23(5): 870-884.
%------------------------------- 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;
            obj.D = 10;
            obj.lower    = [0 0 0 0 0 0 0 0 0 0.01];
            obj.upper    = [1 1 300 100 200 100 1 100 200 0.03];
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values and constraint violations
        function Population = Evaluation(obj,varargin)
            X = varargin{1};
            X = max(min(X,repmat(obj.upper,size(X,1),1)),repmat(obj.lower,size(X,1),1));
            g_temp = -9.* X(:, 6) - 15.* X(:, 9) + 6.* X(:, 2) + 16.* X(:, 3) + 10.* (X(:, 7) + X(:, 8));
            g = (g_temp+400.0551) +1;
            PopObj(:,1) = X(:,1);
            PopObj(:,2) = g.*(1 - (PopObj(:,1))./g);
            % Constraints in objective space
            c(:,1) = max( -(PopObj(:,1).^2 + PopObj(:,2).^2-1), 0);
            c(:,2) = max(-( abs( (-PopObj(:,1) + PopObj(:,2) -0.5)/sqrt(2)) - 0.1/sqrt(2)), 0);
            c(:,3) = max(-( abs( (-PopObj(:,1) + PopObj(:,2) -0)/sqrt(2)) - 0.1/sqrt(2)), 0);
            c(:,4) = max(-( abs( (-PopObj(:,1) + PopObj(:,2) +0.5)/sqrt(2)) - 0.1/sqrt(2)), 0);

            % Constraints in decision space
            c(:,5)  = X(:, 10).* X(:, 4) + 0.02.* X(:, 7) - 0.025.* X(:, 6);
            c(:,6)  = X(:, 10).* X(:, 5) + 0.02.* X(:, 8) - 0.015.* X(:, 9);
            c(:,7)  = abs(X(:, 2) + X(:, 3) - X(:, 4) - X(:, 5)) - 0.0001;
            c(:,8)  = abs(0.03.* X(:, 2) + 0.01.* X(:, 3) - X(:, 10).* (X(:, 4) + X(:, 5))) - 0.0001;
            c(:,9)  = abs(X(:, 4) + X(:, 7) - X(:, 6)) - 0.0001;
            c(:,10) = abs(X(:, 5) + X(:, 8) - X(:, 9)) - 0.0001;
            Population = SOLUTION(X,PopObj,c,varargin{2:end});
            obj.FE     = obj.FE + length(Population);
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            R = UniformPoint(N,2);
            R = R./repmat(sqrt(sum(R.^2,2)),1,2);
            R(0.3403<R(:,1) & R(:,1)<0.4782 | 0.6553<R(:,1) & R(:,1)<0.7553 | 0.8782<R(:,1) & R(:,1)<0.9403,:) = [];
        end
        %% Generate the image of Pareto front
        function R = GetPF(obj)
            R = UniformPoint(100,2);
            R = R./repmat(sqrt(sum(R.^2,2)),1,2);
            R(0.3403<R(:,1) & R(:,1)<0.4782 | 0.6553<R(:,1) & R(:,1)<0.7553 | 0.8782<R(:,1) & R(:,1)<0.9403,:) = nan;
        end
    end
end


function plotEmptySphere(varargin)
% plots white sphere

if check_option(varargin,'parent')
  ax = get_option(varargin,'parent');
else
  ax = gca;
end

[x, y, z] = sphere;
x = 0.99*x;
y = 0.99*y;
z = 0.99*z;
surface(x,y,z,'FaceColor', 'w','EdgeColor','none','parent',ax,'handlevisibility','off')
hold(ax,'on')

dth = 15*degree;
th = -pi/2+dth:dth:pi/2-dth;
rh = linspace(0,2*pi,100);

[th,rh] = meshgrid(th,rh);

[x,y,z] = sph2cart(rh, th, 1);

line(x,y,z,'color',[1 1 1] * 0.8,'parent',ax,'handlevisibility','off');

drh = 15*degree;
rh = 0:drh:2*pi-drh;
th = linspace(-pi/2,pi/2,50);

[th,rh] = meshgrid(th,rh);

[x,y,z] = sph2cart(rh, th, 1);

line(x.',y.',z.','color',[1 1 1] * 0.8,'parent',ax,'handlevisibility','off')

axis(ax,'equal','vis3d','off');
set(ax,'XDir','rev','YDir','rev',...
  'XLim',[-1.02,1.02],'YLim',[-1.02,1.02],'ZLim',[-1.02,1.02]);
view(3);

if nargout == 0, clear h;end

end


function test_approx_test05 ( )

%*****************************************************************************80
%
%% TEST_APPROX_TEST05 uses Overhauser spline interpolation on all problems.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 August 2011
%
%  Author:
%
%    John Burkardt
%
  num_dim = 1;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST_APPROX_TEST05\n' );
  fprintf ( 1, '  Overhauser spline interpolation.\n' );

  prob_num = p00_prob_num ( );

  for prob = 1 : prob_num

    title = p00_title ( prob );

    data_num = p00_data_num ( prob );

    [ xdata, ydata ] = p00_dat ( prob, data_num );

    a = xdata(1);
    b = xdata(data_num);

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Problem %d\n', prob );
    fprintf ( 1, '  %s\n', title );
    fprintf ( 1, '\n' );
    fprintf ( 1, '  X   Y\n' );
    fprintf ( 1, '\n' );
%
%  Evaluate the interpolation function.
%
    for i = 1 : data_num - 1

      jmax = 3;

      if ( i == data_num - 1 )
        jhi = jmax;
      else
        jhi = jmax - 1;
      end

      for j = 1 : jhi

        xval = ( ( jmax - j     ) * xdata(i)     ...
               + (        j - 1 ) * xdata(i+1) ) ...
               / ( jmax     - 1 );

        yval = spline_overhauser_val ( num_dim, data_num, xdata, ydata, xval );

        if ( j == 1 || j == 3 )
          mark = '*';
        else
          mark = ' ';
        end

        fprintf ( 1, '  %c  %14g  %14g\n', mark, xval, yval );

      end

    end

  end

  return
end


function isbn = isbn_fill ( isbn )

%*****************************************************************************80
%
%% ISBN_FILL fills in a missing digit in an ISBN code.
%
%  Example:
%
%    Input:
%
%      0-8493-9?40-9
%
%    Output:
%
%      0-8493-9640-9
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 June 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Book Industry Study Group,
%    The Evolution in Product Identification:
%    Sunrise 2005 and the ISBN-13,
%    http://www.bisg.org/docs/The_Evolution_in_Product_ID.pdf
%
%  Parameters:
%
%    Input, string ISBN, a partial ISBN code, with a
%    single digit replaced by the character '?', signifying
%    that that digit is missing.
%
%    Output, string ISBN, the completed ISBN code.
%
  lenc = s_len_trim ( isbn );

  i = 0;
  isbn_pos = -1;
  digit_pos = -1;
  num_digit = 0;

  while ( 1 )

    i = i + 1;

    if ( lenc < i )
      break
    end

    c = isbn(i);

    if ( ch_is_digit ( c ) )

      num_digit = num_digit + 1;
      digit(num_digit) = isbn_to_i4 ( c );

    elseif ( ( num_digit == 9 & isbn(i:i) == 'X' ) | ...
             ( num_digit == 9 & isbn(i:i) == 'x' ) )

      num_digit = num_digit + 1;
      digit(num_digit) = isbn_to_i4 ( c );

    elseif ( c == '?' )

      if ( isbn_pos == -1 )

        num_digit = num_digit + 1;
        digit(num_digit) = 0;
        digit_pos = num_digit;
        isbn_pos = i;

      else
        fprintf ( 1, '\n' );
        fprintf ( 1, 'ISBN_FILL - Fatal error!\n' );
        fprintf ( 1, '  Only one question mark is allowed!\n' );
        error ( 'ISBN_FILL - Fatal error!' );
      end

    end

    if ( 10 <= num_digit )
      break
    end

  end

  if ( num_digit ~= 10 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'ISBN_FILL - Fatal error!\n' );
    fprintf ( 1, '  The input ISBN code did not have 10 digits.\n' );
    error ( 'ISBN_FILL - Fatal error!' );
  end

  if ( isbn_pos == -1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'ISBN_FILL - Fatal error!\n' );
    fprintf ( 1, '  A question mark is required!\n' );
    error ( 'ISBN_FILL - Fatal error!' );
  end

  check = 0;
  for i = 1 : 10
    check = check + ( 11 - i ) * digit(i);
  end

  check = mod ( check, 11 );

  if ( check == 0 )

    k = 0;
%
%  Need to solve the modular equation:
%
%    A * X = B mod C
%
%  Below is a stupid way.  One day I will come back and fix this up.
%
  else

    for i = 1 : 10
      j = ( 11 - digit_pos ) * i + check;
      if ( mod ( j, 11 ) == 0 )
        k = i;
      end
    end

  end

  isbn(isbn_pos) = i4_to_isbn ( k );

  return
end