docstr: Adjacency matrix for the temporal hierarchy.
  
  This is created in the following way:
      * First get indices of source vertices and destination vertices:
      source vertices are the aggregated nodes and destination vertices are their children in that order;
      e.g., for 15-min hierarchy, `source_ix` = [0, 1, 2] and `dest_ix` = [[1, 2], [3, 4], [5, 6]],
      i.e., 0 --> [1, 2], 1 --> [3, 4], 2 --> [5, 6].
      * Once we have these two lists, we can simply do `adj[s, t] = 1`, for `s` in `source_ix` and `t` `dest_ix`.
      * This is made symmetric by adding `adj[t, s] = 1`.
  
  :return:
docstr_tok: ["Adjacency","matrix","for","the","temporal","hierarchy",".","This","is","created","in","the","following","way",":","*","First","get","indices","of","source","vertices","and","destination","vertices",":","source","vertices","are","the","aggregated","nodes","and","destination","vertices","are","their","children","in","that","order",";","e.g.",",","for","15-min","hierarchy",",","`","source_ix","`","=","[","0",",","1",",","2","]","and","`","dest_ix","`","=","[","[","1",",","2","]",",","[","3",",","4","]",",","[","5",",","6","]","]",",","i.e.",",","0","--",">","[","1",",","2","]",",","1","--",">","[","3",",","4","]",",","2","--",">","[","5",",","6","]",".","*","Once","we","have","these","two","lists",",","we","can","simply","do","`","adj","[","s",",","t","]","=","1","`",",","for","`","s","`","in","`","source_ix","`","and","`","t","`","`","dest_ix","`",".","*","This","is","made","symmetric","by","adding","`","adj","[","t",",","s","]","=","1","`",".",":","return",":"]
code: def _adj_mat(self):
      """
      Adjacency matrix for the temporal hierarchy.
  
      This is created in the following way:
          * First get indices of source vertices and destination vertices:
          source vertices are the aggregated nodes and destination vertices are their children in that order;
          e.g., for 15-min hierarchy, `source_ix` = [0, 1, 2] and `dest_ix` = [[1, 2], [3, 4], [5, 6]],
          i.e., 0 --> [1, 2], 1 --> [3, 4], 2 --> [5, 6].
          * Once we have these two lists, we can simply do `adj[s, t] = 1`, for `s` in `source_ix` and `t` `dest_ix`.
          * This is made symmetric by adding `adj[t, s] = 1`.
  
      :return:
      """
      num_nodes_running_sum = np.cumsum(self.num_nodes_per_level)
  
      # for 15-min hierarchy: [[1, 2], [3, 4, 5, 6]] (we ignore the root).
      node_ix_level_wise = [
          list(range(i, j))
          for i, j in zip(
              num_nodes_running_sum[:-1], num_nodes_running_sum[1:]
          )
      ]
  
      dest_ix = []
      for n, nodes_ix in zip(
          self.num_nodes_per_level[:-1], node_ix_level_wise
      ):
          # split `node_ix` list into `n` equal parts;
          # this relies on the definition of temporal hierarchy: equal splits during disaggregation!
          # for 15-min hierarchy: [1, 2] --> [1, 2]; [3, 4, 5, 6] --> [3, 4], [5, 6]
          dest_ix.extend(np.array_split(nodes_ix, n))
  
      total_num_nodes = np.sum(self.num_nodes_per_level)
      source_ix = list(range(total_num_nodes - self.num_leaves))
  
      adj = np.zeros((total_num_nodes, total_num_nodes))
      for s, t in zip(source_ix, dest_ix):
          adj[s, t] = 1
          adj[t, s] = 1
  
      return adj
  
imports: from typing import Iterator, List
  import numpy
  import pandas
  from gluonts.core.component import validated
  from gluonts.model.forecast import SampleForecast
  from gluonts.mx import Tensor
label_desc: Use image node_id 2 for calling the TemporalHierarchy obj's underlying member method code with example usage: obj._adj_mat() and returns: adj