class_docstr: Distribution over spanning trees on a fixed number ``V`` of vertices.
  
  A tree is represented as :class:`torch.LongTensor` ``edges`` of shape
  ``(V-1,2)`` satisfying the following properties:
  
  1. The edges constitute a tree, i.e. are connected and cycle free.
  2. Each edge ``(v1,v2) = edges[e]`` is sorted, i.e. ``v1 < v2``.
  3. The entire tensor is sorted in colexicographic order.
  
  Use :func:`validate_edges` to verify `edges` are correctly formed.
  
  The ``edge_logits`` tensor has one entry for each of the ``V*(V-1)//2``
  edges in the complete graph on ``V`` vertices, where edges are each sorted
  and the edge order is colexicographic::
  
      (0,1), (0,2), (1,2), (0,3), (1,3), (2,3), (0,4), (1,4), (2,4), ...
  
  This ordering corresponds to the size-independent pairing function::
  
      k = v1 + v2 * (v2 - 1) // 2
  
  where ``k`` is the rank of the edge ``(v1,v2)`` in the complete graph.
  To convert a matrix of edge logits to the linear representation used here::
  
      assert my_matrix.shape == (V, V)
      i, j = make_complete_graph(V)
      edge_logits = my_matrix[i, j]
  
  :param torch.Tensor edge_logits: A tensor of length ``V*(V-1)//2``
      containing logits (aka negative energies) of all edges in the complete
      graph on ``V`` vertices. See above comment for edge ordering.
  :param dict sampler_options: An optional dict of sampler options including:
      ``mcmc_steps`` defaulting to a single MCMC step (which is pretty good);
      ``initial_edges`` defaulting to a cheap approximate sample;
      ``backend`` one of "python" or "cpp", defaulting to "python".
docstr: Validates a batch of ``edges`` tensors, as returned by :meth:`sample` or
  :meth:`enumerate_support` or as input to :meth:`log_prob()`.
  
  :param torch.LongTensor edges: A batch of edges.
  :raises: ValueError
  :returns: None
docstr_tok: ["Validates","a","batch","of","``","edges","``","tensors",",","as","returned","by",":","meth",":","`","sample","`","or",":","meth",":","`","enumerate_support","`","or","as","input","to",":","meth",":","`","log_prob","(",")","`",".",":","param","torch.LongTensor","edges",":","A","batch","of","edges",".",":","raises",":","ValueError",":","returns",":","None"]
code: def validate_edges(self, edges):
      """
      Validates a batch of ``edges`` tensors, as returned by :meth:`sample` or
      :meth:`enumerate_support` or as input to :meth:`log_prob()`.
  
      :param torch.LongTensor edges: A batch of edges.
      :raises: ValueError
      :returns: None
      """
      if edges.shape[-2:] != self.event_shape:
          raise ValueError(
              "Invalid edges shape: {}".format(edges.shape)
          )
  
      # Verify canonical ordering.
      if not ((0 <= edges) & (edges < self.num_vertices)).all():
          raise ValueError("Invalid vertex ids:\n{}".format(edges))
      if not (edges[..., 0] < edges[..., 1]).all():
          raise ValueError(
              "Vertices are not sorted in each edge:\n{}".format(edges)
          )
      if not (
          (edges[..., :-1, 1] < edges[..., 1:, 1])
          | (
              (edges[..., :-1, 1] == edges[..., 1:, 1])
              & (edges[..., :-1, 0] < edges[..., 1:, 0])
          )
      ).all():
          raise ValueError(
              "Edges are not sorted colexicographically:\n{}".format(
                  edges
              )
          )
  
      # Verify tree property, i.e. connectivity.
      V = self.num_vertices
      for i in itertools.product(*map(range, edges.shape[:-2])):
          edges_i = edges[i]
          connected = torch.eye(V, dtype=torch.float)
          connected[edges_i[:, 0], edges_i[:, 1]] = 1
          connected[edges_i[:, 1], edges_i[:, 0]] = 1
          for i in range(int(math.ceil(V**0.5))):
              connected = connected.mm(connected).clamp_(max=1)
          if not connected.min() > 0:
              raise ValueError(
                  "Edges do not constitute a tree:\n{}".format(edges_i)
              )
  
imports: import itertools
  import math
  import torch
  from torch.distributions import constraints
  from torch.distributions.utils import lazy_property
  from pyro.distributions.torch_distribution import TorchDistribution
label_desc: Use image node_id 2 for calling the SpanningTree obj's underlying member method code with example usage: obj.validate_edges(edges) without return types