% Simulation code for [1], presented in ICIP'09 (http://www.icip2009.org/)
%
% [1] Paul Rodriguez and Brendt Wohlberg, "A Generalized Vector-Valued Total
%     Variation Algorithm", in Proceedings of IEEE International Conference
%     on Image Processing (ICIP), (Cairo, Egypt), doi:10.1109/ICIP.2009.5413587 ,
%     pp. 1309--1312, Nov 2009
%
% Legal:
%   irnIcip09.m is based on NUMIPAD (http://numipad.sf.net). NUMIPAD is free
%   software, you can redistribute it and/or modify it under the terms of
%   the GNU General Public License (version 2).
%
%   The NUMIPAD library is being developed under U.S. Government contract
%   W-7405-ENG-36 for Los Alamos National Laboratory.
%
% Authors
%   Paul Rodriguez    prodrig@pucp.edu.pe
%   Brendt Wohlberg   brendt@tmail.lanl.gov

clear all;
%close all;

SHOW_IMGS = false;
%  SHOW_IMGS = true;

%  example = 'icip09'
%  example = 'l1deconv';
%  example = 'l2deconv';
example = 'l1denoise';
%  example = 'l2denoise';

extreme = 0;

nmppath;

BKS_CODE = exist('MainRestoration');
if( (BKS_CODE == 0) && ( strcmp(example, 'l1deconv') || strcmp(example, 'l2deconv') || strcmp(example, 'icip09') ) )
  disp('NOTE:');
  disp('  The function MainRestoration (code for [BKS]) is not in your path...');
  disp(sprintf('  disabling BKS simulations for %s.\n',example));
  disp('  [BKS] L. Bar, A. Brook, N. Sochen and N. Kiryati');
  disp('        "Deblurring of Color Images Corrupted by Impulsive Noise" ');
  disp('        IEEE Transactions on Image Processing, 16 (1101-1111), 2007');
end

BnG_CODE = exist('tvdenoise');
if( (BnG_CODE == 0) && ( strcmp(example, 'l2denoise') || strcmp(example, 'icip09') ) )
  disp('NOTE:');
  disp('  The function tvdenoise (code for [BnG]) is not in your path...');
  disp(sprintf('  disabling BnG simulations for %s.\n',example));
  disp('  [BnG] an implementation of the fast dual minimization of VTV [1].');
  disp('        Code may be downloaded from:');
  disp('        http://www.mathworks.fr/matlabcentral/fileexchange/16236');
  disp('  [1] X. Bresson and T. Chan');
  disp('      "Fast dual minimization of the vectorial total variation norm and');
  disp('       applications to color image processing"');
  disp('      Journal of Inverse Problems and Imaging, 2:4(455--484), 2008');
end

if( exist('color_imgs/peppers_color.png') && exist('color_imgs/mandrill_color.png') ...
    && exist('color_imgs/lena_color_256.png') )
  disp(sprintf('\nRunning %s simulation... \n', example));
else
  disp(' ');
  disp('One or more test images are not in the current directory...');
  disp('You may download them from:');
  disp('http://sites.google.com/a/istec.net/prodrig/Home/en/pubs');
  disp('look for "test images" under "A Generalized Vector-Valued Total ');
  disp('Variation Algorithm"');
  disp(' ');
  disp('Exiting simulation code...');
  return;
end

if( strcmp(example, 'icip09') )

  str_all = [];
  ICIP_FLAG = 1;

else

  ICIP_FLAG = 0;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       Input images        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

pepImg = imread('peppers_color.png');
pepImg = double(pepImg)/255.0;

lenImg = imread('lena_color_256.png');
lenImg = double(lenImg)/255.0;

mdrilImg = imread('mandrill_color.png');
mdrilImg = double(mdrilImg)/255.0;

%%%%%%%%%%%%%%%%%%%%%%%%
%     Normalize        %
%%%%%%%%%%%%%%%%%%%%%%%%

Normalize = @(x) (x - min(x(:)))/(max(x(:)) - min(x(:)));

%%%%%%%%%%%%%%%%%%%%%%%%
%       kernels        %
%%%%%%%%%%%%%%%%%%%%%%%%

kernel_BSK = fspecial('disk',3.2);

K_BSK = @(x) imfilter(x, kernel_BSK, 'symmetric','conv');
KT_BSK = @(x) K_BSK(x);
KC_BSK = {K_BSK, KT_BSK};

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       Blurred & noisy images        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

lenImgBlur = K_BSK(lenImg);

lenImgBlur_01L1 = imnoise(lenImgBlur, 'salt & pepper', 0.1);
lenImgBlur_03L1 = imnoise(lenImgBlur, 'salt & pepper', 0.3);

% ---

lenImgBlur_01L2 = imnoise(lenImgBlur, 'gaussian', 0, ...
                          0.01*max(lenImgBlur(:)) ); %NOTE sigma^2 in imnoise

lenImgBlur_005L2 = imnoise(lenImgBlur,'gaussian', 0, ...
                           0.0025*max(lenImgBlur(:)) );

lenImgBlur_001L2 = imnoise(lenImgBlur,'gaussian', 0, ...
                           0.0001*max(lenImgBlur(:)) );
% -- BSK example ---:
lenImgBlur_bskL2 = imnoise(lenImgBlur,'gaussian', 0, ...
                           0.00001*max(lenImgBlur(:)) );

% ---

mdrilImg_01L1 = imnoise(mdrilImg, 'salt & pepper', 0.1);
mdrilImg_03L1 = imnoise(mdrilImg, 'salt & pepper', 0.3);

mdrilImg_01L2 = imnoise(mdrilImg,  'gaussian', 0, ...
                        0.01*max(mdrilImg(:)) ); %NOTE sigma^2 in imnoise
mdrilImg_005L2 = imnoise(mdrilImg, 'gaussian', 0, ...
                         0.0025*max(mdrilImg(:)) );

% ---

pepImg_01L1 = imnoise(pepImg, 'salt & pepper', 0.1);
pepImg_03L1 = imnoise(pepImg, 'salt & pepper', 0.3);

pepImg_01L2 = imnoise(pepImg, 'gaussian', 0, 0.01*max(pepImg(:)) );
pepImg_005L2 = imnoise(pepImg, 'gaussian', 0, 0.0025*max(pepImg(:)) );

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

if( strcmp(example,'l1deconv') || strcmp(example,'icip09') )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       L1 Deconvolved        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%noise level: 0.1

%-- IRN
lambda = 0.035;
pars = irntvInputPars('l1tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 4;
%  pars.pcgtol_ini   = 1e-4;
pars.U0           = lenImgBlur_01L1;

tic;
IRN_lenImgBlur_01L1 = irntv(lenImgBlur_01L1, KC_BSK, lambda, pars);
tirn_01L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_01L1) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_01L1), tirn_01L1n0));
end

if(BKS_CODE)
%-- BSK MSTV (Mumford-Shah TV)

Params = SetParams;
Params.beta=0.5;              % check - same value as bar-2007-deblurring
Params.alpha=0.1;             % check
Params.epsilon=0.1;           % check
Params.gamma = 2*10^(-3);     % as "\mu in bar-2007-deblurring table IV

%  [uh_mstv,V] = MainRestoration(z, kernel, 'L1', 'MSTV', Params);
tic;
[MSTV_lenImgBlur_01L1, V_MSTV_01L1] = MainRestoration(lenImgBlur_01L1, ...
                                            kernel_BSK, 'L1', 'MSTV', Params);
tbsk_01L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_01L1 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_01L1), tbsk_01L1n0));
end

%-- BSK 1^1-TV
Params = SetParams;
Params.beta=0.1;              % check - same value as bar-2007-deblurring

tic;
[BKSL1_lenImgBlur_01L1, V_BKSL1_01L1] = MainRestoration(lenImgBlur_01L1, ...
                                              kernel_BSK, 'L1', 'L1', Params);
tbsk_01L1n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( BKSL1_lenImgBlur_01L1 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - BKSL1. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, BKSL1_lenImgBlur_01L1), tbsk_01L1n1));
end

end % _END_ if(BKS_CODE)
%------------------------------------------------------------------------------

%noise level: 0.3

lambda = 0.070;
pars = irntvInputPars('l1tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 6;
%  pars.pcgtol_ini   = 1e-4;
pars.U0           = lenImgBlur_03L1;

tic;
IRN_lenImgBlur_03L1 = irntv(lenImgBlur_03L1, KC_BSK, lambda, pars);
tirn_03L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_03L1) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_03L1), tirn_03L1n0));
end

if(BKS_CODE)
%-- BSK MSTV (Mumford-Shah TV)

Params = SetParams;
Params.beta=1.1;            % as describe in bar-2007-deblurring, table IV
Params.alpha=0.5;           % as describe in bar-2007-deblurring, table IV
Params.epsilon=0.1;         % check
Params.gamma = 2*10^(-3);

%  [uh_mstv,V] = MainRestoration(z, kernel, 'L1', 'MSTV', Params);
tic;
[MSTV_lenImgBlur_03L1, V_MSTV_03L1] = MainRestoration(lenImgBlur_03L1, ...
                                            kernel_BSK, 'L1', 'MSTV', Params);
tbsk_03L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_03L1 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_03L1), tbsk_03L1n0));
end

%-- BSK L1

Params = SetParams;
Params.beta=0.2;            % as describe in bar-2007-deblurring, table IV

tic;
[BKSL1_lenImgBlur_03L1, V_MSTV_03L1] = MainRestoration(lenImgBlur_03L1, ...
                                              kernel_BSK, 'L1', 'L1', Params);
tbsk_03L1n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( BKSL1_lenImgBlur_03L1 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, BKSL1_lenImgBlur_03L1), tbsk_03L1n1));
end

end % _END_  if(BKS_CODE)

if(ICIP_FLAG == 0)

  disp('L1 Deconvolve Vector TV');
  disp(' ');
  disp('                          SNR (db)                         Time (s)');
  disp(' Img      Noise    VTV-IRN    MSTV    BKSL1          VTV IRN    MSTV    BKSL1');
  disp(' ');
  if(BKS_CODE)
  disp(sprintf('Lena       0.1      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_01L1), snr(lenImg, MSTV_lenImgBlur_01L1), snr(lenImg, BKSL1_lenImgBlur_01L1), ...
     tirn_01L1n0, tbsk_01L1n0, tbsk_01L1n1));
  disp(sprintf('           0.3      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_03L1), snr(lenImg, MSTV_lenImgBlur_03L1), snr(lenImg, BKSL1_lenImgBlur_03L1), ...
     tirn_03L1n0, tbsk_03L1n0, tbsk_03L1n1));
  else
  disp(sprintf('Lena       0.1      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_01L1), NaN, NaN, ...
     tirn_01L1n0, NaN, NaN));
  disp(sprintf('           0.3      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_03L1), NaN, NaN, ...
     tirn_03L1n0, NaN, NaN));

  end % _END_ if(BKS_CODE)

else % IF(icip)

  str = sprintf('L1 Deconvolve Vector TV\n\n');
  str_all = [str_all str];
  str = sprintf('                          SNR (db)                         Time (s)\n');
  str_all = [str_all str];
  str = sprintf(' Img      Noise    VTV-IRN    MSTV    BKSL1          VTV IRN    MSTV    BKSL1\n\n');
  str_all = [str_all str];

  if(BKS_CODE)
  str = sprintf('Lena       0.1      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_01L1), snr(lenImg, MSTV_lenImgBlur_01L1), snr(lenImg, BKSL1_lenImgBlur_01L1), ...
     tirn_01L1n0, tbsk_01L1n0, tbsk_01L1n1);
  str_all = [str_all str];
  str = sprintf('           0.3      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f\n\n\n', ...
     snr(lenImg, IRN_lenImgBlur_03L1), snr(lenImg, MSTV_lenImgBlur_03L1), snr(lenImg, BKSL1_lenImgBlur_03L1), ...
     tirn_03L1n0, tbsk_03L1n0, tbsk_03L1n1);
  str_all = [str_all str];
  else
  str = sprintf('Lena       0.1      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_01L1), NaN, NaN, ...
     tirn_01L1n0, NaN, NaN);
  str_all = [str_all str];
  str = sprintf('           0.3      %5.1f     %5.1f    %5.1f          %5.1f     %5.1f    %5.1f\n\n\n', ...
     snr(lenImg, IRN_lenImgBlur_03L1), NaN, NaN, ...
     tirn_03L1n0, NaN, NaN);
  str_all = [str_all str];

  end % _END_ if(BKS_CODE)

end

end % _END_ if( strcmp(example,'l1deconv') || strcmp(example,'icip09') )

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

if( strcmp(example,'l2deconv') || strcmp(example,'icip09') )

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       L2 Deconvolved        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if(extreme == 1)

%noise level: 0.1

%-- IRN
lambda  = 0.04;
pars = irntvInputPars('l2tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 3;
pars.pcgtol_ini   = 1e-4;
%  pars.U0           = lenImgBlur_01L2;

tic;
IRN_lenImgBlur_01L2 = irntv(lenImgBlur_01L2, KC_BSK, lambda, pars);
tirn_01L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_01L2) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_01L2), tirn_01L2n0));
end

if(BKS_CODE)
%-- BSK MSTV (Mumford-Shah TV)

Params      = SetParams;
Params.beta = 0.01*max(lenImgBlur(:));

tic;
[MSTV_lenImgBlur_01L2, V_MSTV_001L2] = MainRestoration(lenImgBlur_01L2, ...
                                              kernel_BSK, 'L2', 'MS', Params);
tbsk_01L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_01L2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_01L2), tbsk_01L2n0));
end

end % _END_ if(BKS_CODE)
end % _END_ if(extreme == 1)
%-----------------------------------------------------------------------------

%noise level: 0.05

%-- IRN
lambda  = 0.01;
pars = irntvInputPars('l2tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 3;
%  pars.pcgtol_ini   = 1e-4;
pars.U0           = lenImgBlur_005L2;

tic;
IRN_lenImgBlur_005L2 = irntv(lenImgBlur_005L2, KC_BSK, lambda, pars);
tirn_005L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_005L2) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_005L2), tirn_005L2n0));
end

if(BKS_CODE)
%-- BSK

Params      = SetParams;
Params.beta = 0.0025*max(lenImgBlur(:));

tic;
[MSTV_lenImgBlur_005L2, V_MSTV_05L2] = MainRestoration(lenImgBlur_005L2, ...
                                              kernel_BSK, 'L2', 'MS', Params);
tbsk_005L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_005L2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_005L2), tbsk_005L2n0));
end

%-- BSK l2-VTV

Params      = SetParams;
Params.beta = 0.0025*max(lenImgBlur(:));

tic;
[BSKL2_lenImgBlur_005L2, V_MSTV_05L2] = MainRestoration(lenImgBlur_005L2, ...
                                              kernel_BSK, 'L2', 'L1', Params);
tbsk_005L2n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( BSKL2_lenImgBlur_005L2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, BSKL2_lenImgBlur_005L2), tbsk_005L2n1));
end

end % _END_ if(BKS_CODE)

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

%noise level: 0.01

%-- IRN
lambda  = 0.0005;

pars = irntvInputPars('l2tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 3;
%  pars.pcgtol_ini   = 1e-4;
pars.U0           = lenImgBlur_001L2;

tic;
IRN_lenImgBlur_001L2 = irntv(lenImgBlur_001L2, KC_BSK, lambda, pars);
tirn_001L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_001L2) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_001L2), tirn_001L2n0));
end

if(BKS_CODE)
%-- BSK MSTV (Mumford-Shah TV)

Params      = SetParams;
Params.beta = 0.0001;

tic;
[MSTV_lenImgBlur_001L2, V_MSTV_001L2] = ...
  MainRestoration(Normalize(lenImgBlur_001L2), kernel_BSK, 'L2', 'MS', Params);
tbsk_001L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_001L2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_001L2), tbsk_001L2n0));
end

%-- BSK L2-VTV

Params      = SetParams;
Params.beta = 0.0001;

tic;
[BSKL2_lenImgBlur_001L2, V_MSTV_001L2] = ...
  MainRestoration(Normalize(lenImgBlur_001L2), kernel_BSK, 'L2', 'L1', Params);
tbsk_001L2n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( BSKL2_lenImgBlur_001L2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, BSKL2_lenImgBlur_001L2), tbsk_001L2n1));
end

end % _END_ if(BKS_CODE)

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

%noise level: sqrt(1e-5)   BSK example

%-- IRN
lambda  = 0.0001;
pars = irntvInputPars('l2tv');

pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops        = 3;
%  pars.pcgtol_ini   = 1e-4;
pars.U0           = lenImgBlur_bskL2;

tic;
IRN_lenImgBlur_bskL2 = irntv(lenImgBlur_bskL2, KC_BSK, lambda, pars);
tirn_bskL2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_lenImgBlur_bskL2) );
  axis image; axis off;
  title(sprintf('Deconvolved Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, IRN_lenImgBlur_bskL2), tirn_bskL2n0));
end

if(BKS_CODE)

%-- BSK MSTV (Mumford-Shah TV)

Params      = SetParams;
Params.beta = 0.00001;

tic;
[MSTV_lenImgBlur_bskL2, V_MSTV_bskL2] = ...
  MainRestoration(Normalize(lenImgBlur_bskL2), kernel_BSK, 'L2', 'MS', Params);
tbsk_bskL2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( MSTV_lenImgBlur_bskL2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, MSTV_lenImgBlur_bskL2), tbsk_bskL2n0));
end

%-- BSK l2-VTV

Params      = SetParams;
Params.beta = 0.00001;

tic;
[BSKL2_lenImgBlur_bskL2, V_MSTV_bskL2] = ...
  MainRestoration(Normalize(lenImgBlur_bskL2), kernel_BSK, 'L2', 'L1', Params);
tbsk_bskL2n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( BSKL2_lenImgBlur_bskL2 );
  axis image; axis off;
  title(sprintf('Deconvolved Image - MSTV. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(lenImg, BSKL2_lenImgBlur_bskL2), tbsk_bskL2n1));
end

end % _END_ if(BKS_CODE)

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

if(ICIP_FLAG == 0)

  disp('L2 Deconvolve Vector TV');
  disp(' ');
  disp('                        SNR (db)                    Time (s)');
  disp(' Img      Noise    VTV-IRN  L2-MS(BSK)   BSK-L2          VTV IRN   L2-MS(BKS)  BSK-L2');
  disp(' ');
  if(BKS_CODE)
  disp(sprintf('Lenna      0.05      %5.1f     %5.1f     %5.1f           %5.1f      %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_005L2), snr(lenImg, MSTV_lenImgBlur_005L2), snr(lenImg, BSKL2_lenImgBlur_005L2), ...
     tirn_005L2n0, tbsk_005L2n0, tbsk_005L2n1));
  disp(sprintf('Lenna      0.01      %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_001L2), snr(lenImg, MSTV_lenImgBlur_001L2), snr(lenImg, BSKL2_lenImgBlur_001L2), ...
     tirn_001L2n0, tbsk_001L2n0, tbsk_001L2n1));
  disp(sprintf('Lenna   sqrt(1e-5)   %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_bskL2), snr(lenImg, MSTV_lenImgBlur_bskL2), snr(lenImg, BSKL2_lenImgBlur_bskL2), ...
     tirn_bskL2n0, tbsk_bskL2n0, tbsk_bskL2n1));
  else
  disp(sprintf('Lenna      0.05      %5.1f     %5.1f     %5.1f           %5.1f      %5.1f    %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_005L2), NaN, NaN, ...
     tirn_005L2n0, NaN, NaN));
  disp(sprintf('Lenna      0.01      %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_001L2), NaN, NaN, ...
     tirn_001L2n0, NaN, NaN));
  disp(sprintf('Lenna   sqrt(1e-5)   %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f', ...
     snr(lenImg, IRN_lenImgBlur_bskL2), NaN, NaN, ...
     tirn_bskL2n0, NaN, NaN));
  end % _END_ if(BKS_CODE)

else

  str = sprintf('L2 Deconvolve Vector TV\n\n');
  str_all = [str_all str];
  str = sprintf('                        SNR (db)                    Time (s)\n');
  str_all = [str_all str];
  str = sprintf(' Img      Noise    VTV-IRN  L2-MS(BSK)   BSK-L2          VTV IRN   L2-MS(BKS)  BSK-L2\n\n');
  str_all = [str_all str];

  if(BKS_CODE)
  str = sprintf('Lena       0.05      %5.1f     %5.1f     %5.1f           %5.1f      %5.1f    %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_005L2), snr(lenImg, MSTV_lenImgBlur_005L2), snr(lenImg, BSKL2_lenImgBlur_005L2), ...
     tirn_005L2n0, tbsk_005L2n0, tbsk_005L2n1);
  str_all = [str_all str];
  str = sprintf('Lena       0.01      %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_001L2), snr(lenImg, MSTV_lenImgBlur_001L2), snr(lenImg, BSKL2_lenImgBlur_001L2), ...
     tirn_001L2n0, tbsk_001L2n0, tbsk_001L2n1);
  str_all = [str_all str];
  str = sprintf('Lena    sqrt(1e-5)   %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f\n\n\n', ...
     snr(lenImg, IRN_lenImgBlur_bskL2), snr(lenImg, MSTV_lenImgBlur_bskL2), snr(lenImg, BSKL2_lenImgBlur_bskL2), ...
     tirn_bskL2n0, tbsk_bskL2n0, tbsk_bskL2n1);
  str_all = [str_all str];
  else
  str = sprintf('Lena       0.05      %5.1f     %5.1f     %5.1f           %5.1f      %5.1f    %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_005L2), NaN, NaN, ...
     tirn_005L2n0, NaN, NaN);
  str_all = [str_all str];
  str = sprintf('Lena       0.01      %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f\n', ...
     snr(lenImg, IRN_lenImgBlur_001L2), NaN, NaN, ...
     tirn_001L2n0, NaN, NaN);
  str_all = [str_all str];
  str = sprintf('Lena    sqrt(1e-5)   %5.1f     %5.1f      %5.1f          %5.1f      %5.1f     %5.1f\n\n\n', ...
     snr(lenImg, IRN_lenImgBlur_bskL2), NaN, NaN, ...
     tirn_bskL2n0, NaN, NaN);
  str_all = [str_all str];
  end % _END_ if(BKS_CODE)

end

end % _END_ if( strcmp(example,'l2deconv') || strcmp(example,'icp09') )

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

if( strcmp(example,'l1denoise') || strcmp(example,'icip09') )

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       L1 Denoise        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%

%noise level: 0.1

%-- IRN
lambda  = 1.1;

pars = irntvInputPars('l1tv');

pars.pcgtol_ini = 1e-4;
pars.epsF       = 1e-2;
pars.epsR       = 1e-4;
pars.loops      = 2;

%-- peppers
tic;
IRN_pepImg_01L1 = irntv(pepImg_01L1, [], lambda, pars);
tirn_01L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_pepImg_01L1) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, IRN_pepImg_01L1), tirn_01L1n0));
end

%-- mandrill
tic;
IRN_mdrilImg_01L1 = irntv(mdrilImg_01L1, [], lambda, pars);
tirn_01L1n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_mdrilImg_01L1) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, IRN_mdrilImg_01L1), tirn_01L1n1));
end

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

%noise level: 0.3

%-- IRN
lambda  = 1.2;

pars = irntvInputPars('l1tv');

pars.pcgtol_ini = 1e-4;
pars.epsF       = 1e-2;
pars.epsR       = 1e-4;
pars.loops      = 2;

%-- peppers
tic;
IRN_pepImg_03L1 = irntv(pepImg_03L1, [], lambda, pars);
tirn_03L1n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_pepImg_03L1) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, IRN_pepImg_03L1), tirn_03L1n0));
end

%-- mandrill

tic;
IRN_mdrilImg_03L1 = irntv(mdrilImg_03L1, [], lambda, pars);
tirn_03L1n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_mdrilImg_03L1) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, IRN_mdrilImg_03L1), tirn_03L1n1));
end

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

if(ICIP_FLAG == 0)

  disp('L1 Denoise Vector TV (Vector IRN algorithm)');
  disp(' ');
  disp('                   SNR (db)          Time (s)');
  disp(' Img      Noise    VTV IRN           VTV IRN');
  disp(' ');
  disp(sprintf('Peppers    0.1       %5.1f            %5.1f  ', ...
      snr(pepImg, IRN_pepImg_01L1), tirn_01L1n0));
  disp(sprintf('           0.3       %5.1f            %5.1f  ', ...
      snr(pepImg, IRN_pepImg_03L1), tirn_03L1n0));
  disp(sprintf('Mandrill   0.1       %5.1f            %5.1f  ', ...
      snr(mdrilImg, IRN_mdrilImg_01L1), tirn_01L1n1));
  disp(sprintf('           0.3       %5.1f            %5.1f  ', ...
      snr(mdrilImg, IRN_mdrilImg_03L1), tirn_03L1n1));

else

  str = sprintf('L1 Denoise Vector TV (Vector IRN algorithm)\n\n');
  str_all = [str_all str];
  str = sprintf('                   SNR (db)          Time (s)\n');
  str_all = [str_all str];
  str = sprintf(' Img      Noise    VTV IRN           VTV IRN\n\n');
  str_all = [str_all str];

  str = sprintf('Peppers    0.1       %5.1f            %5.1f  \n', ...
      snr(pepImg, IRN_pepImg_01L1), tirn_01L1n0);
  str_all = [str_all str];
  str = sprintf('           0.3       %5.1f            %5.1f  \n', ...
      snr(pepImg, IRN_pepImg_03L1), tirn_03L1n0);
  str_all = [str_all str];
  str = sprintf('Mandrill   0.1       %5.1f            %5.1f  \n', ...
      snr(mdrilImg, IRN_mdrilImg_01L1), tirn_01L1n1);
  str_all = [str_all str];
  str = sprintf('           0.3       %5.1f            %5.1f  \n\n\n', ...
      snr(mdrilImg, IRN_mdrilImg_03L1), tirn_03L1n1);
  str_all = [str_all str];

end

end % _END_ if( strcmp(example,'l1denoise') || strcmp(example,'icip09') )

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

if( strcmp(example,'l2denoise') || strcmp(example,'icip09') )

%%%%%%%%%%%%%%%%%%%%%%%%%%%
%       L2 Denoise        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%

%noise level: 0.1

%-- IRN
lambda  = 0.3;

pars = irntvInputPars('l2tv');

pars.pcgtol_ini = 1e-4;
%  pars.epsF       = 1e-1;
%  pars.epsR       = 1e-2;
pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops      = 1;

tic;
IRN_pepImg_01L2 = irntv(pepImg_01L2, [], lambda, pars);
tirn_01L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_pepImg_01L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, IRN_pepImg_01L2), tirn_01L2n0));
end

if(BnG_CODE)
%% http://www.mathworks.fr/matlabcentral/fileexchange/16236
%%  Pascal Getreuer based on X. Bresson and T.F. Chan,
%%  "Fast Minimization of the Vectorial Total Variation Norm and Applications
%%  to Color Image Processing", CAM Report 07-25.

lambda  = 0.15;

tic;
BnG_pepImg_01L2 = tvdenoise(pepImg_01L2, 1/lambda);
tirn_01L2n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(BnG_pepImg_01L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - BnG. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, BnG_pepImg_01L2), tirn_01L2n1));
end

end % _END_ if(BnG_CODE)

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

%-- IRN
lambda  = 0.3;

pars = irntvInputPars('l2tv');

pars.pcgtol_ini = 1e-4;
%  pars.epsF       = 1e-1;
%  pars.epsR       = 1e-2;
pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops      = 1;

tic;
IRN_mdrilImg_01L2 = irntv(mdrilImg_01L2, [], lambda, pars);
tirn_01L2n2 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_mdrilImg_01L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, IRN_mdrilImg_01L2), tirn_01L2n2));
end

if(BnG_CODE)
%% http://www.mathworks.fr/matlabcentral/fileexchange/16236
%%  Pascal Getreuer based on X. Bresson and T.F. Chan,
%%  "Fast Minimization of the Vectorial Total Variation Norm and Applications
%%  to Color Image Processing", CAM Report 07-25.

lambda  = 0.15;

tic;
BnG_mdrilImg_01L2 = tvdenoise(mdrilImg_01L2, 1/lambda);
tirn_01L2n3 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(BnG_mdrilImg_01L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - BnG. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, BnG_mdrilImg_01L2), tirn_01L2n3));
end

end % _END_ if(BnG_CODE)

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

%noise level: 0.05

%-- IRN
lambda  = 0.1;

pars = irntvInputPars('l2tv');

pars.pcgtol_ini = 1e-4;
%  pars.epsF       = 1e-1;
%  pars.epsR       = 1e-2;
pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops      = 1;

tic;
IRN_pepImg_005L2 = irntv(pepImg_005L2, [], lambda, pars);
tirn_005L2n0 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_pepImg_005L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, IRN_pepImg_005L2), tirn_005L2n0));
end

if(BnG_CODE)
%% http://www.mathworks.fr/matlabcentral/fileexchange/16236
%%  Pascal Getreuer based on X. Bresson and T.F. Chan,
%%  "Fast Minimization of the Vectorial Total Variation Norm and Applications
%%  to Color Image Processing", CAM Report 07-25.

lambda  = 0.05;

tic;
BnG_pepImg_005L2 = tvdenoise(pepImg_005L2, 1/lambda);
tirn_005L2n1 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(BnG_pepImg_005L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - BnG. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(pepImg, BnG_pepImg_005L2), tirn_005L2n1));
end

end % _END_ if(BnG_CODE)

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

%-- IRN
lambda  = 0.1;

pars = irntvInputPars('l2tv');

pars.pcgtol_ini = 1e-4;
%  pars.epsF       = 1e-1;
%  pars.epsR       = 1e-2;
pars.adapt_epsR   = 1;
pars.epsR_cutoff  = 0.01;
pars.adapt_epsF   = 1;
pars.epsF_cutoff  = 0.05;
pars.loops      = 1;

tic;
IRN_mdrilImg_005L2 = irntv(mdrilImg_005L2, [], lambda, pars);
tirn_005L2n2 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(IRN_mdrilImg_005L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - Vector IRN. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, IRN_mdrilImg_005L2), tirn_005L2n2));
end

if(BnG_CODE)
%% http://www.mathworks.fr/matlabcentral/fileexchange/16236
%%  Pascal Getreuer based on X. Bresson and T.F. Chan,
%%  "Fast Minimization of the Vectorial Total Variation Norm and Applications
%%  to Color Image Processing", CAM Report 07-25.

lambda  = 0.05;

tic;
BnG_mdrilImg_005L2 = tvdenoise(mdrilImg_005L2, 1/lambda);
tirn_005L2n3 = toc;

if(SHOW_IMGS)
  figure; imagesc( Normalize(BnG_mdrilImg_005L2) );
  axis image; axis off;
  title(sprintf('Denoised Image - BnG. SNR: %4.1fdB.\n Time %4.1f sec', ...
               snr(mdrilImg, BnG_mdrilImg_005L2), tirn_005L2n3));
end

end % _END_ if(BnG_CODE)

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

if(ICIP_FLAG == 0)

  disp('L2 Denoise Vector TV (Vector IRN algorithm)');
  disp(' ');
  disp('                         SNR (db)                    Time (s)');
  disp(' Img      Noise   VTV-IRN   bresson-2008-fast     VTV IRN   bresson-2008-fast');
  disp(' ');
  if(BnG_CODE)
  disp(sprintf('Peppers,   0.1      %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(pepImg, IRN_pepImg_01L2), snr(pepImg, BnG_pepImg_01L2), ...
      tirn_01L2n0, tirn_01L2n1));
  disp(sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(pepImg, IRN_pepImg_005L2), snr(pepImg, BnG_pepImg_005L2), ...
      tirn_005L2n0, tirn_005L2n1));
  disp(sprintf('Mandrill,  0.1      %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(mdrilImg, IRN_mdrilImg_01L2), snr(mdrilImg, BnG_mdrilImg_01L2), ...
      tirn_01L2n2, tirn_01L2n3));
  disp(sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(mdrilImg, IRN_mdrilImg_005L2), snr(mdrilImg, BnG_mdrilImg_005L2), ...
      tirn_005L2n2, tirn_005L2n3));
  else
  disp(sprintf('Peppers,   0.1      %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(pepImg, IRN_pepImg_01L2), NaN, ...
      tirn_01L2n0, NaN));
  disp(sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(pepImg, IRN_pepImg_005L2), NaN, ...
      tirn_005L2n0, NaN));
  disp(sprintf('Mandrill,  0.1      %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(mdrilImg, IRN_mdrilImg_01L2), NaN, ...
      tirn_01L2n2, NaN));
  disp(sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f', ...
      snr(mdrilImg, IRN_mdrilImg_005L2), NaN, ...
      tirn_005L2n2, NaN));
  end % _END_ if(BnG_CODE)

else

  str = sprintf('L2 Denoise Vector TV (Vector IRN algorithm)\n\n');
  str_all = [str_all str];
  str = sprintf('                         SNR (db)                    Time (s)\n');
  str_all = [str_all str];
  str = sprintf(' Img      Noise   VTV-IRN   bresson-2008-fast     VTV IRN   bresson-2008-fast\n\n');
  str_all = [str_all str];

  if(BnG_CODE)
  str = sprintf('Peppers,   0.1      %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(pepImg, IRN_pepImg_01L2), snr(pepImg, BnG_pepImg_01L2), ...
      tirn_01L2n0, tirn_01L2n1);
  str_all = [str_all str];
  str = sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(pepImg, IRN_pepImg_005L2), snr(pepImg, BnG_pepImg_005L2), ...
      tirn_005L2n0, tirn_005L2n1);
  str_all = [str_all str];
  str = sprintf('Mandrill,  0.1      %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(mdrilImg, IRN_mdrilImg_01L2), snr(mdrilImg, BnG_mdrilImg_01L2), ...
      tirn_01L2n2, tirn_01L2n3);
  str_all = [str_all str];
  str = sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f\n\n\n', ...
      snr(mdrilImg, IRN_mdrilImg_005L2), snr(mdrilImg, BnG_mdrilImg_005L2), ...
      tirn_005L2n2, tirn_005L2n3);
  str_all = [str_all str];
  else
  str = sprintf('Peppers,   0.1      %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(pepImg, IRN_pepImg_01L2), NaN, ...
      tirn_01L2n0, NaN);
  str_all = [str_all str];
  str = sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(pepImg, IRN_pepImg_005L2), NaN, ...
      tirn_005L2n0, NaN);
  str_all = [str_all str];
  str = sprintf('Mandrill,  0.1      %5.1f      %5.1f                %5.1f         %5.1f\n', ...
      snr(mdrilImg, IRN_mdrilImg_01L2), NaN, ...
      tirn_01L2n2, NaN);
  str_all = [str_all str];
  str = sprintf('           0.05     %5.1f      %5.1f                %5.1f         %5.1f\n\n\n', ...
      snr(mdrilImg, IRN_mdrilImg_005L2), NaN, ...
      tirn_005L2n2, NaN);
  str_all = [str_all str];
  end % _END_ if(BnG_CODE)

end

end % _END_ if( strcmp(example,'l2denoise') || strcmp(example,'icp09') )

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

if(ICIP_FLAG == 1)

  disp(str_all);
end


function value = r8_sin ( x )

%*****************************************************************************80
%
%% R8_SIN evaluates the sine of an R8 argument.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2011
%
%  Author:
%
%    Original FORTRAN77 version by Wayne Fullerton.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Wayne Fullerton,
%    Portable Special Function Routines,
%    in Portability of Numerical Software,
%    edited by Wayne Cowell,
%    Lecture Notes in Computer Science, Volume 57,
%    Springer 1977,
%    ISBN: 978-3-540-08446-4,
%    LC: QA297.W65.
%
%  Parameters:
%
%    Input, real X, the argument.
%
%    Output, real VALUE, the sine of X.
%
  persistent ntsn
  persistent pi2rec
  persistent pihi
  persistent pilo
  persistent pirec
  persistent sincs
  persistent xmax
  persistent xsml
  persistent xwarn

  pi2rec = 0.63661977236758134307553505349006;
  pihi = 3.140625;
  pilo = 9.6765358979323846264338327950288E-04;
  pirec = 0.31830988618379067153776752674503;

  if ( isempty ( ntsn ) )

    sincs = [ ...
     -0.374991154955873175839919279977323464, ...
     -0.181603155237250201863830316158004754, ...
     +0.005804709274598633559427341722857921, ...
     -0.000086954311779340757113212316353178, ...
     +0.000000754370148088851481006839927030, ...
     -0.000000004267129665055961107126829906, ...
     +0.000000000016980422945488168181824792, ...
     -0.000000000000050120578889961870929524, ...
     +0.000000000000000114101026680010675628, ...
     -0.000000000000000000206437504424783134, ...
     +0.000000000000000000000303969595918706, ...
     -0.000000000000000000000000371357734157, ...
     +0.000000000000000000000000000382486123, ...
     -0.000000000000000000000000000000336623, ...
     +0.000000000000000000000000000000000256 ]';

    ntsn = r8_inits ( sincs, 15, 0.1 * r8_mach ( 3 ) );
    xsml = sqrt ( 2.0 * r8_mach ( 3 ) );
    xmax = 1.0 / r8_mach( 4 );
    xwarn = sqrt ( xmax );

  end

  y = abs ( x );

  if ( xmax < y )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8_SIN - Warning!\n' );
    fprintf ( 1, '  No precision because |X| is big.\n' );
    value = 0.0;
    return
  end

  if ( xwarn < y )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R8_SIN - Warning!\n' );
    fprintf ( 1, '  Answer < half precision because |X| is big.\n' );
  end

  value = x;
  if ( y < xsml )
    return
  end

  xn = r8_aint ( y * pirec + 0.5 );
  n2 = r8_aint ( mod ( xn, 2.0 ) + 0.5 );

  sgn = x;
  if ( n2 ~= 0 )
    sgn = - sgn;
  end

  f = ( y - xn * pihi ) - xn * pilo;

  xn = 2.0 * ( f * pi2rec ) * ( f * pi2rec ) - 1.0;

  value = f + f * r8_csevl ( xn, sincs, ntsn );

  if ( sgn < 0.0 )
    value = - value;
  end

  if ( value < - 1.0 )
    value = - 1.0;
  elseif ( 1.0 < value )
    value = + 1.0;
  end

  return
end


function value = r4_sqrt ( x )

%*****************************************************************************80
%
%% R4_SQRT computes the square root of an R4.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 September 2011
%
%  Author:
%
%    Original FORTRAN77 version by Wayne Fullerton.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Wayne Fullerton,
%    Portable Special Function Routines,
%    in Portability of Numerical Software,
%    edited by Wayne Cowell,
%    Lecture Notes in Computer Science, Volume 57,
%    Springer 1977,
%    ISBN: 978-3-540-08446-4,
%    LC: QA297.W65.
%
%  Parameters:
%
%    Input, real X, the number whose square root is desired.
%
%    Output, real VALUE, the square root of X.
%
  persistent niter
  persistent sqrt2

  sqrt2 = [ 0.70710678118654752, 1.0, 1.41421356237309505 ]';

  if ( isempty ( niter ) )
    niter = 1.443 * r4_log ( - 0.104 * r4_log ( 0.1 * r4_mach ( 3 ) ) ) + 1.0;
  end

  if ( x < 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'R4_SQRT - Fatal error!\n' );
    fprintf ( 1, '  X < 0.0\n' );
    error ( 'R4_SQRT - Fatal error!' )
  elseif ( x == 0.0 )
    value = 0.0;
  else

    [ y, n ] = r4_upak ( x );
    ixpnt = floor ( n / 2 );
    irem = floor ( n - 2 * ixpnt + 2 );
    value = 0.261599 + y * ( 1.114292 + y * ( -0.516888 + y * 0.141067 ) );

    for iter = 1 : niter
      value = value + 0.5 * ( y - value * value ) / value;
    end

    value = r4_pak ( sqrt2(irem) * value, ixpnt );

  end

  return
end


function [w,run] = train_bfgs(x,w,lambda)
% TRAIN_BFGS    Train a logistic regression model by BFGS.
%
% W = TRAIN_BFGS(X,W) returns maximum-likelihood weights given data and a
% starting guess.
% Data is columns of X, each column already scaled by the output (+1 or -1).
% W is the starting guess for the parameters (a column).

% Written by Thomas P Minka

if nargin < 3
  lambda = 0;
end
flops(0);
[d,n] = size(x);
old_g = zeros(size(w));
ih = eye(d);
for iter = 1:1000
  old_w = w;
  % s1 = 1-sigma
  s1 = 1./(1+exp(w'*x));
  g = x*s1' - lambda*w;
  flops(flops + flops_mul(w',x) + n*(flops_exp+2) + flops_mul(x,s1') + 2*d);
  if iter > 1
    dw = w - prev_w;
    dg = g - old_g;
    dwdg = dw'*dg;
    ihdg = ih*dg;
    b = 1 + (dg'*ihdg)/dwdg;
    ihdgdw = ihdg*dw';
    ih = ih + (b*dw*dw' - ihdgdw' - ihdgdw)/dwdg;
    flops(flops + d + d + flops_mul(dw',dg) + flops_mul(ih,dg) + ...
	flops_mul(dg',ihdg)+2 + flops_mul(ihdg,dw') + ...
	flops_mul(b,dw) + flops_mul(dw,dw') + 4*d*d);
  end
  u = -ih*g;
  flops(flops + flops_mul(ih,g));
  prev_w = w;

  % line search along u
  ug = u'*g;
  ux = u'*x;
  a = s1.*(1-s1);
  uhu = (ux.^2)*a' + lambda*(u'*u);
  w = w + (ug/uhu)*u;
  old_g = g;
  flops(flops + flops_mul(u',g) + flops_mul(u',x) + 2*n + ...
      n+flops_mul(1,n,1) + 2*d+1);
  if lambda > 0
    flops(flops + 1+flops_mul(u',u));
  end

  run.w(:,iter) = w;
  run.flops(iter) = flops;
  run.e(iter) = logProb(x,w) -0.5*lambda*w'*w;

  if max(abs(w - old_w)) < 1e-5
    break
  end
end
figure(2)
plot(run.e)
if iter == 1000
  warning('not enough iters')
end


function N = tangentspacefactory(M, x)
% Returns a manifold structure representing the tangent space to M at x.
%
% N = tangentspacefactory(M, x)
%
% N defines a (linear) manifold that is the tangent space to M at x. Points
% are represented as tangent vectors to M at x. Tangent vectors are also
% represented as tangent vectors to M at x.
%
% This is chiefly useful to solve optimization problems involving tangent
% vectors to M at x, which notably comes up when solving linear systems
% involving, for example, the Hessian of the cost on M at x. The Riemannian
% (actually, Euclidean) structure on N is that of the tangent space to M,
% that is, the inner product is inherited.
%
% See also: preconhessiansolve

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, April 9, 2015.
% Contributors:
% Change log:

    % N is the manifold we build. y will be a point on N, thus also a
    % tangent vector to M at x. This is a typical Euclidean space, hence it
    % will be easy to describe in terms of the tools available for M.
    N = struct();

    % u, u1 and u2 will be tangent vectors to N at y. The tangent space to
    % N at y is the tangent space to M at x, thus u, u1 and u2 are also
    % tangent vectors to M at x.

    N.dim   = @() M.dim();
    N.inner = @(y, u1, u2) M.inner(x, u1, u2);
    N.norm  = @(y, u) M.norm(x, u);
    N.proj  = M.proj;
    N.typicaldist = @() N.dim();
    N.tangent = @(y, u) u;
    N.egrad2rgrad = @(x, g) g;
    N.ehess2rhess = @(x, eg, eh, d) eh;
    N.exp = @exponential;
    N.retr = @exponential;
    N.log = @(y1, y2) M.lincomb(x, 1, y2, -1, y1);
    N.pairmean = @(y1, y2) M.lincomb(x, 0.5, y1, 0.5, y2);
    N.rand = @() M.randvec(x);
    N.randvec = @(y) M.randvec(x);
    N.zerovec = M.zerovec;
    N.lincomb = M.lincomb;
    N.transp = @(y1, y2, u) u;
    N.hash = @(y) ['z' hashmd5(M.vec(x, y))];

    % In a Euclidean space, the exponential is merely the sum: y + tu.
    function yy = exponential(y, u, t)
        if nargin == 2
            t = 1;
        end
        yy = M.lincomb(x, 1, y, t, u);
    end

end


%This Matlab script can be used to reproduce Figure 4.10 in the monograph:
%
%Emil Bjornson, Jakob Hoydis and Luca Sanguinetti (2017),
%"Massive MIMO Networks: Spectral, Energy, and Hardware Efficiency",
%Foundations and Trends in Signal Processing: Vol. 11, No. 3-4,
%pp. 154-655. DOI: 10.1561/2000000093.
%
%For further information, visit: https://www.massivemimobook.com
%
%This is version 1.0 (Last edited: 2017-11-04)
%
%License: This code is licensed under the GPLv2 license. If you in any way
%use this code for research that results in publications, please cite our
%monograph as described above.

%Empty workspace and close figures
close all;
clear;

%Define the range of BS antennas
Mvalues = [1 10 100];

%Angular standard deviation in the local scattering model (in degrees)
ASDdeg = 10;

%Nominal angle of the desired UE
thetaDesired = pi/6;

%Range of nominal angles of the interfering UE
varphiInterfererDegrees = -180:1:180;
varphiInterfererRadians = varphiInterfererDegrees*(pi/180);

%Define the antenna spacing (in number of wavelengths)
antennaSpacing = 1/2; %Half wavelength distance

%Define the range of the effective SNR in (3.13) for the desired UE
SNR1dB = 10;
SNR1 = 10.^(SNR1dB/10);

%Define the range of the effective SNR in (3.13) for the interfering UE
SNR2dB = SNR1dB-10;
SNR2 = 10.^(SNR2dB/10);

%Preallocate matrices for storing the simulation results
relativeInterferenceCoherent = zeros(length(varphiInterfererRadians),length(thetaDesired),length(Mvalues));

%Compute correlation matrix of the desired UE
R1 = functionRlocalscattering(max(Mvalues),thetaDesired,ASDdeg,antennaSpacing);

%% Go through all angles of the interfering UE
for n = 1:length(varphiInterfererRadians)

    %Compute correlation matrix of the interfering UE
    R2 = functionRlocalscattering(max(Mvalues),varphiInterfererRadians(n),ASDdeg,antennaSpacing);

    %Go through all numbers of antennas
    for m = 1:length(Mvalues)

        R1m = R1(1:Mvalues(m),1:Mvalues(m));
        R2m = R2(1:Mvalues(m),1:Mvalues(m));

        %Compute numerator and denominator of the ratio between desired
        %signal term and coherent interference term in (4.17)
        numerator = SNR2^2*abs(trace(R1m*((SNR1*R1m+SNR2*R2m+eye(Mvalues(m)))\R2m)))^2;
        denominator = SNR1^2*abs(trace(R1m*((SNR1*R1m+SNR2*R2m+eye(Mvalues(m)))\R1m)))^2;

        relativeInterferenceCoherent(n,m) = numerator/denominator;

    end

end

%% Plot the simulation results
figure;
hold on; box on;

plot(varphiInterfererDegrees,10*log10(relativeInterferenceCoherent(:,1)),'k-','LineWidth',1);
plot(varphiInterfererDegrees,10*log10(relativeInterferenceCoherent(:,2)),'r--','LineWidth',1);
plot(varphiInterfererDegrees,10*log10(relativeInterferenceCoherent(:,3)),'b-.','LineWidth',1);

xlabel('Angle of interfering UE [degree]');
ylabel('Coherent interf. power over signal power [dB]');
xlim([-180 180]);
ylim([-40 -10]);

legend('M=1','M=10','M=100','Location','NorthWest');


function [ n_data, x, y, fxy ] = beta_log_values ( n_data )

%*****************************************************************************80
%
%% BETA_LOG_VALUES returns some values of the logarithm of the Beta function.
%
%  Discussion:
%
%    In Mathematica, the function can be evaluated by:
%
%      Log[Beta[x]]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 August 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Wolfram Media / Cambridge University Press, 1999.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
%    first call.  On each call, the routine increments N_DATA by 1, and
%    returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real X, Y, the arguments of the function.
%
%    Output, real FXY, the value of the function.
%
  n_max = 17;

  fxy_vec = [ ...
      0.1609437912434100E+01, ...
      0.9162907318741551E+00, ...
      0.5108256237659907E+00, ...
      0.2231435513142098E+00, ...
      0.1609437912434100E+01, ...
      0.9162907318741551E+00, ...
      0.0000000000000000E+00, ...
     -0.1791759469228055E+01, ...
     -0.3401197381662155E+01, ...
     -0.4941642422609304E+01, ...
     -0.6445719819385578E+01, ...
     -0.3737669618283368E+01, ...
     -0.5123963979403259E+01, ...
     -0.6222576268071369E+01, ...
     -0.7138866999945524E+01, ...
     -0.7927324360309794E+01, ...
     -0.9393661429103221E+01 ];

  x_vec = [ ...
     0.2E+00, ...
     0.4E+00, ...
     0.6E+00, ...
     0.8E+00, ...
     1.0E+00, ...
     1.0E+00, ...
     1.0E+00, ...
     2.0E+00, ...
     3.0E+00, ...
     4.0E+00, ...
     5.0E+00, ...
     6.0E+00, ...
     6.0E+00, ...
     6.0E+00, ...
     6.0E+00, ...
     6.0E+00, ...
     7.0E+00 ];

  y_vec = [ ...
     1.0E+00, ...
     1.0E+00, ...
     1.0E+00, ...
     1.0E+00, ...
     0.2E+00, ...
     0.4E+00, ...
     1.0E+00, ...
     2.0E+00, ...
     3.0E+00, ...
     4.0E+00, ...
     5.0E+00, ...
     2.0E+00, ...
     3.0E+00, ...
     4.0E+00, ...
     5.0E+00, ...
     6.0E+00, ...
     7.0E+00 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    x = 0.0;
    y = 0.0;
    fxy = 0.0;
  else
    x = x_vec(n_data);
    y = y_vec(n_data);
    fxy = fxy_vec(n_data);
  end

  return
end


% 机动车刹车距离
%% 插值数据处理
clear; clc;
v = 20 : 10 : 150;  % 速度，插值节点，单位：千米/小时
d2=[3.15,7.08,12.59,19.68,28.34,38.57,50.4,63.75,...
    78.71,95.22,113.29,132.93,154.12,176.87];  % 制动距离，插值节点
vi = 20 : 1 : 150;  % 速度，待插值点
d2i = interp1(v, d2, vi, 'spline');  % 样条插值得到的制动距离

%% 根据某驾驶员的实际视力和视觉习惯，其驾驶时的有效视距为120m，则其在该路面行车时，时速最高不能超过多少(结果取整)?
dl = 120;  % 某路段的有效视距，单位：米
time = 10;  % 驾驶员的平均反应时间，单位：秒
vs = vi * 1000 / 3600; % 速度，插值节点，单位：米/秒
d1 = vs * time; % 驾驶员反应距离
d3 = 10;  % 预留安全距离，单位：米
di = d1 + d2i + d3;  % 有效视距 = 驾驶员反应距离 + 制动距离 + 预留安全距离
x = abs(di - dl);   % 有效视距差的绝对值
[y,i]=sort(x);    % 排序，i是排序后元素的序号
fprintf('有效视距%.4f米某路段的最高时速: %.f千米/小时\n',dl,vi(i(1)));
plot(vi,di,vi(i(1)),di(i(1)),'rp');

%% 若以表中数据为参考，设计一条最高时速为125km/h的高速公路，则设计人员应该保 证驾驶者在公路上任一点的可视距离为多少米?
v_max = 125; % 最高限速，单位：千米/小时
i = find(vi - 125 == 0);
fprintf('最高时速%.4f千米/小时的路段需保证有效视距: %.4f米\n', v_max, di(i));


function sample = SamplePose(P, G, label)

% sample from the distribution specified by P and G,
% label == 0: class label unknown
% label == k: class label = k; k=1,2,3, ...
%
% Copyright (C) Daphne Koller, Stanford Univerity, 2012

sample = zeros(10,3);

if label == 0
    k = SampleMultinomial(P.c); % sample label using P.c
else
    k = label;
end

visited = zeros(10,1);

while sum(visited) < 10

    for i=1:10 % for each body part

        par = G(i,2); % parent body part, if exists

        if G(i,1) == 0 % parametrized by (2),(3),(4)

            muy = P.clg(i).mu_y(k);
            mux = P.clg(i).mu_x(k);
            muangle = P.clg(i).mu_angle(k);
            sample(i,1) = SampleGaussian(muy, P.clg(i).sigma_y(k));
            sample(i,2) = SampleGaussian(mux, P.clg(i).sigma_x(k));
            sample(i,3) = SampleGaussian(muangle, P.clg(i).sigma_angle(k));
            visited(i) = 1;

        elseif G(i,1) == 1 % parametrized by (5),(6),(7)

            if visited(par)

                muy = P.clg(i).theta(k,1) + ...
                    P.clg(i).theta(k,2) * sample(par,1) + ...
                    P.clg(i).theta(k,3) * sample(par,2) + ...
                    P.clg(i).theta(k,4) * sample(par,3);
                mux = P.clg(i).theta(k,5) + ...
                    P.clg(i).theta(k,6) * sample(par,1) + ...
                    P.clg(i).theta(k,7) * sample(par,2) + ...
                    P.clg(i).theta(k,8) * sample(par,3);
                muangle = P.clg(i).theta(k,9) + ...
                    P.clg(i).theta(k,10) * sample(par,1) + ...
                    P.clg(i).theta(k,11) * sample(par,2) + ...
                    P.clg(i).theta(k,12) * sample(par,3);
                sample(i,1) = SampleGaussian(muy, P.clg(i).sigma_y(k));
                sample(i,2) = SampleGaussian(mux, P.clg(i).sigma_x(k));
                sample(i,3) = SampleGaussian(muangle, P.clg(i).sigma_angle(k));
                visited(i) = 1;
            end

        elseif G(i,1) == 2 % parametrized by (8),(9),(10)

            if visited(par)

                muy = P.clg(i).gamma(k,1) + ...
                    P.clg(i).gamma(k,2) * sample(par,1) + ...
                    P.clg(i).gamma(k,3) * sample(par,2) + ...
                    P.clg(i).gamma(k,4) * sin(sample(par,3)) + ...
                    P.clg(i).gamma(k,5) * cos(sample(par,3));
                mux = P.clg(i).gamma(k,6) + ...
                    P.clg(i).gamma(k,7) * sample(par,1) + ...
                    P.clg(i).gamma(k,8) * sample(par,2) + ...
                    P.clg(i).gamma(k,9) * sin(sample(par,3)) + ...
                    P.clg(i).gamma(k,10) * cos(sample(par,3));
                muangle = P.clg(i).gamma(k,11) + ...
                    P.clg(i).gamma(k,12) * sample(par,1) + ...
                    P.clg(i).gamma(k,13) * sample(par,2) + ...
                    P.clg(i).gamma(k,14) * sample(par,3);
                sample(i,1) = SampleGaussian(muy, P.clg(i).sigma_y(k));
                sample(i,2) = SampleGaussian(mux, P.clg(i).sigma_x(k));
                sample(i,3) = SampleGaussian(muangle, P.clg(i).sigma_angle(k));
                visited(i) = 1;
            end
        end

    end
end


% Tow Thomas Biquad Bandpass Filter - Leverriers Algorithm
% File:  TowThomasLev.m
% 9/22/02
clc;clear;format short g;
K=1e3;uF=1e-6;
R1=200*K;R2=10*K;R3=20*K;R4=10*K;R5=20*K;R6=20*K;
C1=0.0159*uF;C2=C1;
X=[R1 R2 R3 R4 R5 R6 C1 C2]; % Put components in vector form
%
[A,B,D,E]=tow(X);
%
% Uncomment following two lines to output arrays to text file qbout.txt
%fid=fopen('c:\M_files\qbout.txt','w'); % Use local directory
%diary c:\M_Files\qbout.txt; % Use local directory
A
B
D
E
%
% Display results of Leverrier's Algorithm
%
F1=eye(2);T1=-trace(A*F1)/1
F0=A*F1+T1*F1
T0=-trace(A*F0)/2
Y1=D*F1*B+E*T1
Y0=D*F0*B+E*T0
%
% Uncomment the following two lines to close text file.
%diary off
%status=fclose(fid);
%
% Get frequency sweep; BF = Beginning (Log) Frequency, ND = Number of Decades
% PD = Points per Decade
BF=2;ND=2;PD=50;Lit=ND*PD+1;L=linspace(BF,BF+ND,Lit);
for i=1:Lit
   F=10^L(i);s=2*pi*F*j;
   for k=1:3 % Get all three transfer functions from transfer matrix
      num=E(k)*s^2+Y1(k)*s+Y0(k);
      den=s^2+T1*s+T0;
      Vo(k,i)=20*log10(abs(num/den));
   end
end
%
% Plot Vo
%
h=plot(L,Vo(1,:),'k',L,Vo(2,:),'r',L,Vo(3,:),'b');
set(h,'LineWidth',2);
grid on
xlabel('Log Freq(Hz)');
ylabel('dBV');
title('Transfer Matrix Outputs');
legend('V2','V4','V6');
figure(1);


function [bval] = f2b(fval,bounds,bits)
% function [bval] = f2b(fval,bounds,bits)
%
% Return the binary representation of the float number fval.
%
% fval   - the float representation of the number
% bval   - the binary representation of the number
% bounds - the bounds on the variables
% bits   - the number of bits to represent each variable

% Binary and Real-Valued Simulation Evolution for Matlab
% Copyright (C) 1996 C.R. Houck, J.A. Joines, M.G. Kay
%
% C.R. Houck, J.Joines, and M.Kay. A genetic algorithm for function
% optimization: A Matlab implementation. ACM Transactions on Mathmatical
% Software, Submitted 1996.
%
% 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 1, 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. A copy of the GNU
% General Public License can be obtained from the
% Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

scale=(2.^bits-1)./ (bounds(:,2)-bounds(:,1))'; %The range of the variables
numV=size(bounds,1);
cs=[0 cumsum(bits)];
bval=[];
for i=1:numV
  fval(i)=(fval(i)-bounds(i,1)) * scale(i);
  bval=[bval rem(floor(fval(i)*pow2(1-bits(i):0)),2)];
end


function [g]=comp_iwfac(gf,L,a,M)
%COMP_IWFAC  Compute inverse window factorization
%   Usage: g=comp_iwfac(gf,a,M);
%
%   Input parameters:
%         gf    : Factored Window
%         a     : Length of time shift.
%         M     : Number of frequency bands.
%   Output parameters:
%         g     : Window function.
%
%   References: so07-2 st98-8

%   AUTHOR : Peter L. Søndergaard.
%   TESTING: OK
%   REFERENCE: OK

% Calculate the parameters that was not specified
R=prod(size(gf))/L;

N=L/a;
b=L/M;

% The four factorization parameters.
c=gcd(a,M);
p=a/c;
q=M/c;
d=N/q;

gf=reshape(gf,p,q*R,c,d);

% Scale by the sqrt(M) comming from Walnuts representation
gf=gf/sqrt(M);

% fft them
if d>1
  gf=ifft(gf,[],4);
end;

g=zeros(L,R,assert_classname(gf));

% Set up the small matrices
for w=0:R-1
  for s=0:d-1
    for l=0:q-1
      for k=0:p-1
	g((1:c)+mod(k*M-l*a+s*p*M,L),w+1)=reshape(gf(k+1,l+1+q*w,:,s+1),c,1);
      end;
    end;
  end;
end;


% GAMLPR = Gamma Distribution - Log Probability Density Ratio
% Copyright (c) 1998, Harvard University. Full copyright in the file Copyright
%
%   [ lpr ] = gamlpr( g1, g2, alph, gam )
%
% returns log ( p(g1)/p(g2) ) when g1 and g2 are
% distributed gamma(alph,gam)
%

function [ lpr ] = gamlpr(g1, g2, alph, gam)
lpr = (alph-1)*log(g1/g2)  - (g1-g2)/gam ;