class_docstr: Base class for graphical representation of Structural Equation Models(SEMs).
  
  All variables are by default assumed to have an associated error latent variable, therefore
  doesn't need to be specified.
  
  Parameters
  ----------
  ebunch: list/array-like
      List of edges in form of tuples. Each tuple can be of two possible shape:
          1. (u, v): This would add an edge from u to v without setting any parameter
                     for the edge.
          2. (u, v, parameter): This would add an edge from u to v and set the edge's
                      parameter to `parameter`.
  
  latents: list/array-like
      List of nodes which are latent. All other variables are considered observed.
  
  err_corr: list/array-like
      List of tuples representing edges between error terms. It can be of the following forms:
          1. (u, v): Add correlation between error terms of `u` and `v`. Doesn't set any variance or
                     covariance values.
          2. (u, v, covar): Adds correlation between the error terms of `u` and `v` and sets the
                            parameter to `covar`.
  
  err_var: dict (variable: variance)
      Sets variance for the error terms in the model.
  
  Examples
  --------
  Defining a model (Union sentiment model[1]) without setting any paramaters.
  >>> from pgmpy.models import SEMGraph
  >>> sem = SEMGraph(ebunch=[('deferenc', 'unionsen'), ('laboract', 'unionsen'),
  ...                        ('yrsmill', 'unionsen'), ('age', 'deferenc'),
  ...                        ('age', 'laboract'), ('deferenc', 'laboract')],
  ...                latents=[],
  ...                err_corr=[('yrsmill', 'age')],
  ...                err_var={})
  
  Defining a model (Education [2]) with all the parameters set. For not setting any
  parameter `np.NaN` can be explicitly passed.
  >>> sem_edu = SEMGraph(ebunch=[('intelligence', 'academic', 0.8), ('intelligence', 'scale_1', 0.7),
  ...                            ('intelligence', 'scale_2', 0.64), ('intelligence', 'scale_3', 0.73),
  ...                            ('intelligence', 'scale_4', 0.82), ('academic', 'SAT_score', 0.98),
  ...                            ('academic', 'High_school_gpa', 0.75), ('academic', 'ACT_score', 0.87)],
  ...                    latents=['intelligence', 'academic'],
  ...                    err_corr=[],
  ...                    err_var={'intelligence': 1})
  
  References
  ----------
  [1] McDonald, A, J., & Clelland, D. A. (1984). Textile Workers and Union Sentiment.
      Social Forces, 63(2), 502–521
  [2] https://en.wikipedia.org/wiki/Structural_equation_modeling#/
      media/File:Example_Structural_equation_model.svg
  
  Attributes
  ----------
  latents: list
      List of all the latent variables in the model except the error terms.
  
  observed: list
      List of all the observed variables in the model.
  
  graph: nx.DirectedGraph
      The graphical structure of the latent and observed variables except the error terms.
      The parameters are stored in the `weight` attribute of each edge.
  
  err_graph: nx.Graph
      An undirected graph representing the relations between the error terms of the model.
      The node of the graph has the same name as the variable but represents the error terms.
      The variance is stored in the `weight` attribute of the node and the covariance are stored
      in the `weight` attribute of the edge.
  
  full_graph_struct: nx.DiGraph
      Represents the full graph structure. The names of error terms start with `.` and
      new nodes are added for each correlation which starts with `..`.
class_docstr_tok: ["Base","class","for","graphical","representation","of","Structural","Equation","Models","(","SEMs",")",".","All","variables","are","by","default","assumed","to","have","an","associated","error","latent","variable",",","therefore","does","n't","need","to","be","specified",".","Parameters","--","--","--","--","--","ebunch",":","list\/array-like","List","of","edges","in","form","of","tuples",".","Each","tuple","can","be","of","two","possible","shape",":","1",".","(","u",",","v",")",":","This","would","add","an","edge","from","u","to","v","without","setting","any","parameter","for","the","edge",".","2",".","(","u",",","v",",","parameter",")",":","This","would","add","an","edge","from","u","to","v","and","set","the","edge's","parameter","to","`","parameter","`",".","latents",":","list\/array-like","List","of","nodes","which","are","latent",".","All","other","variables","are","considered","observed",".","err_corr",":","list\/array-like","List","of","tuples","representing","edges","between","error","terms",".","It","can","be","of","the","following","forms",":","1",".","(","u",",","v",")",":","Add","correlation","between","error","terms","of","`","u","`","and","`","v","`",".","Does","n't","set","any","variance","or","covariance","values",".","2",".","(","u",",","v",",","covar",")",":","Adds","correlation","between","the","error","terms","of","`","u","`","and","`","v","`","and","sets","the","parameter","to","`","covar","`",".","err_var",":","dict","(","variable",":","variance",")","Sets","variance","for","the","error","terms","in","the","model",".","Examples","--","--","--","--","Defining","a","model","(","Union","sentiment","model","[","1","]",")","without","setting","any","paramaters",".",">",">",">","from","pgmpy.models","import","SEMGraph",">",">",">","sem","=","SEMGraph","(","ebunch=","[","(","'deferenc","'",",","'unionsen","'",")",",","(","'laboract","'",",","'unionsen","'",")",",","...","(","'yrsmill","'",",","'unionsen","'",")",",","(","'age","'",",","'deferenc","'",")",",","...","(","'age","'",",","'laboract","'",")",",","(","'deferenc","'",",","'laboract","'",")","]",",","...","latents=","[","]",",","...","err_corr=","[","(","'yrsmill","'",",","'age","'",")","]",",","...","err_var=","{","}",")","Defining","a","model","(","Education","[","2","]",")","with","all","the","parameters","set",".","For","not","setting","any","parameter","`","np.NaN","`","can","be","explicitly","passed",".",">",">",">","sem_edu","=","SEMGraph","(","ebunch=","[","(","'intelligence","'",",","'academic","'",",","0.8",")",",","(","'intelligence","'",",","'scale_1","'",",","0.7",")",",","...","(","'intelligence","'",",","'scale_2","'",",","0.64",")",",","(","'intelligence","'",",","'scale_3","'",",","0.73",")",",","...","(","'intelligence","'",",","'scale_4","'",",","0.82",")",",","(","'academic","'",",","'SAT_score","'",",","0.98",")",",","...","(","'academic","'",",","'High_school_gpa","'",",","0.75",")",",","(","'academic","'",",","'ACT_score","'",",","0.87",")","]",",","...","latents=","[","'intelligence","'",",","'academic","'","]",",","...","err_corr=","[","]",",","...","err_var=","{","'intelligence","'",":","1","}",")","References","--","--","--","--","--","[","1","]","McDonald",",","A",",","J.",",","&","Clelland",",","D.","A",".","(","1984",")",".","Textile","Workers","and","Union","Sentiment",".","Social","Forces",",","63","(","2",")",",","502\u2013521","[","2","]","https",":","\/\/en.wikipedia.org\/wiki\/Structural_equation_modeling","#","\/","media\/File",":","Example_Structural_equation_model.svg","Attributes","--","--","--","--","--","latents",":","list","List","of","all","the","latent","variables","in","the","model","except","the","error","terms",".","observed",":","list","List","of","all","the","observed","variables","in","the","model",".","graph",":","nx.DirectedGraph","The","graphical","structure","of","the","latent","and","observed","variables","except","the","error","terms",".","The","parameters","are","stored","in","the","`","weight","`","attribute","of","each","edge",".","err_graph",":","nx.Graph","An","undirected","graph","representing","the","relations","between","the","error","terms","of","the","model",".","The","node","of","the","graph","has","the","same","name","as","the","variable","but","represents","the","error","terms",".","The","variance","is","stored","in","the","`","weight","`","attribute","of","the","node","and","the","covariance","are","stored","in","the","`","weight","`","attribute","of","the","edge",".","full_graph_struct",":","nx.DiGraph","Represents","the","full","graph","structure",".","The","names","of","error","terms","start","with","`",".","`","and","new","nodes","are","added","for","each","correlation","which","starts","with","`","..","`","."]
docstr: Transforms the model to the standard LISREL representation of latent and measurement
  equations. The standard LISREL representation is given as:
  
  ..math::
      \mathbf{\eta} = \mathbf{B \eta} + \mathbf{\Gamma \xi} + \mathbf{\zeta} \\
      \mathbf{y} = \mathbf{\wedge_y \eta} + \mathbf{\epsilon} \\
      \mathbf{x} = \mathbf{\wedge_x \xi} + \mathbf{\delta} \\
      \mathbf{\Theta_e} = COV(\mathbf{\epsilon}) \\
      \mathbf{\Theta_\delta} = COV(\mathbf{\delta}) \\
      \mathbf{\Psi} = COV(\mathbf{\eta}) \\
      \mathbf{\Phi} = COV(\mathbf{\xi}) \\
  
  Since the standard LISREL representation has restrictions on the types of model,
  this method adds extra latent variables with fixed loadings of `1` to make the model
  consistent with the restrictions.
  
  Returns
  -------
  var_names: dict (keys: eta, xi, y, x)
      Returns the variable names in :math:`\mathbf{\eta}`, :math:`\mathbf{\xi}`,
      :math:`\mathbf{y}`, :math:`\mathbf{x}`.
  
  params: dict (keys: B, gamma, wedge_y, wedge_x, theta_e, theta_del, phi, psi)
      Returns a boolean matrix for each of the parameters. A 1 in the matrix
      represents that there is an edge in the model, 0 represents there is no edge.
  
  fixed_values: dict (keys: B, gamma, wedge_y, wedge_x, theta_e, theta_del, phi, psi)
      Returns a matrix for each of the parameters. A value in the matrix represents the
      set value for the parameter in the model else it is 0.
  
  See Also
  --------
  to_lisrel: Converts the model to `pgmpy.models.SEMAlg` instance.
  
  Examples
  --------
  TODO: Finish this.
docstr_tok: ["Transforms","the","model","to","the","standard","LISREL","representation","of","latent","and","measurement","equations",".","The","standard","LISREL","representation","is","given","as",":","..","math",":",":","\\mathbf","{","\\eta","}","=","\\mathbf","{","B","\\eta","}","+","\\mathbf","{","\\Gamma","\\xi","}","+","\\mathbf","{","\\zeta","}","\\\\","\\mathbf","{","y","}","=","\\mathbf","{","\\wedge_y","\\eta","}","+","\\mathbf","{","\\epsilon","}","\\\\","\\mathbf","{","x","}","=","\\mathbf","{","\\wedge_x","\\xi","}","+","\\mathbf","{","\\delta","}","\\\\","\\mathbf","{","\\Theta_e","}","=","COV","(","\\mathbf","{","\\epsilon","}",")","\\\\","\\mathbf","{","\\Theta_\\delta","}","=","COV","(","\\mathbf","{","\\delta","}",")","\\\\","\\mathbf","{","\\Psi","}","=","COV","(","\\mathbf","{","\\eta","}",")","\\\\","\\mathbf","{","\\Phi","}","=","COV","(","\\mathbf","{","\\xi","}",")","\\\\","Since","the","standard","LISREL","representation","has","restrictions","on","the","types","of","model",",","this","method","adds","extra","latent","variables","with","fixed","loadings","of","`","1","`","to","make","the","model","consistent","with","the","restrictions",".","Returns","--","--","--","-","var_names",":","dict","(","keys",":","eta",",","xi",",","y",",","x",")","Returns","the","variable","names","in",":","math",":","`","\\mathbf","{","\\eta","}","`",",",":","math",":","`","\\mathbf","{","\\xi","}","`",",",":","math",":","`","\\mathbf","{","y","}","`",",",":","math",":","`","\\mathbf","{","x","}","`",".","params",":","dict","(","keys",":","B",",","gamma",",","wedge_y",",","wedge_x",",","theta_e",",","theta_del",",","phi",",","psi",")","Returns","a","boolean","matrix","for","each","of","the","parameters",".","A","1","in","the","matrix","represents","that","there","is","an","edge","in","the","model",",","0","represents","there","is","no","edge",".","fixed_values",":","dict","(","keys",":","B",",","gamma",",","wedge_y",",","wedge_x",",","theta_e",",","theta_del",",","phi",",","psi",")","Returns","a","matrix","for","each","of","the","parameters",".","A","value","in","the","matrix","represents","the","set","value","for","the","parameter","in","the","model","else","it","is","0",".","See","Also","--","--","--","--","to_lisrel",":","Converts","the","model","to","`","pgmpy.models.SEMAlg","`","instance",".","Examples","--","--","--","--","TODO",":","Finish","this","."]
code: def to_standard_lisrel(self):
      r"""
          Transforms the model to the standard LISREL representation of latent and measurement
          equations. The standard LISREL representation is given as:
  
          ..math::
              \mathbf{\eta} = \mathbf{B \eta} + \mathbf{\Gamma \xi} + \mathbf{\zeta} \\
              \mathbf{y} = \mathbf{\wedge_y \eta} + \mathbf{\epsilon} \\
              \mathbf{x} = \mathbf{\wedge_x \xi} + \mathbf{\delta} \\
              \mathbf{\Theta_e} = COV(\mathbf{\epsilon}) \\
              \mathbf{\Theta_\delta} = COV(\mathbf{\delta}) \\
              \mathbf{\Psi} = COV(\mathbf{\eta}) \\
              \mathbf{\Phi} = COV(\mathbf{\xi}) \\
  
          Since the standard LISREL representation has restrictions on the types of model,
          this method adds extra latent variables with fixed loadings of `1` to make the model
          consistent with the restrictions.
  
          Returns
          -------
          var_names: dict (keys: eta, xi, y, x)
              Returns the variable names in :math:`\mathbf{\eta}`, :math:`\mathbf{\xi}`,
              :math:`\mathbf{y}`, :math:`\mathbf{x}`.
  
          params: dict (keys: B, gamma, wedge_y, wedge_x, theta_e, theta_del, phi, psi)
              Returns a boolean matrix for each of the parameters. A 1 in the matrix
              represents that there is an edge in the model, 0 represents there is no edge.
  
          fixed_values: dict (keys: B, gamma, wedge_y, wedge_x, theta_e, theta_del, phi, psi)
              Returns a matrix for each of the parameters. A value in the matrix represents the
              set value for the parameter in the model else it is 0.
  
          See Also
          --------
          to_lisrel: Converts the model to `pgmpy.models.SEMAlg` instance.
  
          Examples
          --------
          TODO: Finish this.
          """
      lisrel_err_graph = self.err_graph.copy()
      lisrel_latents = self.latents.copy()
      lisrel_observed = self.observed.copy()
  
      # Add new latent nodes to convert it to LISREL format.
      mapping = {}
      for u, v in self.graph.edges:
          if (u not in self.latents) and (v in self.latents):
              mapping[u] = "_l_" + u
          elif (u not in self.latents) and (v not in self.latents):
              mapping[u] = "_l_" + u
      lisrel_latents.update(mapping.values())
      lisrel_graph = nx.relabel_nodes(self.graph, mapping, copy=True)
      for u, v in mapping.items():
          lisrel_graph.add_edge(v, u, weight=1.0)
  
      # Get values of eta, xi, y, x
      latent_struct = lisrel_graph.subgraph(lisrel_latents)
      latent_indegree = lisrel_graph.in_degree()
  
      eta = []
      xi = []
      for node in latent_struct.nodes():
          if latent_indegree[node]:
              eta.append(node)
          else:
              xi.append(node)
  
      x = set()
      y = set()
      for exo in xi:
          x.update(
              [
                  x
                  for x in lisrel_graph.neighbors(exo)
                  if x not in lisrel_latents
              ]
          )
      for endo in eta:
          y.update(
              [
                  y
                  for y in lisrel_graph.neighbors(endo)
                  if y not in lisrel_latents
              ]
          )
  
      # If some node has edges from both eta and xi, replace it with another latent variable
      # otherwise it won't get included in any of the matrices.
      # TODO: Patchy work. Find a better solution.
      common_elements = set(x).intersection(set(y))
      if common_elements:
          mapping = {}
          for var in common_elements:
              mapping[var] = "_l_" + var
          lisrel_graph = nx.relabel_nodes(
              lisrel_graph, mapping, copy=True
          )
          for v, u in mapping.items():
              lisrel_graph.add_edge(u, v, weight=1.0)
          eta.extend(mapping.values())
          x = list(set(x) - common_elements)
          y.update(common_elements)
  
      var_names = {"eta": eta, "xi": xi, "y": list(y), "x": list(x)}
      edges_masks = self.__standard_lisrel_masks(
          graph=lisrel_graph,
          err_graph=lisrel_err_graph,
          weight=None,
          var=var_names,
      )
      fixed_masks = self.__standard_lisrel_masks(
          graph=lisrel_graph,
          err_graph=lisrel_err_graph,
          weight="weight",
          var=var_names,
      )
      return (var_names, edges_masks, fixed_masks)
  
imports: import itertools
  import networkx
  import numpy
  import pandas
  from networkx.algorithms.dag import descendants
  from pyparsing import OneOrMore, Optional, Suppress, Word, alphanums, nums
  from pgmpy.base import DAG
  from pgmpy.global_vars import logger
label_desc: Use image node_id 12 for calling the SEMGraph obj's underlying member method code with example usage: obj.to_standard_lisrel() and returns: var_names,  edges_masks,  fixed_masks