function [ circuit_eulerian, path_eulerian ] = graph_adj_is_eulerian ( A )

%*****************************************************************************80
%
%% graph_adj_is_eulerian() determines if a graph is Eulerian.
%
%  Discussion:
%
%    An edgewise-connected graph is circuit Eulerian if no node 
%    has odd degree;
%
%    An edgewise-connected graph is path Eulerian if at most two nodes 
%    have odd degree;
%
%    It is allowed for some nodes to have zero degree.  We are only
%    interested in using all the edges, not in visiting all the nodes.
%
%    If a graph is circuit Eulerian, then it is possible to start 
%    from any node and trace an Eulerian circuit, which uses every edge 
%    exactly once, and returns to the starting node.
%
%    If a graph is path Eulerian, then it is possible to start 
%    from a node of odd degree and trace an Eulerian path, which uses 
%    every edge exactly once, and finishes at the other node of odd degree.
%
%  Licensing:
%
%    This code is distributed under the MIT license. 
%
%  Modified:
%
%    11 March 2023
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer A(n,n): the adjacency matrix for the graph.
%
%  Output:
%
%    logical circuit_eulerian: true if the graph is circuit Eulerian.
%
%    logical path_eulerian: true if the graph is path Eulerian.
%

%
%  Actually, you need EDGEWISE connectivity, not NODEWISE!
%
  connected = graph_adj_is_nodewise_connected_depth ( A );

  if ( ~ connected )
    circuit_eulerian = false;
    path_eulerian = false;
    return
  end

  degree = sum ( A, 2 );
  circuit_eulerian = ( sum ( mod ( degree, 2 ) == 1 ) == 0 );

  path_eulerian = ( sum ( mod ( degree, 2 ) == 1 ) <= 2 );

  return
end

