class_docstr: Class for NOTEARS MLP (Multi-layer Perceptron) model.
  The model weights consist of dag_layer and loc_lin_layer weights respectively.
  dag_layer weight is the weight of the first fully connected layer which determines the causal structure.
  loc_lin_layer weights are the weight of hidden layers after the first fully connected layer
class_docstr_tok: ["Class","for","NOTEARS","MLP","(","Multi-layer","Perceptron",")","model",".","The","model","weights","consist","of","dag_layer","and","loc_lin_layer","weights","respectively",".","dag_layer","weight","is","the","weight","of","the","first","fully","connected","layer","which","determines","the","causal","structure",".","loc_lin_layer","weights","are","the","weight","of","hidden","layers","after","the","first","fully","connected","layer"]
docstr: Fit NOTEARS MLP model using the input data x
  
  Args:
      x: 2d numpy array input data, axis=0 is data rows, axis=1 is data columns. Data must be row oriented.
      max_iter: max number of dual ascent steps during optimisation.
      h_tol: exit if h(w) < h_tol (as opposed to strict definition of 0).
      rho_max: to be updated
docstr_tok: ["Fit","NOTEARS","MLP","model","using","the","input","data","x","Args",":","x",":","2d","numpy","array","input","data",",","axis=0","is","data","rows",",","axis=1","is","data","columns",".","Data","must","be","row","oriented",".","max_iter",":","max","number","of","dual","ascent","steps","during","optimisation",".","h_tol",":","exit","if","h","(","w",")","<","h_tol","(","as","opposed","to","strict","definition","of","0",")",".","rho_max",":","to","be","updated"]
code: def fit(
      self,
      x: np.ndarray,
      max_iter: int = 100,
      h_tol: float = 1e-8,
      rho_max: float = 1e16,
  ):
      """
      Fit NOTEARS MLP model using the input data x
  
      Args:
          x: 2d numpy array input data, axis=0 is data rows, axis=1 is data columns. Data must be row oriented.
          max_iter: max number of dual ascent steps during optimisation.
          h_tol: exit if h(w) < h_tol (as opposed to strict definition of 0).
          rho_max: to be updated
      """
      rho, alpha, h = 1.0, 0.0, np.inf
      X_torch = torch.from_numpy(x).float().to(self.device)
  
      for n_iter in range(max_iter):
          rho, alpha, h = self._dual_ascent_step(
              X_torch, rho, alpha, h, rho_max
          )
  
          if h <= h_tol or rho >= rho_max:
              break
          if n_iter == max_iter - 1 and h > h_tol:
              self._logger.warning(
                  "Failed to converge. Consider increasing max_iter."
              )
  
      # calculate the adjacency matrix after the fitting is finished
      self.adj = (
          self._calculate_adj(X_torch, mean_effect=False)
          .cpu()
          .detach()
          .numpy()
      )
      self.adj_mean_effect = (
          self._calculate_adj(X_torch, mean_effect=True)
          .cpu()
          .detach()
          .numpy()
      )
  
imports: import logging
  from typing import Iterable, List, Tuple, Union
  import numpy
  import scipy.optimize
  import torch
  from sklearn.base import BaseEstimator
  from torch import nn
  from causalnex.structure.pytorch.dist_type._base import DistTypeBase
  from causalnex.structure.pytorch.nonlinear import LocallyConnected
label_desc: Use image node_id 9 for calling the NotearsMLP obj's underlying member method code with example usage: obj.fit(x, max_iter, h_tol, rho_max) without return types