function rank_a = i4mat_rank ( m, n, a )

%*****************************************************************************80
%
%% i4mat_rank() computes the rank of an I4MAT.
%
%  Discussion:
%
%    Note that "rank" is a MATLAB keyword.  
%    rank(A) returns the rank of a matrix.
%
%    Because this function assumes the input matrix contains only integer
%    values, it is possible to report the matrix rank without any fear
%    of roundoff error producing an incorrect result.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    25 October 2020
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer M, N, the number of rows and columns.
%
%    integer A(M,N), the matrix to be analyzed. 
%
%  Output:
%
%    integer RANK_A, the rank of the matrix.
%    0 <= RANK_A <= min ( M, N ).
%
  if ( ~ i4mat_is_integer ( a ) )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4MAT_RANK - Fatal error!' );
    fprintf ( 1, '  Input matrix A is not integral.\n' );
    error ( 'I4MAT_RANK - Fatal error!' );
  end

  lead = 1;
  rank_a = 0;
 
  for r = 1 : m

    if ( n < lead )
      break
    end
%
%  Start I at row R, and search for nonzero pivot entry A(I,LEAD).
%
    i = r;

    while ( a(i,lead) == 0.0 )

      i = i + 1;
%
%  If reach last row, reset I to R, and increment LEAD.
%
      if ( m < i )
        i = r;
        lead = lead + 1;
%
%  If reach last column, we can find no more pivots.
%
        if ( n < lead )
          lead = -1;
          break
        end
      end

    end

    if ( lead < 0 )
      break
    end
%
%  Increase rank by 1.
%
    rank_a = rank_a + 1;
%
%  Move pivot I into row R.
%
    if ( i ~= r )
      temp     = a(i,1:n);
      a(i,1:n) = a(r,1:n);
      a(r,1:n) = temp;
    end
%
%  Ensure pivot is positive.
%
    if ( a(r,lead) < 0 )
      a(r,1:n) = - a(r,1:n);
    end
%
%  Remove any common factor from row R.
%
    [ a(r,1:n), ifact ] = i4vec_red ( n, a(r,1:n), 1 );
%
%  Use a multiple of A(R,LEAD) to eliminate A(R+1:M,LEAD).
%
    for i = 1 : m

      if ( i ~= r )

        a(i,1:n) = a(r,lead) * a(i,1:n) - a(i,lead) * a(r,1:n);

        [ a(i,1:n), ifact ] = i4vec_red ( n, a(i,1:n), 1 );

      end

    end

    lead = lead + 1;

  end

  return
end

