code: def _generate_inter_structure(
      num_nodes: int,
      p: int,
      degree: float,
      graph_type: str,
      w_min: float,
      w_max: float,
      w_decay: float = 1.0,
      neg: float = 0.5,
  ) -> StructureModel:
      """Simulate random DAG between two time slices.
  
      Args:
          num_nodes: number of nodes per slice
          p: number of slices that influence current slice
          degree: expected in-degree of current time slice
          graph_type: {'erdos-renyi' 'full'}
          w_min: minimum weight for inter-slice nodes
          w_max: maximum weight for inter-slice nodes
          w_decay: exponent of weights decay for slices that are farther apart. Default is 1.0, which implies no decay
          neg: the proportion of edge weights expected to be negative. By default, 50% of the edges are expected
              to be negative weight (`neg == 0.5`).
  
      Returns:
          G_inter: weighted, bipartite DAG for inter-slice connections
  
      Raises:
          ValueError: if graph type not known
      """
      if w_min > w_max:
          raise ValueError(
              "Absolute minimum weight must be less than or equal to maximum weight: "
              f"{w_min} > {w_max}"
          )
  
      if graph_type == "erdos-renyi":
          prob = degree / num_nodes
          b = (np.random.rand(p * num_nodes, num_nodes) < prob).astype(
              float
          )
      elif (
          graph_type == "full"
      ):  # ignore degree, only for experimental use
          b = np.ones([p * num_nodes, num_nodes])
      else:
          raise ValueError(
              f"Unknown inter-slice graph type `{graph_type}`. "
              "Valid types are 'erdos-renyi' and 'full'"
          )
      u = []
      for i in range(p):
          u_i = np.random.uniform(
              low=w_min, high=w_max, size=[num_nodes, num_nodes]
          ) / (w_decay**i)
          u_i[np.random.rand(num_nodes, num_nodes) < neg] *= -1
          u.append(u_i)
  
      u = np.concatenate(u, axis=0) if u else np.empty(b.shape)
      a = (b != 0).astype(float) * u
  
      df = pd.DataFrame(
          a,
          index=[
              f"{var}_lag{l_val}"
              for l_val in range(1, p + 1)
              for var in range(num_nodes)
          ],
          columns=[f"{var}_lag0" for var in range(num_nodes)],
      )
      idxs, cols = list(df.index), list(df.columns)
      for i in idxs:
          df[i] = 0
      for i in cols:
          df.loc[i, :] = 0
  
      g_inter = StructureModel(df)
      return g_inter
  
file_path: causalnex/causalnex/structure/data_generators/wrappers.py
imports: import warnings
  from typing import List, Optional, Tuple
  import networkx
  import numpy
  import pandas
  from scipy.sparse import csr_matrix
  from sklearn.gaussian_process.kernels import Kernel
  from causalnex.structure.data_generators import generate_structure, nonlinear_sem_generator, sem_generator
  from causalnex.structure.structuremodel import StructureModel
label_desc: Use image node_id 8 for calling a global function with example usage: _generate_inter_structure(num_nodes, p, degree, graph_type, w_min, w_max, w_decay, neg) and returns: g_inter