code: def gen_stationary_dyn_net_and_df(  # pylint: disable=R0913, R0914
      num_nodes: int = 10,
      n_samples: int = 100,
      p: int = 1,
      degree_intra: float = 3,
      degree_inter: float = 3,
      graph_type_intra: str = "erdos-renyi",
      graph_type_inter: str = "erdos-renyi",
      w_min_intra: float = 0.5,
      w_max_intra: float = 0.5,
      w_min_inter: float = 0.5,
      w_max_inter: float = 0.5,
      w_decay: float = 1.0,
      sem_type: str = "linear-gauss",
      noise_scale: float = 1,
      max_data_gen_trials: int = 1000,
  ) -> Tuple[StructureModel, pd.DataFrame, List[str], List[str]]:
      """
      Generates a dynamic structure model as well a dataframe representing a time series realisation of that model.
      We do checks to verify the network is stationary, and iterate until the resulting network is stationary.
      Args:
          num_nodes: number of nodes in the intra-slice structure
          n_samples: number of points to sample from the model, as a time series
          p: lag value for the dynamic structure
          degree_intra: expected degree for intra_slice nodes
          degree_inter: expected degree for inter_slice nodes
          graph_type_intra:
              - erdos-renyi: constructs a graph such that the probability of any given edge is degree / (num_nodes - 1)
              - barabasi-albert: constructs a scale-free graph from an initial connected graph of (degree / 2) nodes
              - full: constructs a fully-connected graph - degree has no effect
          graph_type_inter:
              - erdos-renyi: constructs a graph such that the probability of any given edge is degree / (num_nodes - 1)
              - full: connect all past nodes to all present nodesw_min_intra:
          w_min_intra: minimum weight on intra-slice adjacency matrix
          w_max_intra: maximum weight on intra-slice adjacency matrix
          w_min_inter: minimum weight on inter-slice adjacency matrix
          w_max_inter: maximum weight on inter-slice adjacency matrix
          w_decay: exponent of weights decay for slices that are farther apart. Default is 1.0, which implies no decay
          sem_type: {linear-gauss,linear-exp,linear-gumbel}
          noise_scale: scale parameter of noise distribution in linear SEM
          max_data_gen_trials: maximun number of attempts until obtaining a seemingly stationary model
      Returns:
          Tuple with:
          - the model created,as a Structure model
          - DataFrame representing the time series created from the model
          - Intra-slice nodes names
          - Inter-slice nodes names
      """
  
      with np.errstate(over="raise", invalid="raise"):
          burn_in = max(n_samples // 10, 50)
  
          simulate_flag = True
          g, intra_nodes, inter_nodes = None, None, None
  
          while simulate_flag:
              max_data_gen_trials -= 1
              if max_data_gen_trials <= 0:
                  simulate_flag = False
  
              try:
                  simulate_graphs_flag = True
                  while simulate_graphs_flag:
                      g = generate_structure_dynamic(
                          num_nodes=num_nodes,
                          p=p,
                          degree_intra=degree_intra,
                          degree_inter=degree_inter,
                          graph_type_intra=graph_type_intra,
                          graph_type_inter=graph_type_inter,
                          w_min_intra=w_min_intra,
                          w_max_intra=w_max_intra,
                          w_min_inter=w_min_inter,
                          w_max_inter=w_max_inter,
                          w_decay=w_decay,
                      )
                      intra_nodes = sorted(
                          [el for el in g.nodes if "_lag0" in el]
                      )
                      inter_nodes = sorted(
                          [el for el in g.nodes if "_lag0" not in el]
                      )
                      # Exclude empty graphs from consideration unless input degree is 0
                      if (
                          (
                              [
                                  (u, v)
                                  for u, v in g.edges
                                  if u in intra_nodes
                              ]
                              and [
                                  (u, v)
                                  for u, v in g.edges
                                  if u in inter_nodes
                              ]
                          )
                          or degree_intra == 0
                          or degree_inter == 0
                      ):
                          simulate_graphs_flag = False
  
                  # generate single time series
                  df = (
                      generate_dataframe_dynamic(
                          g,
                          n_samples=n_samples + burn_in,
                          sem_type=sem_type,
                          noise_scale=noise_scale,
                      )
                      .loc[burn_in:, intra_nodes + inter_nodes]
                      .reset_index(drop=True)
                  )
  
                  if df.isna().any(axis=None):
                      continue
              except (OverflowError, FloatingPointError):
                  continue
              if (df.abs().max().max() < 1e3) or (
                  max_data_gen_trials <= 0
              ):
                  simulate_flag = False
          if max_data_gen_trials <= 0:
              warnings.warn(
                  "Could not simulate data, returning constant dataframe",
                  UserWarning,
              )
  
              df = pd.DataFrame(
                  np.ones((n_samples, num_nodes * (1 + p))),
                  columns=intra_nodes + inter_nodes,
              )
      return g, df, intra_nodes, inter_nodes
  
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 10 for calling a global function with example usage: gen_stationary_dyn_net_and_df(num_nodes, n_samples, p, degree_intra, degree_inter, graph_type_intra, graph_type_inter, w_min_intra, w_max_intra, w_min_inter, w_max_inter, w_decay, sem_type, noise_scale, max_data_gen_trials) and returns: g,  df,  intra_nodes,  inter_nodes