function mu = log_norm ( A, p )

%*****************************************************************************80
%
%% log_norm() evaluates the matrix logarithmic norm for the l1, l2 and loo norms.
%
%  Discussion:
%
%    The matrix logarithmic norm is not a norm.  It can have a negative value.
%    However, it is useful in estimating error growth in solving systems
%    of differential equations, because of the necessity of estimating the
%    quantity exp(A*t).
%
%    If mu = log_norm ( A, p ), then
%      || exp(A*t) ||_p <= exp ( mu * t )
%    This result applies even when the matrix A is non-normal.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    02 February 2021
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Willem Hundsdorfer, Jan Verwer,
%    Numerical solution of time dependent advection-diffusion-reaction equations,
%    Springer, 2003,
%    ISBN13: 978-3-662-09017-6.
%
%    Gustaf Soderlind,
%    The logarithmic norm: History and modern theory,
%    BIT Numerical Mathematics,
%    Volume 46, pages 631-652, 2006.
%
%  Input:
%
%    real/complex A(N,N), the matrix whose norm is to be evaluated.
%
%    real P, indicates the P-norm to be used.
%    1: the L1 norm
%    2: the L2 norm
%    Inf: the Loo norm
%
%  Output:
%
%    real MU, the logarithmic norm of the matrix.
%
  if ( p == 1 )

    B = abs ( A ) - diag ( diag ( abs ( A ) ) );
    c = real ( diag ( A ) );
    d = sum ( B, 1 );
    mu = max ( c + d' );

  elseif ( p == 2 )

    B = 0.5 * ( A + A' );
    c = eig ( B );
    mu = max ( c );

  elseif ( p == Inf )

    B = abs ( A ) - diag ( diag ( abs ( A ) ) );
    c = real ( diag ( A ) );
    d = sum ( B, 2 );
    mu = max ( c + d );

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'log_norm(): Fatal error!\n' );
    fprintf ( 1, '  Illegal value of second argument "p" = %g\n', p );
    fprintf ( 1, '  Legal values are 1, 2 and Inf\n' );
    error ( 'log_norm(): Fatal error!' );
 
  end

  return
end
