code: def main():
      """Learning Poincaré graph embedding.
  
      Learns Poincaré Ball embedding by using Riemannian
      gradient descent algorithm.
      """
      gs.random.seed(1234)
      dim = 2
      max_epochs = 100
      lr = 0.05
      n_negative = 2
      context_size = 1
      karate_graph = load_karate_graph()
  
      nb_vertices_by_edges = [
          len(e_2) for _, e_2 in karate_graph.edges.items()
      ]
      logging.info("Number of edges: %s", len(karate_graph.edges))
      logging.info(
          "Mean vertices by edges: %s",
          (sum(nb_vertices_by_edges, 0) / len(karate_graph.edges)),
      )
  
      negative_table_parameter = 5
      negative_sampling_table = []
  
      for i, nb_v in enumerate(nb_vertices_by_edges):
          negative_sampling_table += (
              [i]
              * int((nb_v ** (3.0 / 4.0)))
              * negative_table_parameter
          )
  
      negative_sampling_table = gs.array(negative_sampling_table)
      random_walks = karate_graph.random_walk()
      embeddings = gs.random.normal(size=(karate_graph.n_nodes, dim))
      embeddings = embeddings * 0.2
  
      hyperbolic_manifold = PoincareBall(2)
  
      colors = {1: "b", 2: "r"}
      for epoch in range(max_epochs):
          total_loss = []
          for path in random_walks:
              for example_index, one_path in enumerate(path):
                  context_index = path[
                      max(0, example_index - context_size) : min(
                          example_index + context_size, len(path)
                      )
                  ]
                  negative_index = gs.random.randint(
                      negative_sampling_table.shape[0],
                      size=(len(context_index), n_negative),
                  )
                  negative_index = negative_sampling_table[
                      negative_index
                  ]
  
                  example_embedding = embeddings[one_path]
  
                  for one_context_i, one_negative_i in zip(
                      context_index, negative_index
                  ):
                      context_embedding = embeddings[one_context_i]
                      negative_embedding = embeddings[one_negative_i]
                      l, g_ex = loss(
                          example_embedding,
                          context_embedding,
                          negative_embedding,
                          hyperbolic_manifold,
                      )
                      total_loss.append(l)
  
                      example_to_update = embeddings[one_path]
                      embeddings[
                          one_path
                      ] = hyperbolic_manifold.metric.exp(
                          -lr * g_ex, example_to_update
                      )
  
          logging.info(
              "iteration %d loss_value %f",
              epoch,
              sum(total_loss, 0) / len(total_loss),
          )
  
      circle = visualization.PoincareDisk(coords_type="ball")
      plt.figure()
      ax = plt.subplot(111)
      circle.add_points(gs.array([[0, 0]]))
      circle.set_ax(ax)
      circle.draw(ax=ax)
      for i_embedding, embedding in enumerate(embeddings):
          plt.scatter(
              embedding[0],
              embedding[1],
              c=colors[karate_graph.labels[i_embedding][0]],
          )
      plt.show()
  
file_path: geomstats/examples/learning_graph_structured_data_h2.py
imports: import logging
  import matplotlib.pyplot
  import geomstats.backend
  import geomstats.visualization
  from geomstats.datasets.utils import load_karate_graph
  from geomstats.geometry.poincare_ball import PoincareBall
label_desc: Use image node_id 5 for calling a global function with example usage: main() without return types