function r = sobol_dataset ( m, n, skip )

%*****************************************************************************80
%
%% SOBOL_DATASET generates a Sobol dataset and writes it to a file.
%
%  Usage:
%
%    r = sobol_dataset ( m, n, skip )
%
%    where
%
%    * M, the spatial dimension,
%    * N, the number of points to generate,
%    * SKIP, the number of initial values to skip.
%    * R is the M by N array created.
%
%    creates an M by N Sobol dataset and writes it to the
%    file "sobol_M_N.txt".
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 December 2009
%
%  Author:
%
%    John Burkardt
%
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SOBOL_DATASET\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Generate a Sobol dataset.\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 SKIP.
%
  if ( nargin < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, '  SKIP is the number of points to skip.\n' );
    fprintf ( 1, '  0 is a common choice.\n' );
    fprintf ( 1, '  Another is the least power of 2 greater than or equal to N.\n' );
    skip = input ( '  Enter SKIP: ' );
  else
    skip = str2num ( skip );
  end

  fprintf ( 1, '  SKIP = %d\n', skip );
%
%  Compute the data.
%
  r = i4_sobol_generate ( m, n, skip );
%
%  Write it to a file.
%
  output_filename = ...
    strcat ( 'sobol_', 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, 'SOBOL_DATASET:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

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

  return
end
function bit = i4_bit_hi1 ( n )

%*****************************************************************************80
%
%% I4_BIT_HI1 returns the position of the high 1 bit base 2 in an integer.
%
%  Example:
%
%       N    Binary     BIT
%    ----    --------  ----
%       0           0     0
%       1           1     1
%       2          10     2
%       3          11     2
%       4         100     3
%       5         101     3
%       6         110     3
%       7         111     3
%       8        1000     4
%       9        1001     4
%      10        1010     4
%      11        1011     4
%      12        1100     4
%      13        1101     4
%      14        1110     4
%      15        1111     4
%      16       10000     5
%      17       10001     5
%    1023  1111111111    10
%    1024 10000000000    11
%    1025 10000000001    11
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the integer to be measured.
%    N should be nonnegative.  If N is nonpositive, the value will always be 0.
%
%    Output, integer BIT, the number of bits base 2.
%
  i = floor ( n );
  bit = 0;

  while ( 1 )

    if ( i <= 0 )
      break;
    end

    bit = bit + 1;
    i = floor ( i / 2 );

  end

  return
end

function bit = i4_bit_lo0 ( n )

%*****************************************************************************80
%
%% I4_BIT_LO0 returns the position of the low 0 bit base 2 in an integer.
%
%  Example:
%
%       N    Binary     BIT
%    ----    --------  ----
%       0           0     1
%       1           1     2
%       2          10     1
%       3          11     3
%       4         100     1
%       5         101     2
%       6         110     1
%       7         111     4
%       8        1000     1
%       9        1001     2
%      10        1010     1
%      11        1011     3
%      12        1100     1
%      13        1101     2
%      14        1110     1
%      15        1111     5
%      16       10000     1
%      17       10001     2
%    1023  1111111111     1
%    1024 10000000000     1
%    1025 10000000001     1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the integer to be measured.
%    N should be nonnegative.
%
%    Output, integer BIT, the position of the low 1 bit.
%
  bit = 0;
  i = floor ( n );

  while ( 1 )

    bit = bit + 1;
    i2 = floor ( i / 2 );

    if ( i == 2 * i2 )
      break;
    end

    i = i2;

  end

  return
end
function [ quasi, seed ] = i4_sobol ( dim_num, seed )

%*****************************************************************************80
%
%% I4_SOBOL generates a new quasirandom Sobol vector with each call.
%
%  Discussion:
%
%    The routine adapts the ideas of Antonov and Saleev.
%
%    Thanks to Francis Dalaudier for pointing out that the range of allowed
%    values of DIM_NUM should start at 1, not 2!  17 February 2009.
%
%    This function was modified to use PERSISTENT variables rather than
%    GLOBAL variables, 13 December 2009.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 January 2010
%
%  Author:
%
%    Original FORTRAN77 version by Bennett Fox.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Antonov, Saleev,
%    USSR Computational Mathematics and Mathematical Physics,
%    Volume 19, 1980, pages 252 - 256.
%
%    Paul Bratley, Bennett Fox,
%    Algorithm 659:
%    Implementing Sobol's Quasirandom Sequence Generator,
%    ACM Transactions on Mathematical Software,
%    Volume 14, Number 1, pages 88-100, 1988.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, pages 362-376, 1986.
%
%    Ilya Sobol,
%    USSR Computational Mathematics and Mathematical Physics,
%    Volume 16, pages 236-242, 1977.
%
%    Ilya Sobol, Levitan,
%    The Production of Points Uniformly Distributed in a Multidimensional
%    Cube (in Russian),
%    Preprint IPM Akad. Nauk SSSR,
%    Number 40, Moscow 1976.
%
%  Parameters:
%
%    Input, integer DIM_NUM, the number of spatial dimensions.
%    DIM_NUM must satisfy 1 <= DIM_NUM <= 40.
%
%    Input/output, integer SEED, the "seed" for the sequence.
%    This is essentially the index in the sequence of the quasirandom
%    value to be generated.  On output, SEED has been set to the
%    appropriate next value, usually simply SEED+1.
%    If SEED is less than 0 on input, it is treated as though it were 0.
%    An input value of 0 requests the first (0-th) element of the sequence.
%
%    Output, real QUASI(DIM_NUM), the next quasirandom vector.
%
  persistent atmost;
  persistent dim_max;
  persistent dim_num_save;
  persistent initialized;
  persistent lastq;
  persistent log_max;
  persistent maxcol;
  persistent poly;
  persistent recipd;
  persistent seed_save;
  persistent v;

  if ( isempty ( initialized ) )
    initialized = 0;
    dim_num_save = -1;
  end

  if ( ~initialized | dim_num ~= dim_num_save )

    initialized = 1;

    dim_max = 40;
    dim_num_save = -1;
    log_max = 30;
    seed_save = -1;
%
%  Initialize (part of) V.
%
    v(1:dim_max,1:log_max) = zeros(dim_max,log_max);

    v(1:40,1) = [ ...
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]';

    v(3:40,2) = [ ...
            1, 3, 1, 3, 1, 3, 3, 1, ...
      3, 1, 3, 1, 3, 1, 1, 3, 1, 3, ...
      1, 3, 1, 3, 3, 1, 3, 1, 3, 1, ...
      3, 1, 1, 3, 1, 3, 1, 3, 1, 3 ]';

    v(4:40,3) = [ ...
               7, 5, 1, 3, 3, 7, 5, ...
      5, 7, 7, 1, 3, 3, 7, 5, 1, 1, ...
      5, 3, 3, 1, 7, 5, 1, 3, 3, 7, ...
      5, 1, 1, 5, 7, 7, 5, 1, 3, 3 ]';

    v(6:40,4) = [ ...
                     1, 7, 9,13,11, ...
      1, 3, 7, 9, 5,13,13,11, 3,15, ...
      5, 3,15, 7, 9,13, 9, 1,11, 7, ...
      5,15, 1,15,11, 5, 3, 1, 7, 9 ]';

    v(8:40,5) = [ ...
                           9, 3,27, ...
     15,29,21,23,19,11,25, 7,13,17, ...
      1,25,29, 3,31,11, 5,23,27,19, ...
     21, 5, 1,17,13, 7,15, 9,31, 9 ]';

    v(14:40,6) = [ ...
              37,33, 7, 5,11,39,63, ...
     27,17,15,23,29, 3,21,13,31,25, ...
      9,49,33,19,29,11,19,27,15,25 ]';

    v(20:40,7) = [ ...
                                         13, ...
     33,115, 41, 79, 17, 29,119, 75, 73,105, ...
      7, 59, 65, 21,  3,113, 61, 89, 45,107 ]';

    v(38:40,8) = [ ...
                                7, 23, 39 ]';
%
%  Set POLY.
%
    poly(1:40)= [ ...
        1,   3,   7,  11,  13,  19,  25,  37,  59,  47, ...
       61,  55,  41,  67,  97,  91, 109, 103, 115, 131, ...
      193, 137, 145, 143, 241, 157, 185, 167, 229, 171, ...
      213, 191, 253, 203, 211, 239, 247, 285, 369, 299 ];

    atmost = 2^log_max - 1;
%
%  Find the number of bits in ATMOST.
%
    maxcol = i4_bit_hi1 ( atmost );
%
%  Initialize row 1 of V.
%
    v(1,1:maxcol) = 1;

  end
%
%  Things to do only if the dimension changed.
%
  if ( dim_num ~= dim_num_save )
%
%  Check parameters.
%
    if ( dim_num < 1 | dim_max < dim_num )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'I4_SOBOL - Fatal error!\n' );
      fprintf ( 1, '  The spatial dimension DIM_NUM should satisfy:\n' );
      fprintf ( 1, '    1 <= DIM_NUM <= %d\n', dim_max );
      fprintf ( 1, '  But this input value is DIM_NUM = %d\n', dim_num );
      return
    end

    dim_num_save = dim_num;
%
%  Initialize the remaining rows of V.
%
    for i = 2 : dim_num
%
%  The bits of the integer POLY(I) gives the form of polynomial I.
%
%  Find the degree of polynomial I from binary encoding.
%
      j = poly(i);
      m = 0;

      while ( 1 )

        j = floor ( j / 2 );

        if ( j <= 0 )
          break;
        end

        m = m + 1;

      end
%
%  Expand this bit pattern to separate components of the logical array INCLUD.
%
      j = poly(i);
      for k = m : -1 : 1
        j2 = floor ( j / 2 );
        includ(k) = ( j ~= 2 * j2 );
        j = j2;
      end
%
%  Calculate the remaining elements of row I as explained
%  in Bratley and Fox, section 2.
%
      for j = m + 1 : maxcol
        newv = v(i,j-m);
        l = 1;
        for k = 1 : m
          l = 2 * l;
          if ( includ(k) )
            newv = bitxor ( newv, l * v(i,j-k) );
          end
        end
        v(i,j) = newv;
      end
    end
%
%  Multiply columns of V by appropriate power of 2.
%
    l = 1;
    for j = maxcol-1 : -1 : 1
      l = 2 * l;
      v(1:dim_num,j) = v(1:dim_num,j) * l;
    end
%
%  RECIPD is 1/(common denominator of the elements in V).
%
    recipd = 1.0 / ( 2 * l );

    lastq(1:dim_num) = 0;

  end

  seed = floor ( seed );

  if ( seed < 0 )
    seed = 0;
  end

  if ( seed == 0 )

    l = 1;
    lastq(1:dim_num) = 0;

  elseif ( seed == seed_save + 1 )
%
%  Find the position of the right-hand zero in SEED.
%
    l = i4_bit_lo0 ( seed );

  elseif ( seed <= seed_save )

    seed_save = 0;
    l = 1;
    lastq(1:dim_num) = 0;

    for seed_temp = seed_save : seed - 1
      l = i4_bit_lo0 ( seed_temp );
      for i = 1 : dim_num
        lastq(i) = bitxor ( lastq(i), v(i,l) );
      end
    end

    l = i4_bit_lo0 ( seed );

  elseif ( seed_save + 1 < seed )

    for seed_temp = seed_save + 1 : seed - 1
      l = i4_bit_lo0 ( seed_temp );
      for i = 1 : dim_num
        lastq(i) = bitxor ( lastq(i), v(i,l) );
      end
    end

    l = i4_bit_lo0 ( seed );

  end
%
%  Check that the user is not calling too many times!
%
  if ( maxcol < l )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_SOBOL - Fatal error!\n' );
    fprintf ( 1, '  Too many calls!\n' );
    fprintf ( 1, '  MAXCOL = %d\n', maxcol );
    fprintf ( 1, '  L =      %d\n', l );
    return
  end
%
%  Calculate the new components of QUASI.
%
  for i = 1 : dim_num
    quasi(i) = lastq(i) * recipd;
    lastq(i) = bitxor ( lastq(i), v(i,l) );
  end

  seed_save = seed;
  seed = seed + 1;

  return
end
function r = i4_sobol_generate ( m, n, skip )

%*****************************************************************************80
%
%% I4_SOBOL_GENERATE generates a Sobol dataset.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 December 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, integer N, the number of points to generate.
%
%    Input, integer SKIP, the number of initial points to skip.
%
%    Output, real R(M,N), the points.
%
  seed = skip;

  for j = 1 : n
    [ r(1:m,j), seed ]  = i4_sobol ( m, seed );
  end

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

%*****************************************************************************80
%
%% R8MAT_WRITE writes an R8MAT file.
%
%  Discussion:
%
%    An R8MAT is an array of R8's.
%
%  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 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 [A,B,C,D]=era(h,n,N,Ts,def);

% Eigensystem Realization Algorithm (ERA)
%
% Author: Samuel da Silva - UNICAMP
% e-mail: samsilva@fem.unicamp.br
% Date: 2006/10/20
%
% [A,B,C,D]=era(h,n,N,Ts,def);
%
% Inputs:
%    h: discrete-time impulse response
%    n: order of the system
%    N: number of samples to assembly the Hankel matrix
%    Ts: sample time
%    def: if = 1: the output will be the discrete-time state-space model
%         if = 2: the output will be the continuous-time state-space model
%
% Otputs:
%    [A,B,C,D]: state-space model
%
% Note: For now, it works to SISO systems and it is necessary the control toolbox
%
% References: Juang, J. N. and Phan, M. Q. "Identification and Control of
% Mechanical Systems", Cambridge University Press, 2001

% Hankel matrix
H0 = hankel(h(2:N+1));            % k = 0
H1 = hankel(h(3:N+2));            % k = 1;

% Factorization of the Hankel matrix by use of SVD
[R,Sigma,S] = svd(H0);
% R and S are orthonormal and Sigma is a rectangular matrix

Sigman = Sigma(1:n,1:n);

Wo = R(:,1:n)*Sigman^0.5;           % observability matrix
Co = Sigman^.5*S(:,1:n)';           % controllability matrix

% The identified system matrix are:
A = Sigman^-.5*R(:,1:n)'*H1*S(:,1:n)*Sigman^-.5;            % dynamic matrix
B = Co(:,1);                    % input matrix
C = Wo(1,:);                    % output matrix
D = h(1);                       % direct-transmission matrix

sysdisc = ss(A,B,C,D,Ts);       % discrete-time system

if def == 2
    syscont = d2c(sysdisc,'zoh');       % Conversion of discrete LTI models to continuous time
    [A,B,C,D]=ssdata(syscont);          % continuous system
end

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


function [ c ] = get_bpsk_cap( snr_db )
% assumes e[x^2] = 1;

x_vec = [-1, 1];
n_0 = 1/2*10^(-snr_db/10);
delta_y = sqrt(n_0) * 0.001;
max_value = min(10000, max(x_vec) + 3 + 3*sqrt(n_0));
y_vec = -max_value: delta_y : max_value;
p_y = zeros(length(y_vec), 1);
for y_index = 1 : length(y_vec)
    y = y_vec(y_index);
    for x_index = 1 : length(x_vec)
        x = x_vec(x_index);
        p_y(y_index) = p_y(y_index) + exp(-(y - x).^2/2/n_0)/sqrt(2*pi*n_0) * 0.5;
    end
end

p_y = p_y / (sum(p_y)*delta_y);

h = 0;
for y_index = 1 : length(y_vec)
    if p_y(y_index) > 0
        h = h + (-log2(p_y(y_index))) * p_y(y_index) * delta_y;
    end
end
c = h - 0.5 * (1 + log(2*pi*n_0))/log(2) ;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% inhomo_iso.m demonstrates Edge-preserving non-linear
% inhomogeneous linear isotropic filtering for denoising
%
% Copyright (c) Ritwik Kumar, Harvard University 2010
%               www.seas.harvard.edu/~rkkumar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clear;
%read the image
im = image_read('synimgn2');
w = double(im);

% set up finite difference parameters
alpha =0.5;
k = 1;
h = 1;

lambda = (alpha^2)*(k/(h^2));

[m n] = size(w);
% stick image into a vector
w_vec = reshape(w,n*n,1);
w_old = w_vec;
w_new = w_vec;

%smooth the image using Gaussian filtering
im_smth = filter_function(w,3);

%required of g() calculation
[dx_im_smth dy_im_smth] = gradient(im_smth);
gr_im_smth = dx_im_smth.^2 + dy_im_smth.^2;

% element by element g() calculation
[mmm nnn] = size(gr_im_smth);
for i=1:mmm
    for j=1:nnn
        g(i,j) = 1/(1+(gr_im_smth(i,j)/36));
    end
end
g = g';
jj=1;

figure;
for k=1:200   % for each iteration
    for i=1:n*n % solve using JAcobi iteration scheme
        row = ceil(i/n); %compute what row this pixel belongs to in original image
        col = i - (row-1) * n; % compute the column similarly

        %different if conditions handles pixels at different location in
        %the image as depending on their location they may or may not have
        %all their neighbor pixels which will be required for finite
        %differences

        if((col > 1) && (col < n) && (row > 1) && (row < n))
            xx = [(lambda * (-g(row,col) + g(row,col+1) + g(row+1,col) -g(row+1,col+1))) * ...
                    (- w_old(i) + w_old(i+1) - w_old(i+n) + w_old(i+n+1))];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i-1) + w_old(i+n) + w_old(i-n))] ...
                + xx;
            w_new(i) = (-s + w_old(i))/(1+4*lambda*g(row,col));
        elseif((row == 1) && (col > 1) && (col < n))
            xx = [(lambda * (-g(row,col) + g(row,col+1) + g(row+1,col) -g(row+1,col+1))) * ...
                    (- w_old(i) + w_old(i+1) - w_old(i+n) + w_old(i+n+1))];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i-1) + w_old(i+n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((row == n) && (col > 1) && (col < n))
            xx = [(lambda * (-g(row,col) + g(row,col+1))) * ...
                    (- w_old(i) + w_old(i+1))];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i-1) + w_old(i-n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col == 1) && (row > 1) && (row < n))
            xx = [(lambda * (-g(row,col) + g(row,col+1) + g(row+1,col) -g(row+1,col+1))) * ...
                    (- w_old(i) + w_old(i+1) - w_old(i+n) + w_old(i+n+1))];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i+n) + w_old(i-n))] ...
                + xx;

            %s = -(lambda) * (w_old(i+1) + w_old(i+n) + w_old(i-n));
            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col == n) && (row > 1) && (row < n))
            xx = [(lambda * (-g(row,col) + g(row+1,col) )) * ...
                    (- w_old(i)  - w_old(i+n))];

            s = [-(lambda * g(row,col)) * ( w_old(i-1) + w_old(i+n) + w_old(i-n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col==1) && (row==1))
            xx = [(lambda * (-g(row,col) + g(row,col+1) + g(row+1,col) -g(row+1,col+1))) * ...
                    (- w_old(i) + w_old(i+1) - w_old(i+n) + w_old(i+n+1))];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i+n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col==n) && (row==1))
                        xx = [(lambda * (-g(row,col) + g(row+1,col))) * ...
                (- w_old(i)  - w_old(i+n) )];

            s = [-(lambda * g(row,col)) * (w_old(i-1) + w_old(i+n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col==1) && (row==n))
                       xx = [(lambda * (-g(row,col) + g(row,col+1) )) * ...
                (- w_old(i) + w_old(i+1) )];

            s = [-(lambda * g(row,col)) * (w_old(i+1) + w_old(i-n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        elseif((col==n) && (row==n))
                        xx = [(lambda * (-g(row,col) )) * ...
                (- w_old(i) )];

            s = [-(lambda * g(row,col)) * ( w_old(i-1) + w_old(i-n))] ...
                + xx;

            w_new(i) = (-s + w_old(i))/(1+4*lambda);
        end
    end
    w_old = w_new;
    if((k==10)||(k==50)||(k==100)||(k==200)) % outputting the values at different iterations
        subplot(2,2,jj)
        imshow(uint8(reshape(w_new,n,n)));
        imwrite(uint8(reshape(w_new,n,n)),strcat('iso-synimgn2',int2str(jj),'.bmp'));
                title('Linear Inhomogeneous Isotropic Filtering (Implicit Euler Method)');
        xlabel(strcat('Lenna at t=',int2str(k),', Alpha=0.5'));

        jj=jj+1;
    end

end


function [C, status] = parfileCondition(parfiles, nFrames);
%
% [C, status] = parfileCondition(parfiles, <nFrames=set by parfiles>);
%
% Estimate the condition number of an experimental paradigm
% specified by parfiles. This condition number determines
% whether or not time courses can be successfully deconvolved
% for data with this paradigm.
%
% parfiles: cell of parfile paths.
%
% nFrames: optional argument specifying # of frames to take from
% each parfile. If omitted, just takes max # of frames set by the
% parfiles.
%
% C: condition number, equal to sum(X' * X), where X is the
% design matrix constructed from the parfiles.
%
% status: 1 if time courses can be deconvolved, 0 if not.
% Basically, status just tests whether C is less than 10 million.
%
%
%
% ras 02/2006.
status = 0;

params = er_defaultParams;
params.glmHRF = 0;

% create Toeplitz matrix for deconvolution from the parfiles
S = delta_function_from_parfile(parfiles);
X = glm_deconvolution_matrix(S, -4:17);

% This part I've empirically determined from er_selxavg, but
% hope to understand soon:
% iteratively sum the matrix X' * W * X
% (where W is a whitening matrix which we basically always
% set to the identitiy matrix, so I'm only concerned with that
% case).
nFrames = size(X, 1);
nPred = size(X, 2);
nRuns = size(X, 3);
XtX = zeros(nPred, nPred);
for i = 1:nRuns
    XtX = XtX + [X(:,:,i)' * X(:,:,i)];
end

C = cond(XtX);
status = (C < 10^7);

if status==0
    disp('Paradigm is ill-conditioned.')
end

return


function [xc,Vi] = canonical_autocorrelation(TR,n,varargin)
% [xc,Vi] = canonical_autocorrelation(TR,n,[a])
% Tor Wager, 2 / 23 / 04
%
% exponential autocorrelation function of the form xc = e ^ (-ax)
% Optional input "a" is an exponent; higher = more white noise, low =
% colored
%
% TR = sampling rate (time per data point)
% n = number of samples in timeseries
%
% xc = vector containing autocorrelation coefficients
% Vi = autocorrelation matrix

f = inline('A * exp(-a * x)','A','a','x');  % exponential function
xa = 0:TR:60;

if length(varargin) > 0
    xc = f(1,varargin{1},xa);
else
    xc = f(.9475,.5323,xa);    % params at 3T from vnl experiment, n = 10
    xc = xc ./ max(xc);
end

% autocorrelation
Vi = getV('make',xc,n);

return


% Program for Bus Power Injections, Line & Power flows (p.u)...

%function [Pi Qi Pg Qg Pl Ql] = loadflow(nb,V,del,BMva)
function [Load_Flow_M Line_Flow_M] = loadflow(nb,V,del,BMva,Line_Data,Bus_Data)

Y = ybusppg(nb,Line_Data);                % Calling Ybus program..
%lined = linedatas(nb);          % Get linedats.
lined = Line_Data;
busd = Bus_Data;
%busd = busdatas(nb);            % Get busdatas..

Vm = pol2rect(V,del);           % Converting polar to rectangular..
Del = 180/pi*del;               % Bus Voltage Angles in Degree...
fb = lined(:,1);                % From bus number...
tb = lined(:,2);                % To bus number...
nl = length(fb);                % No. of Branches..
Pl = busd(:,7);                 % PLi..
Ql = busd(:,8);                 % QLi..

Iij = zeros(nb,nb);
Sij = zeros(nb,nb);
Si = zeros(nb,1);

% Bus Current Injections..
 I = Y*Vm;
 Im = abs(I);
 Ia = angle(I);

%Line Current Flows..
for m = 1:nl
    p = fb(m); q = tb(m);
    Iij(p,q) = -(Vm(p) - Vm(q))*Y(p,q); % Y(m,n) = -y(m,n)..
    Iij(q,p) = -Iij(p,q);
end
Iij = sparse(Iij);
Iijm = abs(Iij);
Iija = angle(Iij);

% Line Power Flows..
for m = 1:nb
    for n = 1:nb
        if m ~= n
            Sij(m,n) = Vm(m)*conj(Iij(m,n))*BMva;
        end
    end
end
Sij = sparse(Sij);
Pij = real(Sij);
Qij = imag(Sij);

% Line Losses..
Lij = zeros(nl,1);
for m = 1:nl
    p = fb(m); q = tb(m);
    Lij(m) = Sij(p,q) + Sij(q,p);
end
Lpij = real(Lij);
Lqij = imag(Lij);

% Bus Power Injections..
for i = 1:nb
    for k = 1:nb
        Si(i) = Si(i) + conj(Vm(i))* Vm(k)*Y(i,k)*BMva;
    end
end
Pi = real(Si);
Qi = -imag(Si);
Pg = Pi+Pl;
Qg = Qi+Ql;

Load_Flow_M = zeros(nb+1,9);

for m = 1:nb
    Load_Flow_M(m,1) = m;
    Load_Flow_M(m,2) = V(m);
    Load_Flow_M(m,3) = Del(m);
    Load_Flow_M(m,4) = Pi(m);
    Load_Flow_M(m,5) = Qi(m);
    Load_Flow_M(m,6) = Pg(m);
    Load_Flow_M(m,7) = Qg(m);
    Load_Flow_M(m,8) = Pl(m);
    Load_Flow_M(m,9) = Ql(m);
end
m = m + 1;
    Load_Flow_M(m,1) = NaN;
    Load_Flow_M(m,2) = NaN;
    Load_Flow_M(m,3) = NaN;
    Load_Flow_M(m,4) = sum(Pi);
    Load_Flow_M(m,5) = sum(Qi);
    Load_Flow_M(m,6) = sum(Pi+Pl);
    Load_Flow_M(m,7) = sum(Qi+Ql);
    Load_Flow_M(m,8) = sum(Pl);
    Load_Flow_M(m,9) = sum(Ql);

Line_Flow_M = zeros(nl+1,10);

for m = 1:nl
    p = fb(m); q = tb(m);
    Line_Flow_M(m,1) = full(p);
    Line_Flow_M(m,2) = full(q);
    Line_Flow_M(m,3) = full(Pij(p,q));
    Line_Flow_M(m,4) = full(Qij(p,q));
    Line_Flow_M(m,5) = full(q);
    Line_Flow_M(m,6) = full(p);
    Line_Flow_M(m,7) = full(Pij(q,p));
    Line_Flow_M(m,8) = full(Qij(q,p));
    Line_Flow_M(m,9) = Lpij(m);
    Line_Flow_M(m,10) = Lqij(m);
end
m = m+1;
    Line_Flow_M(m,1) = NaN;
    Line_Flow_M(m,2) = NaN;
    Line_Flow_M(m,3) = NaN;
    Line_Flow_M(m,4) = NaN;
    Line_Flow_M(m,5) = NaN;
    Line_Flow_M(m,6) = NaN;
    Line_Flow_M(m,7) = NaN;
    Line_Flow_M(m,8) = NaN;
    Line_Flow_M(m,9) = sum(Lpij);
    Line_Flow_M(m,10) = sum(Lqij);


function fem1d_bvp_quadratic_test06 ( )

%*****************************************************************************80
%
%% FEM1D_BVP_QUADRATIC_TEST06 does an error analysis.
%
%  Discussion:
%
%    Use A6, C6, F6, EXACT6, EXACT_UX6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'FEM1D_BVP_QUADRATIC_TEST06\n' );
  fprintf ( 1, '  Solve -( A(x) U''(x) )'' + C(x) U(x) = F(x)\n' );
  fprintf ( 1, '  for 0 < x < 1, with U(0) = U(1) = 0.\n' );
  fprintf ( 1, '  A6(X)  = 1.0\n' );
  fprintf ( 1, '  C6(X)  = 0.0\n' );
  fprintf ( 1, '  F6(X)  = pi*pi*sin(pi*X)\n' );
  fprintf ( 1, '  U6(X)  = sin(pi*x)\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Compute L2 norm and seminorm of error for various N.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '     N        L1 error        L2 error      Seminorm error\n' );
  fprintf ( 1, '\n' );

  n = 11;
  for i = 0 : 4
%
%  Geometry definitions.
%
    x_first = 0.0;
    x_last = 1.0;
    x = linspace ( x_first, x_last, n );
    x = x(:);

    u = fem1d_bvp_quadratic ( n, @a6, @c6, @f6, x );

    e1 = l1_error ( n, x, u, @exact6 );
    e2 = l2_error_quadratic ( n, x, u, @exact6 );
    h1s = h1s_error_quadratic ( n, x, u, @exact_ux6 );

    fprintf ( 1, '  %4d  %14f  %14f  %14f\n', n, e1, e2, h1s );

    n = 2 * ( n - 1 ) + 1;

  end

  return
end
function value = a6 ( x )

%*****************************************************************************80
%
%% A6 evaluates A function #6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Output, real VALUE, the value of A(X).
%
  value = 1.0;

  return
end
function value = c6 ( x )

%*****************************************************************************80
%
%% C6 evaluates C function #6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Output, real VALUE, the value of C(X).
%
  value = 0.0;

  return
end
function value = exact6 ( x )

%*****************************************************************************80
%
%% EXACT6 returns exact solution #6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Output, real VALUE, the value of U(X).
%
  value = sin ( pi * x );

  return
end
function value = exact_ux6 ( x )

%*****************************************************************************80
%
%% EXACT_UX6 evaluates the derivative of exact solution #6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Output, real VALUE, the value of dUdX(X).
%
  value = pi * cos ( pi * x );

  return
end
function value = f6 ( x )

%*****************************************************************************80
%
%% F6 evaluates right hand side function #6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 February 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the evaluation point.
%
%    Output, real VALUE, the value of F(X).
%
  value = pi * pi * sin ( pi * x );

  return
end


function ou_euler_maruyama ( theta, mu, sigma, x0, tmax, n, r, seed )

%*****************************************************************************80
%
%% OU_EULER_MARUYAMA applies Euler-Maruyama to the Ornstein-Uhlenbeck SDE.
%
%  Discussion:
%
%    The stochastic differential equation (SDE) is:
%
%      dx = theta * ( mu - x(t) ) dt + sigma dW,
%      x(0) = x0,
%
%    The discretized Brownian path uses a constant stepsize.
%
%    A "large" time step DT_LARGE is used for the smooth portion of the
%    equation, while a smaller time step DT_SMALL is used for the
%    discretized Brownian path.  We take R small steps to equal one
%    large step, so that:
%
%      dt_large = r * dt_small = tmax / n
%
%    For an SDE of the form:
%
%      dx = f(x(t)) dt + g(x(t)) dW(t)
%
%    the Euler-Maruyama method has the form:
%
%      x(j) = x(j-1) + f(X(j-1)) * dt_large + g(X(j-1)) * dW(j-1)
%
%    where dW(j-1) is approximated by the sum of R normal random values
%    multiplied by the square root of DT_SMALL.
%
%    Note that if SIGMA is zero, the problem becomes deterministic,
%    with solution
%
%      x(t) = mu + ( x0 - mu ) * exp ( - theta * t )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 January 2013
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Desmond Higham,
%    An Algorithmic Introduction to Numerical Simulation of
%    Stochastic Differential Equations,
%    SIAM Review,
%    Volume 43, Number 3, September 2001, pages 525-546
%
%  Parameters:
%
%    Input, real THETA, MU, SIGMA, the value of problem parameters.
%
%    Input, real X0, the initial condition.  When studying many
%    realizations of this problem, it is usual for X0 to be chosen
%    from a normal distribution.
%
%    Input, real TMAX, the final time.
%
%    Input, integer N, the number of large scale time steps.
%
%    Input, integer R, the number of small scale time steps per single
%    large scale time step.
%
%    Input, integer SEED, a seed for the random number generator.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'OU_EULER_MARUYAMA:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Use an Euler-Maruyama method to approximate the solution of\n' );
  fprintf ( 1, '  the Ornstein-Uhlenbeck stochastic differential equation:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    d x(t) = theta * ( mu - x(t) ) dt + sigma dW\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  with initial condition x(0) = x0.\n' );

  if ( nargin < 1 )
    theta = 2.0;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default decay rate THETA = %g\n', theta );
  end

  if ( nargin < 2 )
    mu = 1.0;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default mean MU = %g\n', mu );
  end

  if ( nargin < 3 )
    sigma = 0.15;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default variance SIGMA = %g\n', sigma );
  end

  if ( nargin < 4 )
    x0 = 2.0;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default initial value X0 = %g\n', x0 );
  end

  if ( nargin < 5 )
    tmax = 3.0;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default final time TMAX = %g\n', tmax );
  end

  if ( nargin < 6 )
    n = 10000;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default number of large timesteps N = %d\n', n );
  end

  if ( nargin < 7 )
    r = 8;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default ratio of small to large timesteps R = %d\n', r );
  end

  if ( nargin < 8 )
    seed = 123456789;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default value of random SEED = %d\n', seed );
  end
%
%  Initialize the random number generator.
%  The following way to initialize the random number generator
%  may not be available in older versions of MATLAB.
%
  rng ( seed )
%
%  Set time steps.
%
  dt_large = tmax / n;
  dt_small = tmax / n / r;
%
%  Carry out the Euler-Maruyama approximate integration process.
%
  t = linspace ( 0, tmax, n + 1 );
  x = zeros ( 1, n + 1 );

  x(1) = x0;
  for j = 1 : n
    dw = sqrt ( dt_small ) * randn ( 1, r );
    x(j+1) = x(j) + dt_large * theta * ( mu - x(j) ) + sigma * sum ( dw(1:r) );
  end
%
%  Plot the approximate solution.
%
  plot ( t, x, 'r-', 'LineWidth', 3 )
  xlabel ( 't', 'FontSize', 16 )
  ylabel ( 'X(t)', 'FontSize', 16, 'Rotation', 0, 'HorizontalAlignment', 'right' )
  title ( 'Euler-Maruyama solution of Ornstein-Uhlenbeck SDE', 'FontSize', 16 )
  grid on

  filename = 'ou_euler_maruyama.png';
  print ( '-dpng', filename )
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Plot saved as "%s"\n', filename );

  return
end


function d = edge_degree ( n_node, n_edge, t )

%*****************************************************************************80
%
%% EDGE_DEGREE returns the degree of the nodes of a graph stored by edges.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer N_NODE, the number of nodes in the graph.
%    N_NODE must be positive.
%
%    Input, integer N_EDGE, the number of edges in the graph.
%    N_EDGE must be positive.
%
%    Input, integer T(2,N_EDGE), describes the edges of the tree
%    as pairs of nodes.
%
%    Output, integer D(N_NODE), the degree of each node.
%

%
%  Check.
%
  ierror = edge_check ( n_node, n_edge, t );

  if ( ierror ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'EDGE_DEGREE - Fatal error!\n' );
    fprintf ( 1, '  The input array is illegal.\n' );
    fprintf ( 1, '  IERROR = %d\n', ierror );
    error ( 'EDGE_DEGREE - Fatal error!' );
  end
%
%  Compute the degree of each node.
%
  d(1:n_node) = 0;

  for j = 1 : n_edge
    d(t(1,j)) = d(t(1,j)) + 1;
    d(t(2,j)) = d(t(2,j)) + 1;
  end

  return
end


%% "Spirograph" Code
%  Jonathan Jamieson - September 2013
%  unigamer@gmail.com
%  www.jonathanjamieson.com

% This is the main script. Run it in Matlab and then mess around with
% the "User Configurable Parameters". By default arm at the bottom
% is arm "a" and the left arm is arm "b". The "c" coordinates denote
% the position of the rotating platform.

%% User Configurable Parameters -------------------------------------------
% a - arm a parameters
% b - arm b parameters
% c - parameters of the rotating disc where the paper would be

% Time-span
t=1:0.01:900;

% The positions of the local coordinate systems in the global one
xa = 18;
ya = 2.5;

xb = 6.5;
yb = 12;

xc = 18;
yc = 12;

% The positions of where the arms are mounted to the rotating discs
A_x_local =-1.8;
A_y_local = 0.2;

B_x_local = 3;
B_y_local = 1;

% The angular speeds of the rotating discs
A_omega = -3*5;
B_omega = 1*5;
C_omega = 0.22*5;

% The lengths of the arms
La = 8;
Lb = 13;

% The distance between where the two rods join and the pen
extension = 1;

% Radii of the discs
ra = 2; % The "r" parameters are only
rb = 4; % used for the purpose of
rc = 6; % visualisation, not calculation

% End of User Configurable Parameters -------------------------------------

%% Graphical Stuff
scrsz = get(0,'ScreenSize');  % Get screen size
figure('Name','The drawing','Position',[scrsz(1)+scrsz(3)/4 scrsz(2)+scrsz(4)/6 scrsz(3)/2 scrsz(4)/1.5]);
hold on
title('The Plot');
axis equal

field_size = 30;
xlim(gca, [0 field_size]);
ylim(gca, [0 field_size]);

L1_handle = line([0 0],[0 0],'Color','red','LineWidth',2);
L2_handle = line([0 0],[0 0],'Color','red','LineWidth',2);
P_handle = line([0 0],[0 0],'Color','red','LineWidth',2);

PlotCircle(xa,ya,ra);
PlotCircle(xb,yb,rb);
PlotCircle(xc,yc,rc);

pen_log = zeros(numel(t),2); % Pre-allocate the matrix, this speeds stuff up and is good practice.

%% Main Loop
% This loop is executed for each time-step

try
  for loop_counter=1:1:numel(t)

    %% Calculate the position of the pen at the current time-step
    current_time=t(loop_counter);
    [A_x_global,A_y_global] = Local2Global(A_x_local,A_y_local,xa,ya,current_time*A_omega);
    [B_x_global,B_y_global] = Local2Global(B_x_local,B_y_local,xb,yb,current_time*B_omega);
    [C_x_global,C_y_global] = Calculate_Point_C(A_x_global,B_x_global,A_y_global,B_y_global,La,Lb); % This is the intersection of two circles
    [P_x_global,P_y_global ] = CalculatePenPosition(A_x_global,A_y_global,C_x_global,C_y_global,extension);
    [C_x_local,C_y_local] = Global2Local(P_x_global,P_y_global,xc,yc,current_time*C_omega);

    pen_log((loop_counter),:) = [C_x_local,C_y_local]; % Update the pen_log with the new pen position

    %% Create a temporary matrix with the global position of each pen point generated so far
    % at the current time. Since the local coordinate system is rotating a new set of temporary coordinates need to be generated each time step.
    pen_log_temp = zeros(loop_counter,2);

    for loop_plot=1:1:loop_counter;

        [temp_x temp_y] = Local2Global(pen_log(loop_plot,1),pen_log(loop_plot,2),xc,yc,current_time*C_omega);

        pen_log_temp(loop_plot,:) = [temp_x temp_y];
    end

    if loop_counter ~= 1; % Don't try and delete on the first iteration because nothing will have been plotted yet
            delete(h_plot);
    end

    %% Redraw everything for the current time-step
    h_plot = plot(pen_log_temp(:,1),pen_log_temp(:,2),'Color','magenta');

    set(L1_handle,'XData',[A_x_global  C_x_global],'YData',[A_y_global C_y_global]);
    set(L2_handle,'XData',[B_x_global  C_x_global],'YData',[B_y_global C_y_global]);
    set(P_handle,'XData',[C_x_global  P_x_global],'YData',[C_y_global P_y_global]);

    refresh
    pause(0.000001);

  end

    %% Check figure hasn't been closed
    catch E
    if ~strcmp(E.identifier, 'MATLAB:class:InvalidHandle')
        pen_log = pen_log(any(pen_log,2),:); % Delete unused pen_log entries
        x = pen_log(:,1); % Make a vector from the first column
        y = pen_log(:,2); % Make a vector from the second column
        clearvars -except x y % Delete all variables except the coordinates generated in the drawing process. Uncomment this if you wish to debug something.
        break

    end
end

% comet(x,y) % Uncomment this function if you want an animated plot at the end of the drawing
% plot (x,y) % Uncomment this function if you want a plot at the end of the drawing


function w = dualtree(x, J, Faf, af)

% Dual-tree Complex Discrete Wavelet Transform
%
% USAGE:
%    w = dualtree(x, J, Faf, af)
% INPUT:
%   x - N-point vector
%       1) N is divisible by 2^J
%       2) N >= 2^(J-1)*length(af)
%   J - number of stages
%   Faf - filters for the first stage
%   af - filters for the remaining stages
% OUTPUT:
%   w - DWT coefficients
%      w{j}{1}, j = 1..J - real part
%      w{j}{2}, j = 1..J - imaginary part
%      w{J+1}{d} - lowpass coefficients, d = 1,2
% EXAMPLE:
%    x = rand(1, 512);
%    J = 4;
%    [Faf, Fsf] = FSfarras;
%    [af, sf] = dualfilt1;
%    w = dualtree(x, J, Faf, af);
%    y = idualtree(w, J, Fsf, sf);
%    err = x - y;
%    max(abs(err))
%
% WAVELET SOFTWARE AT POLYTECHNIC UNIVERSITY, BROOKLYN, NY
% http://taco.poly.edu/WaveletSoftware/

% normalization
x = x/sqrt(2);

% Tree 1
[x1 w{1}{1}] = afb(x, Faf{1});
for j = 2:J
    [x1 w{j}{1}] = afb(x1, af{1});
end
w{J+1}{1} = x1;

% Tree 2
[x2 w{1}{2}] = afb(x, Faf{2});
for j = 2:J
    [x2 w{j}{2}] = afb(x2, af{2});
end
w{J+1}{2} = x2;


function value = c8_le_l2 ( x, y )

%*****************************************************************************80
%
%% C8_LE_L2 := X <= Y for complex values, and the L2 norm.
%
%  Discussion:
%
%    The L2 norm can be defined here as:
%
%      C8_NORM2(X) = sqrt ( ( real (X) )**2 + ( imag (X) )**2 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, complex X, Y, the values to be compared.
%
%    Output, logical VALUE, is TRUE if X <= Y.
%
  if ( ( real ( x ) )^2 + ( imag ( x ) )^2 ...
    <= ( real ( y ) )^2 + ( imag ( y ) )^2 )
    value = 1;
  else
    value = 0;
  end

  return
end


function a = oto ( m, n )

%*****************************************************************************80
%
%% OTO returns the OTO matrix.
%
%  Example:
%
%    N = 5
%
%    2  1  .  .  .
%    1  2  1  .  .
%    .  1  2  1  .
%    .  .  1  2  1
%    .  .  .  1  2
%
%  Properties:
%
%    A is banded, with bandwidth 3.
%
%    A is tridiagonal.
%
%    Because A is tridiagonal, it has property A (bipartite).
%
%    A is integral: int ( A ) = A.
%
%    A is Toeplitz: constant along diagonals.
%
%    A is symmetric: A' = A.
%
%    Because A is symmetric, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is persymmetric: A(I,J) = A(N+1-J,N+1-I).
%
%    A is weakly diagonally dominant, but not strictly diagonally dominant.
%
%    The family of matrices is nested as a function of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of A.
%
%    Output, real A(M,N), the matrix.
%
  a = zeros ( m, n );

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

      if ( j == i - 1 )
        a(i,j) = 1.0;
      elseif ( j == i )
        a(i,j) = 2.0;
      elseif ( j == i + 1 )
        a(i,j) = 1.0;
      else
        a(i,j) = 0.0;
      end

    end
  end

  return
end


function [TCER, TCER_rand] = gsp_learn_tcer(G, X, params)
%GSP_LEARN_TCER Learn the Total Cumulative Energy Residual
%   Usage: TCER = gsp_learn_tcer(G, X);
%          TCER = gsp_learn_tcer(G, X, params);
%          [TCER, TCER_rand] = gsp_learn_tcer(...);
%
%   Input parameters:
%       G           : the graph
%       X           : a data matrix
%   Output parameters:
%       TCER        : the computed total commulative energy residual for G
%       TCER_rand   : the computed total commulative energy residual for a random basis
%
%   Total Cumulative Energy Residual (TCER): This is a number from [0 to 1]
%   describing how well a graph fits a given data matrix X, or
%   distribution.
%
%   Optional parameters
%   -------------------
%
%   * *params.s*      : s = svd(X);
%   * *params.verbose*: 0 = nothing, 1 = plot cum energy, 2 = plot against
%     random basis as a baseline (default 0)
%   * *params.sort*   : sort basis columns to get the minimum residual
%     possible (default 0)
%
%   See also: gsp_good_graph_index, gsp_stationarity_ratio
%

% Author  : Andreas Loukas, Vassilis Kalofolias
% Date    : 15 Nov 2016

% Handle input
if nargin < 3, params = struct(); end
if not(isfield(params, 'verbose')); params.verbose = 0; end;
if not(isfield(params, 'sort'));    params.sort = 0;    end;
if not(isfield(params, 's'));       params.s = svd(full(X));  end;

s = params.s;

if numel(s)< G.N
    s = [s; zeros(G.N-numel(s),1)];
end

if not(isfield(G, 'U'))
    G = gsp_compute_fourier_basis(G);
end

% frobenius norm of X
norm_X_fro = norm(s);

% sorting already done by svd.
% var_cumsum_svd = cumsum(sort(s.^2, 'descend')) ./ norm_X_fro^2;
var_cumsum_svd = cumsum(s.^2) ./ norm_X_fro^2;

% frobenius norm of X
norm_X_fro = norm(X, 'fro');

% for the graph
if params.sort
    var_cumsum_s_G = cumsum(sort(sum(abs(G.U' * X).^2, 2) ./ norm_X_fro^2, 'descend'));
else
    var_cumsum_s_G = cumsum(sum(abs(G.U' * X).^2, 2) ./ norm_X_fro^2);
end

% area under the curve
AUC_SVD   = sum(var_cumsum_svd);
AUC_G     = sum(var_cumsum_s_G);
TCER      = 1 - AUC_G/AUC_SVD;

% compute also the result for a random basis
AUC_RB    = sum(linspace(1/G.N, 1, G.N));
TCER_rand = (AUC_SVD - AUC_RB)/(AUC_SVD);

if params.verbose >= 1

    figure; hold on;

    plot(var_cumsum_svd)
    plot(var_cumsum_s_G)
    [Urand, ~] = qr(randn(G.N));        % random basis
    var_cumsum_s_rand = cumsum(sum(abs(Urand' * X).^2, 2) ./ norm_X_fro^2);
    plot(var_cumsum_s_rand)

    xlabel('k (number of basis vectors used)');
    ylabel('cumulative variance');
    legend('svd', 'G', 'random basis')
end

% plot good quality residual figure
if params.verbose >= 2
    figure;
    plot(var_cumsum_svd);
    hold on;
    %     plot(cum_energy_graph);
    plot(var_cumsum_s_G, 'color', [0.8500    0.3250    0.0980]);
    n_nodes = length(var_cumsum_svd);
    xf = [1:n_nodes, fliplr(1:n_nodes)];
    yf = [zeros(n_nodes,1); flipud(var_cumsum_svd)];
    fill(xf, yf, [     0    0.4470    0.7410],'facealpha', .2);

    xf = [1:n_nodes, fliplr(1:n_nodes)];
    yf = [zeros(n_nodes,1); flipud(var_cumsum_s_G)];
    fill(xf, yf, [0.8500    0.3250    0.0980],'facealpha', .2);

    plot(var_cumsum_s_G, 'color', [0.8500    0.3250    0.0980]);
    plot(var_cumsum_svd, 'color', [     0    0.4470    0.7410]);
    legend('Ground truth covariance', 'Graph', 'Ground truth total C.E.', 'Graph total C.E.','location', 'se')
%     title(['graph from ', num2str(k), ' samples'])
    ylabel('Expected cumulative energy');
    text(n_nodes/2, .5, ['Residual: ', num2str(100*TCER, 3), '%']);
    xlabel('k');
    ylim([0,1]);
end


function [uout, tout] = spin2(varargin)
%SPIN2  Solve stiff PDEs in 2D periodic domains, Fourier spectral method and
%exponential integrators.
%
%   UOUT = SPIN2(PDECHAR) solves the PDE specified by the string PDECHAR, and
%   plays a movie of the solution. Possible strings include 'GL' and 'GS' for
%   the Ginzburg-Landau and Gray-Scott equations. Other PDEs are available, see
%   Remark 1 and Examples 1-4. The output UOUT is a CHEBFUN2 corresponding to
%   the solution at the final time (a CHEBMATRIX for systems of equations, each
%   row representing one variable).
%
%   UOUT = SPIN2(S, N, DT) solves the PDE specified by the SPINOP2 S with N grid
%   points in each direction and time-step DT, and plays a movie of the solution.
%   See HELP/SPINOP2 and Example 5.
%
%   [UOUT, TOUT] = SPIN2(...) also returns the times chunks TOUT at which UOUT
%   was computed.
%
%   Users of SPIN2 will quickly find they want to vary aspects of the plotting.
%   The fully general syntax for this involves using preferences specified by
%   a SPINPREF2 object PREF. See HELP/SPINPREF2 and Example 6. However for many
%   purposes it is most convenient to use the syntax
%
%   UOUT = SPIN2(..., 'PREF1', VALUE1, 'PREF2', VALUE2, ...)
%
%   For example:
%
%   UOUT = SPIN2(..., 'Clim', [a b]) changes colorbar limits to [a b]
%   UOUT = SPIN2(..., 'colormap', 'jet') changes the colormap to 'jet'
%   UOUT = SPIN2(..., 'dataplot', 'abs') plots absolute value
%   UOUT = SPIN2(..., 'iterplot', 4) plots only every 4th time step
%   UOUT = SPIN2(..., 'Nplot', 256) plays a movie at 256x256 resolution
%   UOUT = SPIN2(..., 'plot', 'off') for no movie
%   UOUT = SPIN2(..., 'view', [a b]) changes the view angle to [a b]
%
% Remark 1: List of PDEs (case-insensitive)
%
%    - 'GL' for the Ginzburg-Landau equation,
%    - 'GS' for the Gray-Scott equations (stripes),
%    - 'GSspots' for the Gray-Scott equations (spots),
%    - 'SCHNAK' for the Schnakenberg equations,
%    - 'SH' for the Swift-Hohenberg equation.
%
% Example 1: Ginzburg-Landau equation (spiral waves)
%
%       u = spin2('GL');
%
%    solves the Ginzburg-Landau equation
%
%       u_t = laplacian(u) + u - (1+1.5i)*u*|u|^2,
%
%    on [0 100]^2 from t=0 to t=100, with a RANDNFUN2 initial condition.
%    The movie shows the real part of u.  For a movie of the absolute
%    value of u rather than the real part, execute
%
%       S = spinop2('GL');
%       u = spin2(S, 128, 1e-1, 'dataplot', 'abs');
%
% Example 2: Gray-Scott equations (pattern formation - stripes)
%
%       u = spin2('GS');
%
%    solves the Gray-Scott equations
%
%       u_t = 2e-5*laplacian(u) + F*(1-u) - u*v^2,
%       v_t = 1e-5*laplacian(v) - (F+K)*v + u*v^2,
%
%    on [0 1]^2 from t=0 to t=5000, with initial condition
%
%       u0(x,y) = 1 - exp(-100*((x-1/2.05)^2 + (y-1/2.05)^2)),
%       v0(x,y) = exp(-100*((x-1/2)^2 + 2*(y-1/2)^2)),
%
%    with F=0.030 and K=0.057.
%
% Example 2 (bis): Gray-Scott equations (pattern formation - spots)
%
%       u = spin2('GSspots');
%
%    solves the Gray-Scott equations
%
%       u_t = 2e-5*laplacian(u) + F*(1-u) - u*v^2,
%       v_t = 1e-5*laplacian(v) - (F+K)*v + u*v^2,
%
%    on [0 1]^2 from t=0 to t=5000, with initial condition
%
%       u0(x,y) = 1 - exp(-100*((x-1/2.05)^2 + (y-1/2.05)^2)),
%       v0(x,y) = exp(-100*((x-1/2)^2 + 2*(y-1/2)^2)),
%
%    with F=0.026 and K=0.059.
%
% Example 3: Schnakenberg equations (pattern formation - spots)
%
%       u = spin2('SCHNAK');
%
%    solves the Schnakenberg equations
%
%       u_t = laplacian(u) + 3*(a - u + u^2*v),
%       v_t = 10*laplacian(v) + 3*(b - u^2*v),
%
%    on [0 50]^2 from t=0 to t=500, with initial condition
%
%       u0(x,y) = (a+b) - exp(-2*((x-G/2.15)^2 + (y-G/2.15)^2)),
%       v0(x,y) = b/(a+b)^2 + exp(-2*((x-G/2)^2 + 2*(y-G/2)^2)),
%           with G=50, a=0.1 and b=0.9.
%
% Example 4: Swift-Hohenberg equation (Rayleigh-Benard convection rolls)
%
%       u = spin2('SH');
%
%    solves the Swift-Hohenberg equation
%
%       u_t = -2*laplacian(u) - biharmonic(u) - .9*u - u^3,
%
%    on [0 50]^2 from t=0 to t=800, with a RANDNFUN2 initial condition.
%
% Example 5: PDE specified by a SPINOP2
%
%       dom = [0 100 0 100]; tspan = [0 100];
%       S = spinop2(dom, tspan);
%       S.lin = @(u) lap(u);
%       S.nonlin = @(u) u - (1 + 1.5i)*u.*(abs(u).^2);
%       S.init = randnfun2(4, dom, 'trig');
%       S.init = S.init/norm(S.init, inf);
%       u = spin2(S, 128, 1e-1);
%
%   is equivalent to u = spin2('GL');
%
% Example 6: Using preferences
%
%       pref = spinpref2('plot', 'off', 'scheme', 'pecec433');
%       S = spinop2('SH');
%       u = spin2(S, 128, 5e-1, pref);
%   or simply,
%       u = spin2(S, 128, 5e-1, 'plot', 'off', 'scheme', 'pecec433');
%
%   solves the Swift-Hohenberg equation using N=128 grid points in each
%   direction, a time-step dt=5e-1, doesn't play any movie and uses the
%   time-stepping scheme PECEC433.
%
% See also SPINOP2, SPINPREF2, EXPINTEG.

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

% We are going to parse the inputs and call SOLVEPDE in the following ways,
%
%       SPINOPERATOR.SOLVEPDE(S, N, dt)
%  or
%       SPINOPERATOR.SOLVEPDE(S, N, dt, pref)
%
% where S is a SPINOP2 object, N is the number of grid points in each direction,
% DT is the time-step and PREF is a SPINPREF2 oject.

% CASE 1. U = SPIN2('GL'):
if ( nargin == 1 )

    try spinop2(varargin{1});
    catch
        error('Unrecognized PDE. See HELP/SPINSPHERE for the list of PDEs.')
    end
    [S, N, dt, pref] = parseInputs(varargin{1});
    varargin{1} = S;
    varargin{2} = N;
    varargin{3} = dt;
    varargin{4} = pref;

% CASE 2. U = SPIN2('GL', 'PREF1', VALUE1) or U = SPINSPHERE(S, N, DT):
elseif ( nargin == 3 )

    % CASE 2.1. U = SPIN2('GL', 'PREF1', VALUE1):
    if ( isa(varargin{1}, 'char') == 1 && isa(varargin{2}, 'char') == 1 )
        [S, N, dt, pref] = parseInputs(varargin{1});
        pref.(varargin{2}) = varargin{3};
        varargin{1} = S;
        varargin{2} = N;
        varargin{3} = dt;
        varargin{4} = pref;

    % CASE 2.2. U = SPIN2(S, N, DT):
    else
        % Nothing to do here.
    end

% CASE 3. U = SPIN2(S, N, DT, PREF)
elseif ( nargin == 4 )
    % Nothing to do here.

% CASE 4.
elseif ( nargin >= 5 )

    % CASE 4.1. U = SPIN2('GL', 'PREF1', VALUE1, 'PREF2', VALUE2, ...)
    if ( isa(varargin{1}, 'char') == 1 && isa(varargin{2}, 'char') == 1 )
        [S, N, dt, pref] = parseInputs(varargin{1});
        j = 2;
        while j < nargin
            pref.(varargin{j}) = varargin{j+1};
            varargin{j} = [];
            varargin{j+1} = [];
            j = j + 2;
        end
        varargin{1} = S;
        varargin{2} = N;
        varargin{3} = dt;
        varargin{4} = pref;
        varargin = varargin(~cellfun(@isempty, varargin));

    % CASE 4.2. U = SPIN2(S, N, DT, 'PREF1', VALUE1, 'PREF2', VALUE2, ...)
    else
        pref = spinpref2();
        j = 4;
        while j < nargin
            pref.(varargin{j}) = varargin{j+1};
            varargin{j} = [];
            varargin{j+1} = [];
            j = j + 2;
        end
        varargin{4} = pref;
        varargin = varargin(~cellfun(@isempty, varargin));
    end

end

% SPIN2 is a wrapper for SOLVPDE:
[uout, tout] = spinoperator.solvepde(varargin{:});

end

function [S, N, dt, pref] = parseInputs(pdechar)
%PARSEINPUTS   Parse the inputs.

pref = spinpref2();
S = spinop2(pdechar);
if ( strcmpi(pdechar, 'GL') == 1 )
    dt = 1e-1;
    N = 128;
    pref.Clim = [-1 1];
    pref.iterplot = 2;
    pref.Nplot = 256;
elseif ( strcmpi(pdechar, 'GS') == 1 )
    dt = 5;
    N = 64;
    pref.Clim = [.25 .8 0 .35];
    pref.iterplot = 10;
    pref.Nplot = 128;
elseif ( strcmpi(pdechar, 'GSspots') == 1 )
    dt = 2;
    N = 64;
    pref.Clim = [.25 .85 0 .35];
    pref.iterplot = 25;
    pref.Nplot = 128;
elseif ( strcmpi(pdechar, 'SCHNAK') == 1 )
    dt = 5e-1;
    N = 64;
    pref.Clim = [.7 1.7 .65 1.05];
    pref.iterplot = 10;
    pref.Nplot = 128;
elseif ( strcmpi(pdechar, 'SH') == 1 )
    dt = 1;
    N = 128;
    pref.Clim = [-.4 .5];
    pref.iterplot = 4;
    pref.Nplot = 256;
end

end


%% compute predicted travel times for infrasound waves based on GPS coords & wind
%% also add lat, lon, distance and backaz fields to waveform objects
disp('Predicting travel times based on GPS coordinates and wind vector...')
fout = fopen(fullfile(figureOutDirectory, 'predictedTravelTimes.txt'), 'w');
fprintf(fout,'\n_______________________________________________\n');
fprintf(fout,'PREDICTED TRAVEL TIME BASED ON:\n');
fprintf(fout,'  sound speed(c) %.1fm/s\n', speed_of_sound);
fprintf(fout,'  wind speed     %.1fm/s\n', wind_speed);
fprintf(fout,'  wind direction %.1f degrees\n', wind_direction);
fprintf(fout,'------\t--------\t-----------\t----------\t-----------\n');
fprintf(fout,'Channel\tDistance\tBackAzimuth\tTravelTime\tc_effective\n');
fprintf(fout,'------\t--------\t-----------\t----------\t-----------\n');
for c=1:length(lat)
    [arclen(c), backaz(c)] = distance(lat(c), lon(c), source.lat, source.lon, 'degrees');
    arclen(c) = deg2km(arclen(c))*1000;
    effective_speed(c) = speed_of_sound + wind_speed * cos(deg2rad( (180+backaz(c)) - wind_direction) );
    predicted_traveltime_seconds(c) = arclen(c)/effective_speed(c);
    fprintf(fout,'%s\t%.1fm\t\t%.1f degrees\t%.3fs\t\t%.1fm/s\n',get(w(c),'channel'), arclen(c), backaz(c), predicted_traveltime_seconds(c),effective_speed(c));
    w(c) = addfield(w(c), 'lat', lat(c));
    w(c) = addfield(w(c), 'lon', lon(c));
    w(c) = addfield(w(c), 'distance', arclen(c));
    w(c) = addfield(w(c), 'backaz', backaz(c));
end
fprintf(fout,'_______________________________________________\n');
fprintf(fout,'Program name: %s\n',mfilename('fullpath'));
fclose(fout);


function f = erfz(zz)
%ERFZ  Error function for complex inputs
%   f = erfz(z) is the error function for the elements of z.
%   Z may be complex and of any size.
%   Accuracy is better than 12 significant digits.
%
%   Usage:  f = erfz(z)
%
%   Ref: Abramowitz & Stegun section 7.1
%   equations 7.1.9, 7.1.23, and 7.1.29
%
%   Tested under version 5.3.1
%
%   See also erf, erfc, erfcx, erfinc, erfcore

%   Main author Paul Godfrey <pgodfrey@intersil.com>
%   Small changes by Peter J. Acklam <jacklam@math.uio.no>
%   09-26-01

   error(nargchk(1, 1, nargin));

   % quick exit for empty input
   if isempty(zz)
      f = zz;
      return;
   end

   twopi = 2*pi;
   sqrtpi=1.772453850905516027298;

   f = zeros(size(zz));
   ff=f;

   az=abs(zz);
   p1=find(az<=8);
   p2=find(az> 8);

if ~isempty(p1)
   z=zz(p1);

   nn = 32;

   x = real(z);
   y = imag(z);
   k1 = 2 / pi * exp(-x.*x);
   k2 = exp(-i*2*x.*y);

   s1 = erf(x);

   s2 = zeros(size(x));
   k = x ~= 0;          % when x is non-zero
   s2(k) = k1(k) ./ (4*x(k)) .* (1 - k2(k));
   k = ~k;              % when x is zero
   s2(k) = i / pi * y(k);

   f = s1 + s2;

   k = y ~= 0;          % when y is non-zero
   xk = x(k);
   yk = y(k);

   s5 = 0;
   for n = 1 : nn
      s3 = exp(-n*n/4) ./ (n*n + 4*xk.*xk);
      s4 = 2*xk - k2(k).*(2*xk.*cosh(n*yk) - i*n*sinh(n*yk));
      s5 = s5 + s3.*s4;
   end
   s6 = k1(k) .* s5;
   f(k) = f(k) + s6;
   ff(p1)=f;
end

if ~isempty(p2)
   z=zz(p2);
   pn=find(real(z)<0);

   if ~isempty(pn)
      z(pn)=-z(pn);
   end

   nmax=193;
   s=1;
   y=2*z.*z;
   for n=nmax:-2:1
       s=1-n.*(s./y);
   end

   f=1.0-s.*exp(-z.*z)./(sqrtpi*z);

   if ~isempty(pn)
      f(pn)=-f(pn);
   end

   pa=find(real(z)==0);
%  fix along i axis problem
   if ~isempty(pa)
      f(pa)=f(pa)-1;
   end

   ff(p2)=f;
end

f=ff;

return

   %a demo of this function is
   x = -4:0.125:4;
   y = x;
   [X, Y] = meshgrid(x,y);
   z = complex(X, Y);
   f = erfz(z);
   af = abs(f);
   %let's truncate for visibility
   p = find(af > 5);
   af(p) = 5;
   mesh(x, y, af);
   view(-70, 40);
   rotate3d on;

   return


function x = gumbel_cdf_inv ( cdf )

%*****************************************************************************80
%
%% GUMBEL_CDF_INV inverts the Gumbel CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real CDF, the value of the CDF.
%    0.0 <= CDF <= 1.0.
%
%    Output, real X, the corresponding argument of the CDF.
%
  if ( cdf < 0.0 | 1.0 < cdf )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'GUMBEL_CDF_INV - Fatal error!\n' );
    fprintf ( 1, '  CDF < 0 or 1 < CDF.\n' );
    error ( 'GUMBEL_CDF_INV - Fatal error!' );
  end

  x =  - log ( - log ( cdf ) );

  return
end


function Vpolicy = mdp_eval_policy_matrix(P, R, discount, policy)

% mdp_eval_policy_matrix    Evaluation of the value function of a policy
% Arguments -------------------------------------------------------------
% Let S = number of states, A = number of actions
%   P(SxSxA) = transition matrix
%              P could be an array with 3 dimensions or
%              a cell array (1xA), each cell containing a matrix (SxS) possibly sparse
%   R(SxSxA) or (SxA) = reward matrix
%              R could be an array with 3 dimensions (SxSxA) or
%              a cell array (1xA), each cell containing a sparse matrix (SxS) or
%              a 2D array(SxA) possibly sparse
%   discount = discount rate in ]0; 1[
%   policy(S) = a policy
% Evaluation -------------------------------------------------------------
%   Vpolicy(S) = value function of the policy

% MDPtoolbox: Markov Decision Processes Toolbox
% Copyright (C) 2009  INRA
% Redistribution and use in source and binary forms, with or without modification,
% are permitted provided that the following conditions are met:
%    * Redistributions of source code must retain the above copyright notice,
%      this list of conditions and the following disclaimer.
%    * Redistributions in binary form must reproduce the above copyright notice,
%      this list of conditions and the following disclaimer in the documentation
%      and/or other materials provided with the distribution.
%    * Neither the name of the <ORGANIZATION> nor the names of its contributors
%      may be used to endorse or promote products derived from this software
%      without specific prior written permission.
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
% IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
% OF THE POSSIBILITY OF SUCH DAMAGE.

% check of arguments
if iscell(P); S = size(P{1},1); else S = size(P,1); end;
if discount <= 0 || discount >= 1
    disp('--------------------------------------------------------')
    disp('MDP Toolbox ERROR: Discount rate must be in ]0; 1[')
    disp('--------------------------------------------------------')
elseif size(policy,1)~=S || any(mod(policy,1)) || any(policy<1) || any(policy>S)
    disp('--------------------------------------------------------')
    disp('MDP Toolbox ERROR: policy must be a (1xS) vector with integer from 1 to S')
    disp('--------------------------------------------------------')
else

    [Ppolicy, PRpolicy] = mdp_computePpolicyPRpolicy(P, R, policy);

    % V = PR + gPV  => (I-gP)V = PR  => V = inv(I-gP)*PR
    Vpolicy = (speye(S,S) - discount*Ppolicy) \ PRpolicy;

end


function fx = p04_fun ( option, nvar, x )

%*****************************************************************************80
%
%% P04_FUN evaluates the function for problem 4.
%
%  Title:
%
%    The Broyden function
%
%  Description:
%
%    The function F is derived via homotopy from a simpler function G:
%
%      F(X(1),X(2),X(3)) = g(X(1),X(2)) + (X(3)-1) * G(Y1,Y2).
%
%    with
%
%      (Y1,Y2) some starting point,
%
%    and
%
%      G(1) = 0.5*sin(X(1)*X(2)) - X(2)/PI - X(1)
%      G(2) = (1-1/(4*PI))*(exp(2*X(1))-E) + E*X(2)/PI- 2*E*X(1)
%
%    where "E" = exp(1).
%
%  Options:
%
%    The only option starts with (0.4, 3, 0), and seeks the target
%    solution whose third component is 1.  The correct value of the
%    target solution is
%
%      ( -0.2207014, 0.8207467, 1.0D+00 )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Charles Broyden,
%    A New Method of Solving Nonlinear Simultaneous Equations,
%    The Computer Journal,
%    Volume 12, 1969, pages 94-99.
%
%  Parameters:
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Input, real X(NVAR), the argument of the function.
%
%    Output, real FX(NVAR-1), the value of the function at X.
%

%
%  Get the starting point.
%
  y = p04_start ( option, nvar );
%
%  Get the function value at the starting point and at the
%  current point.
%
  gy = p04_gx ( y );
  gx = p04_gx ( x );
%
%  Use X3 to compute a homotopy.
%
  for i = 1 : nvar-1
    fx(i) = gx(i) + ( x(3) - 1.0 ) * gy(i);
  end

  return
end


% p23 例5 埃特金逐步插值
clear;
format long;
x = 0.3 :0.1 : 0.7;
y = [0.29850, 0.39646, 0.49311, 0.58813, 0.68122];
xx = 0.462; % 插值点
fij(:,1) = y;
for i = 1 : 3
    for j = i+1 : 5
       fij(j,i+1) = fij(i,i)*(xx-x(j))/(x(i)-x(j)) + fij(j,i)*(xx-x(i))/(x(j)-x(i))  % 显示中间结果，体现迭代
    end
end
fij


function svd_snowfall_test04 ( x )

%*****************************************************************************80
%
%% SVD_SNOWFALL_TEST04 looks at the first 6 modes in the U matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 May 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X(8,123), the snowfall data.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SVD_SNOWFALL_TEST04\n' );
  fprintf ( 1, '  Look at the first 6 modes in the U matrix.\n' );
  fprintf ( 1, '  Each of these represents a pattern for snowfall over a year.\n' );
  fprintf ( 1, '  The first mode is the pattern that is strongest in the data.\n' );
%
%  Compute the SVD.
%
  [ u, s, v ] = svd ( x );
%
%  Normalize the patterns so that each column has maximum entry 1.
%
  us = r8col_normalize_li ( 8, 8, u );
%
%  Plot the modes.
%
  t = 1 : 8;

  figure ( 4 )

  subplot ( 2, 3, 1 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,1), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #1' )
  hold off

  subplot ( 2, 3, 2 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,2), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #2' )
  hold off

  subplot ( 2, 3, 3 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,3), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #3' )
  hold off

  subplot ( 2, 3, 4 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,4), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #4' )
  hold off

  subplot ( 2, 3, 5 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,5), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #5' )
  hold off

  subplot ( 2, 3, 6 )
  hold on
  plot ( [1,8], [0,0], 'r-' )
  plot ( t, us(:,6), 'b-', 'Linewidth', 3 )
  axis ( [1,8,-1.0,+1.0] )
  grid on
  title ( 'U Mode #6' )
  hold off

  print ( '-dpng', 'u_modes.png' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Plotted U modes 1 to 6 in "u_modes.png".\n' );

  return
end


function [ pl, pld ] = p12_legendre_val ( t, dtdx, npolys )

%*****************************************************************************80
%
%% P12_LEGENDRE_VAL evaluates the Legendre polynomials and derivatives.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real T, the argument of the Legendre polynomials, in
%    the normalized interval [-1,1].
%
%    Input, real DTDX, the value of the quantity dTdX at the point
%    X.  In the most common case, this is simply the relationship
%    between the width of the normalized T interval (2), and the
%    width of the X interval to which the Legendre polynomial
%    arguments have been mapped.  DTDX is needed so that the
%    computed values PLD can be converted from dPL/dT to dPL/dX.
%
%    Input, integer NPOLYS, the number of Legendre polynomials to
%    evaluate.  If NPOLYS is 1, then only the constant polynomial
%    is evaluated,  NPOLYS = 2 means the constant and linear, and so on.
%
%    Output, real PL(NPOLYS), PLD(NPOLYS), the values of PL(X)
%    and dPL(X)/dX at the point X which has normalized coordinate T.
%
  if ( 1 <= npolys )
    pl(1) = 1.0;
    pld(1) = 0.0;
  end

  if ( 2 <= npolys )
    pl(2) = t;
    pld(2) = 1.0;
  end

  a = 0.0;
  for i = 3 : npolys

    a = a + 1.0;

    pl(i) = ( ( 2.0 * a + 1.0 ) * t * pl(i-1) - a * pl(i-2) ) / ( a + 1.0 );

    pld(i) = ( ( 2.0 * a + 1.0 ) * ( t * pld(i-1) + pl(i-1) ) ...
           - a * pld(i-2) ) / ( a + 1.0 );

  end

  pld(1:npolys) = dtdx * pld(1:npolys);

  return
end


function SStar=covMatEstShrinkage(x,centerData,algorithm)
%%COVMATESTSHRINKAGE When estimating a covariance matrix from a small
%           number of samples, it can occur that the resultng estimate is
%           poorly conditioned. This function estimates the covariance
%           matrix from samples using one of two shrinkage estimators that
%           are mean to avoid poor conditioning and that can produce more
%           accurate (in terms of the squared Frobenius norm) estimates
%           than one can obtain from the sample covariance matrix.
%
%INPUTS: x A pXn matrix of n samples of a p-dimensional distribution.
% centerData If the samples in x are zero mean or the mean has been
%          subtracted from them, then centerData can be false. Otherwise,
%          centerData should be true to center the data (subtract the
%          sample mean). The algorithmic choices assume that the true mean
%          has been subtracted, so subtracting the sample mean might affect
%          the performance. The default if omitted or an empty matrix is
%          passd is true.
% algorithm An optional parameter selecting the algorithm to use. Possible
%          values are:
%          0 (The default if omitted or an empty matrix is passed) Use the
%            Ledoit-Wolf algorithm of [1].
%          1 Use the empirical Bayesian estimator (the Hanff estimator),
%            which is also described in [1].
%
%OUTPUTS: SStar The pXp covariance matrix estimate.
%
%Note that the algorithms are not unbiased. However, the Ledoit-Wolf
%algorithm is shown in [1] to be asymptotically unbiased (as n gets large
%keeping p/n fixed).
%
%EXAMPLE:
%Here, we look at the performance when considering random diagonal
%covariance matrices whose elements are drawn from the log-normal
%distribution. We look at the percentage relative improvement in average
%loss (PRIAL) criterion, which is essentially the relative improvement in
%the squared Frobenius norm of the error of the sample covariance matrix
%versus the Ledoit-Wolf covariance matrix esitmate.
% numRuns=10000;
% p=20;
% n=40;
% %Parameters for the log-normal distribution from which the covariance
% %matrix is drawn.
% mu=1;
% Sigma=1;
% centerData=false;
%
% SSigmaFro2=0;
% SStarSigmaFro2=0;
% for curRun=1:numRuns
%     x=LogNormalD.rand(p,mu,Sigma);
%     X=diag(x);%The current covariance matrix.
%     SX=cholSemiDef(X,'lower');
%     x=SX*randn(p,n);%Zero mean.
%
%     S=(1/n)*(x*x');%Sample covariance matrix.
%     SStar=covMatEstShrinkage(x,centerData);
%
%     SSigmaFro2=SSigmaFro2+norm(S-Sigma,'fro')^2;
%     SStarSigmaFro2=SStarSigmaFro2+norm(SStar-Sigma,'fro')^2;
% end
% SSigmaFro2=SSigmaFro2/numRuns;
% SStarSigmaFro2=SStarSigmaFro2/numRuns;
% PRIAL=(SSigmaFro2-SStarSigmaFro2)/SSigmaFro2
%One will typically see that the PRIAL is positive, around 0.08, indicating
%that the Ledoit-Wolf covariance matrix esitmate is 8% better than the
%sample covariance estimate. It was empirically noticed that setting
%centerData=true will further improve the performance on this example even
%though the samples generated are already zero-mean.
%
%REFERENCES:
%[1] O. Ledoit and M. Wolf "A Well-conditioned estimator for large-
%    dimensional covariance matrices," Journal of Multivariate Analysis,
%    vol. 88, no. 2, pp. 365-411, 2004.
%
%October 2018 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<3||isempty(algorithm))
    algorithm=0;
end

if(nargin<2||isempty(centerData))
    centerData=true;
end

if(centerData)
    x=bsxfun(@minus,x,mean(x,2));
end

p=size(x,1);
n=size(x,2);
%The sample covariance matrix.
S=(1/n)*(x*x');

switch(algorithm)
    case 0%The Ledoit-Wolf covariance estimator.
        %Lemma 3.2
        m=trace(S)/p;

        %Lemma 3.3
        d2=norm(S-diag(m),'fro')^2;

        %Lemma 3.4
        b2Bar=0;
        for k=1:n
            b2Bar=b2Bar+norm(x(:,k)*x(:,k)'-S,'fro')^2;
        end
        b2Bar=(1/n^2)*b2Bar;
        b2=min(b2Bar,d2);

        %Lemma 3.5
        a2=d2-b2;

        %Equation 14
        SStar=(b2/d2)*diag(m)+(a2/d2)*S;
    case 1%The empirical Bayesian estimator (Haff estimator).
        mEB=det(S)^(1/p);
        if(mEB<=0||~isreal(mEB))
            mEB=trace(S)/p;
        end

        SStar=((p*n-2*n-2)/(p*n^2))*diag(mEB)+(n/(n+1))*S;
    otherwise
        error('Unknown algorithm specified.')
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.


function [F,J] = bananaobj(x)
% Evaluate the vector function and the Jacobian matrix for
% the system of nonlinear equations derived from the general
% n-dimensional Rosenbrock function.
% Get the problem size
n = length(x);
if n == 0, error('Input vector, x, is empty.'); end
if mod(n,2) ~= 0,
   error('Input vector, x, must have an even number of components.');
end
% Evaluate the vector function
odds  = 1:2:n;
evens = 2:2:n;
F=x(:);
% F = zeros(n,1);
F(odds,1)  = 1-x(odds);
F(evens,1) = 10.*(x(evens)-x(odds).^2);
% Evaluate the Jacobian matrix if nargout > 1
if nargout > 1
   c = -ones(n/2,1);    C = sparse(odds,odds,c,n,n);
   d = 10*ones(n/2,1);  D = sparse(evens,evens,d,n,n);
   e = -20.*x(odds);    E = sparse(evens,odds,e,n,n);
   J = C + D + E;
end


function [xm xcov] = UT(Xi, W, noiseCov)
%
%
[n, kmax] = size(Xi);

xm = 0;
for k=1:kmax
  xm = xm + W(k)*Xi(:, k);
end

xcov = zeros(n, n);
for k=1:kmax
  xcov = xcov + W(k)*(Xi(:, k) - xm)*(Xi(:, k) - xm)';
end
xcov = xcov + noiseCov;


function [out] = ReedSolomon(random,codeRS,Tx);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                       %
%%     Name: ReedSolomon.m                                               %
%%                                                                       %
%%     Description: The Reed-Solomon encoder is realized according to    %
%%      the standard.                                                    %
%%                                                                       %
%%     Parameters:                                                       %
%%      Sequence of bits to endoe with the algorithm.                    %
%%                                                                       %
%%     Result: It gives back the encoded bits according to the need      %
%%      and also following the modulation.                               %
%%                                                                       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 m = 8;                          % Number of bits per symbol
 n = codeRS(1);                  % Length of the codeword
 k = codeRS(2);                  % Number of information symbols

 % To realize the Reed-Solomon code, the information is needed in decimal.

  random = reshape(random,8,length(random)/8)';
  random = bi2de(random,'left-msb');

if Tx==1
    % 36 bytes are needed with a stuffed zero at the end of the vector:
     yk=[random' 0];

    % The Galois vector is generated, the generating polynomial of the
    % code. Then the symbols are encoded with Reed-Solomon.
    msg = gf([yk],m);
    if n==k                      % bypass for BPSK
        codeRS = msg;
    elseif n~=k
        codeRS = rsenc(msg,n,k);
    end
    out = codeRS.x;

elseif Tx==0
    yk = random;            % In the receiver, nothing needs to be completed.

    msg = gf([yk],m);           % In this case, the encoding is undone.
    if n==k
        codeRS = yk;
    elseif n~=k
        codeRS = rsdec(msg',n,k);
        codeRS = codeRS.x;
    end
    out = codeRS(1:end-1);
end

% The binary data to continue working:
 out = double (out);
 out = de2bi (out,8,'left-msb');

% Serial the data for the next step.
 out = reshape (out', 1, length(out)*8);


function [out] = phenology_2(p1,p2,p3,t,tmax,dt)
%phenology_2

% 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:  Phenology-based maximum interception capacity (returns store size [mm])
% Constraints:  Implicit assumption: 0 <= p2 <= 1
% @(Inputs):    p1   - mean interception capacity [mm]
%               p2   - seasonal change as fraction of the mean [-]
%               p3   - time of maximum store size [d]
%               t    - current time step [-]
%               tmax - seasonal length [d]
%               dt   - time step size [d]

out = p1*(1+p2*sin(2*pi*(t*dt-p3)/tmax));

end


%CREATETREFOILKNOT Create a 3D mesh around a trefoild curve
%
%   [X, Y, Z] = createTrefoilKnot;
%   [X, Y, Z] = createTrefoilKnot(NPTS);
%
%   Example
%   createTrefoilKnot
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@grignon.inra.fr
% Created: 2015-01-07,    using Matlab 8.4.0.150421 (R2014b)
% Copyright 2015 INRA - Cepia Software Platform.

%% Constants

% number of vertices of trefoil curve
nPoints = 200;

% thickness of the 3D mesh
thickness = .5;

% number of corners around each curve vertex
nCorners = 16;

%% Create trefoil curve

% parameterisation variable
t = linspace(0, 2*pi, nPoints + 1);
t(end) = [];

% trefoil curve coordinates
curve(:,1) = sin(t) + 2 * sin(2 * t);
curve(:,2) = cos(t) - 2 * cos(2 * t);
curve(:,3) = -sin(3 * t);

% display curve
figure;
drawPolyline3d(curve, 'LineWidth', 4, 'color', 'b');
axis equal; view(3);
axis([-4 4 -4 4 -2 2]);

%% Create surrounding mesh

% compute mesh
[v2, f2] = curveToMesh(curve, thickness, nCorners);

% display mesh
drawMesh(v2, f2, 'FaceAlpha', 0.5);


function [ fea, out ] = ex_diffusion2( varargin )
%EX_DIFFUSION2 1D Time dependent diffusion equation examples.
%
%   [ FEA, OUT ] = EX_DIFFUSION2( VARARGIN ) 1D time dependent diffusion equation on
%   a line with exact solutions. Accepts the following property/value pairs.
%
%       Input       Value/{Default}        Description
%       -----------------------------------------------------------------------------------
%       nu          scalar {1e-1}          Diffusion coefficient
%       icase       scalar {2}             Test case
%       hmax        scalar {1/25}          Max grid cell size
%       dt          scalar {0.1}           Time step size
%       ischeme     scalar {3}             Time stepping scheme
%       sfun        string {sflag1}        Shape function
%       iplot       scalar 0/{1}           Plot solution (=1)
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       fea         struct                 Problem definition struct
%       out         struct                 Output struct

% Copyright 2013-2022 Precise Simulation, Ltd.

cOptDef = { ...
  'nu',       1e-1; ...
  'icase',    2; ...
  'hmax',     1/25; ...
  'dt'        0.1; ...
  'ischeme'   3; ...
  'sfun',     'sflag1'; ...
  'iplot',    1; ...
  'tol',      1e-2; ...
  'fid',      1 };
[got,opt] = parseopt(cOptDef,varargin{:});
fid       = opt.fid;

tmax = 1;
switch( opt.icase )
  case 1
    refsol = '(1-x)*2.2+x*3.3';
  case 2
    n = 1;
    refsol = ['exp(-',num2str(opt.nu*n^2*pi^2),'*t)*sin(',num2str(n*pi),'*x)'];
end

% Grid generation.
fea.grid = linegrid( 1/opt.hmax, 0, 1 );

% Problem definition.
fea.sdim  = { 'x' };
fea = addphys( fea, @convectiondiffusion );
fea.phys.cd.sfun = { opt.sfun };
fea.phys.cd.eqn.coef{2,4} = { opt.nu };
fea = parsephys(fea);

% Parse and solve problem.
x = fea.grid.p';
n = length(x);
if( strcmp( opt.sfun,'sflag2' ) )
  x = [ x; (x(2:end)+x(1:end-1))/2 ];
end
t   = 0;
u0  = eval( refsol );
fea = parseprob( fea );
if( opt.ischeme>0 )

  fea.bdr.d{1} = refsol;
  fea.bdr.d{2} = refsol;
  fea.bdr.n    = cell(1,2);
  [fea.sol.u,tlist] = solvetime( fea, 'fid', fid, 'init', u0, 'ischeme', opt.ischeme, 'tstep', opt.dt, 'tmax', tmax, 'nstbwe', 0, 'tstop', 0, 'imass', 2 );

else

  [M,A,f] = assembleprob( fea, 'f_m', 1, 'imass', 1, 'f_a', 1, 'f_f', 1, 'f_sparse', 1 );
  M = spdiags( full(sum(M')'), 0, size(M,1), size(M,1) );
  fea.sol.u = u0;
  dt = opt.dt;
  it = 0;
  tlist = 0;
  if( opt.ischeme==-1 )       % Crank-Nicolson.
    C = [ M + dt/2*A ];
  elseif( opt.ischeme==-2 )   % Backward Euler.
    C = [ M + dt*A ];
  end
  C(1,:) = 0;
  C(1,1) = 1;
  C(n,:) = 0;
  C(n,n) = 1;
  while 1
    t  = t  + dt;
    it = it + 1;

    u_r = eval( refsol );
    if( opt.ischeme==-1 )       % Crank-Nicolson.
      b = [ [ M - dt/2*A ]*u0 + dt*f ];
    elseif( opt.ischeme==-2 )   % Backward Euler.
      b = [ M*u0 + dt*f ];
    end
    b(1) = u_r(1);
    b(n) = u_r(n);

    u1 = C\b;

    if( t>=tmax )
      break
    end

    err = norm( u1 - u_r )/norm( u_r );
    errnm(it) = err;
    if( ~isempty(fid) )
      fprintf( fid, 'Time = %f, error norm = %d\n', t, err );
    end

    fea.sol.u = [ fea.sol.u u1 ];
    tlist = [ tlist t ];
    u0 = u1;
  end

end

% Postprocessing.
if( opt.iplot>0 )
  figure;
  if( opt.iplot>1 )
    i_sol_list = 1:numel(tlist);
  else
    i_sol_list = numel(tlist);
  end
  [~,ix] = sort( x );
  for i_sol=i_sol_list
    t = tlist(i_sol);
    clf
    postplot( fea, 'surfexpr', 'c', 'solnum', i_sol );
    hold on
    u_r = eval( refsol );
    plot( sort(x), u_r(ix), 'r--' );
    title( ['Solution at time ',num2str(t)])
    xlabel( 'x' )
    drawnow
  end
end

% Error checking.
for i_sol=1:numel(tlist)
  u_i = fea.sol.u(:,i_sol);
  t   = tlist(i_sol);
  u_r = eval( refsol );
  errnm(i_sol) = norm( u_i - u_r )/norm( u_r );
end
out.err  = errnm;
out.pass = all( errnm<opt.tol );

if ( nargout==0 )
  clear fea out
end


function triangulation_test213 ( )

%*****************************************************************************80
%
%% TEST213 tests TRIANGULATION_ORDER3_QUAD.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 January 2007
%
%  Author:
%
%    John Burkardt
%
  quad_num = 6;

  quad_w = [ ...
    0.1666666666666666, ...
    0.1666666666666666, ...
    0.1666666666666666, ...
    0.1666666666666666, ...
    0.1666666666666666, ...
    0.1666666666666666 ];
  quad_xy = [ ...
    0.659027622374092,  0.231933368553031; ...
    0.659027622374092,  0.109039009072877; ...
    0.231933368553031,  0.659027622374092; ...
    0.231933368553031,  0.109039009072877; ...
    0.109039009072877,  0.659027622374092; ...
    0.109039009072877,  0.231933368553031  ]';
  test_num = 4;
  triangle_order = 3;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST213\n' );
  fprintf ( 1, '  TRIANGULATION_ORDER3_QUAD can apply a quadrature rule\n' );
  fprintf ( 1, '  to every triangle in a triangulated region,\n' );
  fprintf ( 1, '  and estimate the integral of a function over\n' );
  fprintf ( 1, '  that region.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  NODE_NUM   TRI_NUM  Integral estim  Area of Region\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
%
%  Set up the grid.
%
    n = 2^( test - 1 );
    node_num = ( n + 1 ) * ( n + 1 );

    node_xy = zeros(2,node_num);

    k = 0;
    for j = 1 : n + 1
      y = ( j - 1 ) / ( n + 1 - 1 );
      for i = 1 : n + 1
        x = ( i - 1 ) / ( n + 1 - 1 );
        k = k + 1;
        node_xy(1:2,k) = [ x, y ]';
      end
    end
%
%  Set up the triangulation.
%
    triangle_num = 2 * n * n;

    triangle_node = zeros(triangle_order,triangle_num);

    k = 0;
    for j = 1 : n
      for i = 1 : n

        n11 = i     + ( j     - 1 ) * ( n + 1 );
        n12 = i     + ( j + 1 - 1 ) * ( n + 1 );
        n21 = i + 1 + ( j     - 1 ) * ( n + 1 );
        n22 = i + 1 + ( j + 1 - 1 ) * ( n + 1 );

        k = k + 1;
        triangle_node(1:triangle_order,k) = [ n11, n21, n12 ]';
        k = k + 1;
        triangle_node(1:triangle_order,k) = [ n22, n12, n21 ]';

      end
    end
%
%  Estimate the integral.
%
    [ quad_value, region_area ] = triangulation_order3_quad ( node_num, ...
      node_xy, triangle_order, triangle_num, triangle_node, @quad_fun, ...
      quad_num, quad_xy, quad_w );

    fprintf ( 1, '  %8d  %8d  %14f  %14f\n', ...
      node_num, triangle_num, quad_value, region_area );
%
%  Delete arrays.
%
    node_xy = [];
    triangle_node = [];

  end

  return
end


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni
%
%
% Problem 5- System response to sinusoidal input

w0=2*pi;
Hw0=(3*(j*w0)^2+4*j*w0+2)/((j*w0)^2+2*j*w0+1);
mag=abs(Hw0);
phas=angle(Hw0);
t=0:.1:5;
y=3*mag*cos(w0*t+pi/2+phas);
plot(t,y)
legend('Output signal y(t)')


function FEVD = fevd(hor,Phi,Sigma,Omega)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% computes the forecast error variance decomposition using the VAR
% representation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

N           = size(Sigma,1);
[m , k]     = size(Phi);
if rem(m, k)==0
    lags = m/k;
else
    lags = floor((m-1)/k);
end

if nargin < 4
    Omega = eye(N);
end

% companion
F       = [Phi(1 : N * lags, :)'; eye(N*(lags-1), N*lags)];
G       = eye(N * lags, N);
%C       = [Phi(end, :)'; zeros(N*(lags-1),1)];

A     = chol(Sigma,'lower');
Kappa = G * A * Omega ;

tmp_=0;
for hh  = 1 : hor
    tmp_ = tmp_ + F^(hh-1) * Kappa * Kappa' * F^(hh-1)';
end
out_.all_var_  =  diag(tmp_(1:N,1:N));

for sho =1 : N
    tmp_1 = 0;
    Ind              = zeros(N);
    Ind(sho,sho) = 1;
    for hh  = 1 : hor
        tmp_1 = tmp_1 + F^(hh-1) * Kappa * Ind * Kappa' * F^(hh-1)';

    end
    out_.var_(:,sho) = diag(tmp_1(1:N,1:N));
end

if max(max(abs( sum(out_.var_,2) - out_.all_var_))) > 1e-10
    error('Something went wrong')
end

for indx_sho = 1 : N
    FEVD(:,indx_sho) = out_.var_(:,indx_sho)./out_.all_var_*100;

end


function [W, funcVal] = Least_NCFGLassoF2(X, Y, lambda, beta, opts)
% Non-Convex Fused Group Lasso with Least Squares Loss (Formulation 2).
% By Jiayu Zhou (jiayu.zhou@asu.edu) Dec. 2011

% Objective (Non-Convex):
% argmin_W { \sum_{i=1}^t (0.5 * norm (Y{i} - X{i}' * W(:, i))^2)
%    + lambda * \sum_{i=1}^d \sqrt{ \|R * W(i, :)\|_1 + beta  * \|W(i, :)\|_1}
%          }
%
% t - task number
% d - dimension
% n - sample size
%
% lambda: joint feature selection
% beta:   Lasso sparsity.
% R encodes fused structure relationship [1 -1 0 ...; 0 1 -1 ...; ...]
%    R=zeros(t,t-1);R(1:(t+1):end)=1;R(2:(t+1):end)=-1;

%%% input
% X: {d * n} * t - input matrix
% Y: {n * 1} * t - output matrix
% lambda: 1        - joint feature selection
% beta:   1        - Lasso sparsity.

if nargin <5
    opts = [];
end

if isfield(opts, 'max_iter')
    max_iter = opts.max_iter;
else
    max_iter = 20;
end

if isfield(opts, 'tol_funcVal')
    tol_funcVal = opts.tol_funcVal;
else
    tol_funcVal = 10^-6;
end

task_num  = length (X);
dimension = size(X{1}, 1);

% Relation
R=zeros(task_num,task_num-1);
R(1:(task_num+1):end)=1;
R(2:(task_num+1):end)=-1;
R = R';

if isfield(opts, 'starting_point')
    %fprintf('Least_NCFGLassoF2: Init model used\n');
    W0 = opts.starting_point;
else
    %W0 = rand(dimension, task_num);
    [W0] = Least_FGLasso(X, Y, lambda*beta, lambda);
end

epsilon = 10e-12; % should be slight larger than machine error.

funcVal = funcVal_eval (W0);

inner_iteration_opts.max_iter = 100;
inner_iteration_opts.tol_funcVal = 10^-7;

iter = 0;
while iter < max_iter
    % reweigting vector.

    rho1 = zeros(dimension, 1); % weighted Lasso
    rho2 = zeros(dimension, 1); % weighted Fused Lasso
    for t = 1: dimension
        rho2(t) = lambda / (2 * sqrt(norm(W0(t, :),1) + norm(R * W0(t, :)', 1) + epsilon));
        rho1(t) = rho2(t) * beta;
    end

    [W, sub_funcVal] = Least_Weight2FGLasso(X, Y, rho1, rho2, inner_iteration_opts);

    funcVal = cat(1, funcVal, funcVal_eval (W));

    % test stop condition.
    if length(funcVal)> 1 &&...
            (abs(funcVal(end-1) - funcVal(end))/ funcVal(end))<=tol_funcVal
        break;
    end

    iter = iter + 1;
    W0 = W;

end

    function [funcVal] = funcVal_eval (W)
        funcVal = 0;
        for i = 1: task_num
            funcVal = funcVal + 0.5 * norm (Y{i} - X{i}' * W(:, i))^2;
        end
        % non-smooth part
        for i = 1 : size(W, 1) % dimension
            w = W(i, :);
            funcVal = funcVal ...
                + lambda * sqrt(norm(R * w', 1) + beta * norm(w, 1));
        end
    end

end


function pers=categorical_persistence(S)
% CATEGORICAL_PERSISTENCE computes the persistence of an unordered multilayer partition
%
% Version: 2.2.0
% Date: Thu 11 Jul 2019 12:25:42 CEST
%
% pers = categorical_PERSISTENCE(S) with a single multilayer partition or a
% cell of multilayer partitions S (with S{i} the ith multilayer partition of
% cell S) computes the "persistence" of multilayer partitions. The output pers
% is a vector such that pers(i) is the persistence of multilayer partition
% S{i} (stored as an N*T matrix where N is the number of nodes in each layer
% and T is the number of layers). For a multilayer network with unordered
% layers, the value of persistence is the sum over all pairs of layers of
% the number of nodes that do not change community assignments. Categorical
% persistence varies between 0 and 1. Categorical persistence is related to
% the multilayer quality function developed in Mucha et al. 2010 when one
% uses categorical interlayer coupling.
%
%   References:
%
%     Mucha, Peter J., Thomas Richardson, Kevin Macon, Mason A. Porter, and
%     Jukka-Pekka Onnela. "Community Structure in Time-Dependent,
%     Multiscale, and Multiplex Networks," Science 328, 876-878 (2010).
%
%     Bazzi, Marya, Mason A. Porter, Stacy Williams, Mark McDonald, Daniel
%     J. Fenn, and Sam D. Howison. "Community Detection in Temporal
%     Multilayer Networks, with an Application to Correlation Networks",
%     MMS: A SIAM Interdisciplinary Journal 14, 1-41 (2016).

if ~iscell(S)
    S={S};
end

[N,T]=size(S{1});
all2all = N*[(-T+1):-1,1:(T-1)];
A=spdiags(ones(N*T,2*T-2),all2all,N*T,N*T);
pers=zeros(length(S),1);
for i=1:length(S)

    G=sparse(1:length(S{i}(:)),S{i}(:),1);
    pers(i)=trace(G'*A*G)/(N*T*(T-1));
end

end


%--------------------------------------------------------------------------
%   [yn,ref_dn,W,en] = lms2(xn,dn,M,mu)
%--------------------------------------------------------------------------
%   功能：
%   LMS自适应滤波器 带通道时延
%--------------------------------------------------------------------------
%   输入:
%           xn  输入信号的序列 列向量
%           dn  所期望的响应序列 列向量
%           M   滤波器阶数
%           mu  收敛因子(步长)
%   输出:
%           W   滤波器的权值矩阵     大小为M * iter
%           en  误差序列（itr * 1） 列向量
%           yn  实际输出序列        列向量
%--------------------------------------------------------------------------
%   例子：
%   暂无
%--------------------------------------------------------------------------
function [yn,ref_dn,W,en] = lms2(xn,dn,M,mu)
if rem(M,2)==0
    disp('请将滤波器阶数为奇数')
    return
end

w_ref = [zeros((M-1)/2,1);1;zeros((M-1)/2,1)];                              %正常延迟信号 延迟(M-1)/2个点
xn = xn(:);
dn =conv(w_ref,dn(:));                                                      %正常信号延迟
ref_dn = dn;
itr = length(xn);
en = zeros(itr,1);                                                          %误差序列，en(k)表示第k次迭代时预期输出与实际输出的误差
W = zeros(M,itr);                                                           %滤波器的权值矩阵（矩阵）
%--------------------------------------------------------------------------
%   迭代计算
%--------------------------------------------------------------------------
for idx = M:itr                                                             %第k次迭代
    x = xn(idx:-1:idx-M+1);                                                 %滤波器M个抽头的输入
    y = W(:,idx-1).'*x;                                                     %滤波器的输出
    en(idx) = dn(idx) - y;                                                  %第k次迭代的误差
    %----------------------------------------------------------------------
    %   滤波器权值计算的迭代式
    %----------------------------------------------------------------------
    W(:,idx) = W(:,idx-1) + 2*mu*en(idx)*x;
end

%--------------------------------------------------------------------------
%   求最优时滤波器的输出序列，r如果没有yn的返回参数可以不要下面的
%--------------------------------------------------------------------------
yn = conv(W(:,end),xn);


function [masks,keepLocs] = maskGaussians( siz, M, width, offset, show )
% Divides a volume into softly overlapping gaussian windows.
%
% Return M^nd masks each of size siz.  Each mask represents a symmetric
% gaussian window, the locations are evenly spaced throughout the array of
% size siz.  For example, if M=2, then along each dimension d the location
% of each mask is either 1/4 or 3/4 of siz(d) and likewise if M=3 that mask
% is at 1/6,3/6, or 5/6 of siz(d). For higher M the locations are:
% 1/2M,3/2M,...,M-1/2M. See examples below to visualize the masks.
%
% The std of each gaussian is set to be equal to the spacing between two
% adjacent masks multiplied by width.  Reducing the widths of the gaussians
% causes there to be less overlap between masks, but if the width is
% reduced too far certain pixels in between masks receive very little
% weight.  A desired property of the masks is that their coverage (the
% total weight placed on the pixel by all the masks) is approximately
% constant.  Typically, we settle for having the coverage be monotonically
% decreasing as we move away from the center.  (In reality the coverage
% oscilates as we move past peaks, it's just that the oscillations tend to
% be small).  The default value of the width is .6, which minimizes overlap
% while still providing good overall coverage. Values lower tend to produce
% noticeable oscillations in coverage.  offset in (-.5,1) controls the
% spacing of the locations.  Essentially, a positive offset moves the
% locations away from the center of the array and a negative offset moves
% the windows away from the center.  Using a positive offset gives better
% coverage to areas near the borders.
%
% USAGE
%  [masks,keepLocs] = maskGaussians( siz, M, [width], [offset], [show] )
%
% INPUTS
%  siz         - dimensions of each mask
%  M           - # mask locations along each dim [either scalar or vector]
%  width       - [.6] widths of the gaussians
%  offset      - [.1] spacing of mask centers; in (-.5,1)
%  [show]      - [0] figure to use for display (no display if==0) (nd<=3)
%
% OUTPUTS
%  masks       - [see above] array of size [siz x M^nd]
%  keepLocs    - logical array of all locs where masks is nonzero
%
% EXAMPLE
%  masks = maskGaussians( 100, 10, .6, -.1, 1 );  %1D
%  masks = maskGaussians( [35 35], 3, .6, .1, 1 );  %2D
%  masks = maskGaussians( [35 35 35], [2 2 4], .6, .1, 1 ); %3D
%
% See also HISTCIMLOC, MASKCIRCLE
%
% Piotr's Computer Vision Matlab Toolbox      Version 2.0
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

nd = length(siz);
if( nargin<3 || isempty(width)); width = .6; end;
if( nargin<4 || isempty(offset)); offset = .1; end;
if( nargin<5 || isempty(show) || nd>3 ); show = 0; end;

%%% uses a cache since this is slow but often called with same inputs.
persistent cache; if( isempty(cache) ); cache=simpleCache('init'); end;
key = [nd siz M width offset];
[found,val] = simpleCache( 'get', cache, key );
if( found ) %%% get masks and keepLocs from cache
  [masks,keepLocs] = deal(val{:});
else %%% create masks and keepLocs
  [M,er] = checkNumArgs( M, [1 nd], 0, 2 ); error(er);
  inds = {':'}; inds = inds(:,ones(1,nd));
  if( offset<=-.5 || offset>=1 ); error('offset must be in (-.5,1)'); end;

  %%% the covariance of each window
  spacing = (siz*(1+2*offset))./M;
  sigmas = spacing * width;
  C = diag(sigmas.^2);

  %%% create each mask
  masks = zeros( [siz,prod(M)] );
  for c=1:prod(M)
    sub = ind2sub2( M, c );
    mus = (sub-.5).* spacing + .5-offset*siz;
    masks(inds{:},c) = filterGauss( siz, mus, C );
  end
  keepLocs = masks>1e-7;

  %%% place into cache
  cache = simpleCache( 'put', cache, key, {masks,keepLocs} );
end;

%%% optionally display
if( show )
  if( nd==1 )
    figure(show); clf; plot( masks );
    figure(show+1); clf; plot(sum( masks,nd+1 ));
    a=axis; a(3)=0; axis(a);
    title('coverage');
 elseif( nd==2)
    figure(show); clf; montage2( masks );
    figure(show+1); clf; im(sum( masks,nd+1));
    title('coverage');
  elseif( nd==3)
    figure(show); clf; montage2( masks );
    figure(show+1); clf; montage2(sum( masks,nd+1) );
    title('coverage');
  end
end;