code: def from_numpy_dynamic(  # pylint: disable=too-many-arguments
      X: np.ndarray,
      Xlags: np.ndarray,
      lambda_w: float = 0.1,
      lambda_a: float = 0.1,
      max_iter: int = 100,
      h_tol: float = 1e-8,
      w_threshold: float = 0.0,
      tabu_edges: List[Tuple[int, int, int]] = None,
      tabu_parent_nodes: List[int] = None,
      tabu_child_nodes: List[int] = None,
  ) -> StructureModel:
      """
      Learn the graph structure of a Dynamic Bayesian Network describing conditional dependencies between variables in
      data. The input data is time series data present in numpy arrays X and Xlags.
  
      The optimisation is to minimise a score function F(W, A) over the graph's contemporaneous (intra-slice) weighted
      adjacency matrix, W, and lagged (inter-slice) weighted adjacency matrix, A, subject to the a constraint function
      h(W), where h_value(W) == 0 characterises an acyclic graph. h(W) > 0 is a continuous, differentiable function that
      encapsulated how acyclic the graph is (less = more acyclic).
  
      Based on "DYNOTEARS: Structure Learning from Time-Series Data".
      https://arxiv.org/abs/2002.00498
      @inproceedings{pamfil2020dynotears,
          title={DYNOTEARS: Structure Learning from Time-Series Data},
          author={Pamfil, Roxana and Sriwattanaworachai, Nisara and Desai, Shaan and Pilgerstorfer,
          Philip and Georgatzis, Konstantinos and Beaumont, Paul and Aragam, Bryon},
          booktitle={International Conference on Artificial Intelligence and Statistics},
          pages={1595--1605},
          year={2020}year={2020},
      }
  
      Args:
          X (np.ndarray): 2d input data, axis=1 is data columns, axis=0 is data rows. Each column represents one variable,
          and each row represents x(m,t) i.e. the mth time series at time t.
          Xlags (np.ndarray): shifted data of X with lag orders stacking horizontally. Xlags=[shift(X,1)|...|shift(X,p)]
          lambda_w (float): l1 regularization parameter of intra-weights W
          lambda_a (float): l1 regularization parameter of inter-weights A
          max_iter: max number of dual ascent steps during optimisation
          h_tol (float): exit if h(W) < h_tol (as opposed to strict definition of 0)
          w_threshold: fixed threshold for absolute edge weights.
          tabu_edges: list of edges(lag, from, to) not to be included in the graph. `lag == 0` implies that the edge is
          forbidden in the INTRA graph (W), while lag > 0 implies an INTER weight equal zero.
          tabu_parent_nodes: list of nodes banned from being a parent of any other nodes.
          tabu_child_nodes: list of nodes banned from being a child of any other nodes.
      Returns:
          W (np.ndarray): d x d estimated weighted adjacency matrix of intra slices
          A (np.ndarray): d x pd estimated weighted adjacency matrix of inter slices
  
      Raises:
          ValueError: If X or Xlags does not contain data, or dimensions of X and Xlags do not conform
      """
      _, d_vars = X.shape
      p_orders = Xlags.shape[1] // d_vars
  
      bnds_w = 2 * [
          (0, 0)
          if i == j
          else (0, 0)
          if tabu_edges is not None and (0, i, j) in tabu_edges
          else (0, 0)
          if tabu_parent_nodes is not None and i in tabu_parent_nodes
          else (0, 0)
          if tabu_child_nodes is not None and j in tabu_child_nodes
          else (0, None)
          for i in range(d_vars)
          for j in range(d_vars)
      ]
  
      bnds_a = []
      for k in range(1, p_orders + 1):
          bnds_a.extend(
              2
              * [
                  (0, 0)
                  if tabu_edges is not None and (k, i, j) in tabu_edges
                  else (0, 0)
                  if tabu_parent_nodes is not None
                  and i in tabu_parent_nodes
                  else (0, 0)
                  if tabu_child_nodes is not None
                  and j in tabu_child_nodes
                  else (0, None)
                  for i in range(d_vars)
                  for j in range(d_vars)
              ]
          )
  
      bnds = bnds_w + bnds_a
      w_est, a_est = _learn_dynamic_structure(
          X, Xlags, bnds, lambda_w, lambda_a, max_iter, h_tol
      )
  
      w_est[np.abs(w_est) < w_threshold] = 0
      a_est[np.abs(a_est) < w_threshold] = 0
      sm = _matrices_to_structure_model(w_est, a_est)
      return sm
  
file_path: causalnex/causalnex/structure/dynotears.py
imports: import warnings
  from typing import Dict, List, Tuple, Union
  import numpy
  import pandas
  import scipy.linalg
  import scipy.optimize
  from causalnex.structure import StructureModel
  from causalnex.structure.transformers import DynamicDataTransformer
label_desc: Use image node_id 3 for calling a global function with example usage: from_numpy_dynamic(X, Xlags, lambda_w, lambda_a, max_iter, h_tol, w_threshold, tabu_edges, tabu_parent_nodes, tabu_child_nodes) and returns: sm