function [ ival, jval, kval ] = r8mat_is_sum ( m, n, a )

%*****************************************************************************80
%
%% r8mat_is_sum() checks whether an R8MAT has constant sums on rows or columns.
%
%  Discussion:
%
%    An R8MAT is a matrix of real values.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    04 November 2007
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer M, N, the row and column dimensions of 
%    the matrix.  M and N must be positive.
%
%    real A(M,N), the matrix.
%
%  Output:
%
%    integer IVAL:
%    -1, the matrix is not row sum constant.
%    1, the matrix is row sum constant.
%    2, the matrix is row sum constant with constant = 1 (Markov/stochastic).
%
%    integer JVAL:
%    -1, the matrix is not column sum constant.
%    1, the matrix is column sum constant.
%    2, the matrix is column sum constant with constant = 1 (transition).
%
%    integer KVAL:
%    -1, row sum constant not equal to column sum constant.
%    1, row sum constant = column sum constant (weak magic).
%    2, row sum constant = column sum constant = 1 (biMarkov/double stochastic).
%    3, row sum constant = column sum constant
%       = main diagonals sum constant (magic)
%    4, row sum constant = column sum constant
%       = main diagonals sum constant = 1 (magic biMarkov)
%
  tol = 0.0001;

  a_norm = sum ( sum ( abs ( a(1:m,1:n) ) ) );
%
%  Look at row sums.
%
  ival = -1;

  row_sum(1:m) = sum ( a(1:m,1:n), 2 );

  rmax = maxval ( row_sum(1:m) );
  rmin = minval ( row_sum(1:m) );
  rave = 0.5 * ( rmax + rmin );
  rtol = tol * ( 1.0 + a_norm / n );

  if ( abs ( rmax - rmin ) <= rtol )
    ival = 1;
    if ( abs ( rave - 1.0 ) <= rtol )
      ival = 2;
    end
  end
%
%  Look at column sums.
%
  jval = -1;

  col_sum(1:n) = sum ( a(1:m,1:n), 1 );

  cmax = maxval ( col_sum(1:n) );
  cmin = minval ( col_sum(1:n) );
  cave = 0.5 * ( cmax + cmin );
  ctol = tol * ( 1.0 + a_norm / m );

  if ( abs ( cmax - cmin ) <= ctol )
    jval = 1;
    if ( abs ( cave - 1.0 ) <= ctol )
      jval = 2;
    end
  end
%
%  Compute diagonal sums, compare row and column situations,
%  and see if we can throw in the diagonal as well.
%
  kval = -1;

  dsum1 = 0.0;
  for i = 1 : min ( m, n )
    dsum1 = dsum1 + a(i,i);
  end

  dsum2 = 0.0;
  for i = 1 : min ( m, n )
    dsum2 = dsum2 + a(i,n+1-i);
  end

  dave = 0.5 * ( dsum1 + dsum2 );

  dtol = tol * ( 1.0 + a_norm / min ( m, n ) );

  if ( 1 <= ival & 1 <= jval )

    if ( abs ( rave - cave ) <= dtol )

      kval = 1;

      if ( ival == 2 & jval == 2 )
        kval = 2;
      end

      if ( abs ( dsum1 - dsum2 ) <= dtol )
        if ( abs ( dave - rave ) <= dtol )
          kval = kval + 2;
        end
      end

    end

  end

  return
end
