class_docstr: Class for performing inference using Belief Propagation method.
  
  Creates a Junction Tree or Clique Tree (JunctionTree class) for the input
  probabilistic graphical model and performs calibration of the junction tree
  so formed using belief propagation.
  
  Parameters
  ----------
  model: BayesianNetwork, MarkovNetwork, FactorGraph, JunctionTree
      model for which inference is to performed
docstr: Checks whether the calibration has converged or not. At convergence
  the sepset belief would be precisely the sepset marginal.
  
  Parameters
  ----------
  operation: str ('marginalize' | 'maximize')
      The operation to do for passing messages between nodes.
      if operation == marginalize, it checks whether the junction tree is calibrated or not
      else if operation == maximize, it checks whether the junction tree is max calibrated or not
  
  Formally, at convergence or at calibration this condition would be satisfied for
  
  .. math:: \sum_{C_i - S_{i, j}} eta_i = \sum_{C_j - S_{i, j}} eta_j = \mu_{i, j}
  
  and at max calibration this condition would be satisfied
  
  .. math:: \max_{C_i - S_{i, j}} eta_i = \max_{C_j - S_{i, j}} eta_j = \mu_{i, j}
docstr_tok: ["Checks","whether","the","calibration","has","converged","or","not",".","At","convergence","the","sepset","belief","would","be","precisely","the","sepset","marginal",".","Parameters","--","--","--","--","--","operation",":","str","(","'marginalize","'","|","'maximize","'",")","The","operation","to","do","for","passing","messages","between","nodes",".","if","operation","==","marginalize",",","it","checks","whether","the","junction","tree","is","calibrated","or","not","else","if","operation","==","maximize",",","it","checks","whether","the","junction","tree","is","max","calibrated","or","not","Formally",",","at","convergence","or","at","calibration","this","condition","would","be","satisfied","for","..","math",":",":","\\sum_","{","C_i","-","S_","{","i",",","j","}","}","\beta_i","=","\\sum_","{","C_j","-","S_","{","i",",","j","}","}","\beta_j","=","\\mu_","{","i",",","j","}","and","at","max","calibration","this","condition","would","be","satisfied","..","math",":",":","\\max_","{","C_i","-","S_","{","i",",","j","}","}","\beta_i","=","\\max_","{","C_j","-","S_","{","i",",","j","}","}","\beta_j","=","\\mu_","{","i",",","j","}"]
code: def _is_converged(self, operation):
      """
      Checks whether the calibration has converged or not. At convergence
      the sepset belief would be precisely the sepset marginal.
  
      Parameters
      ----------
      operation: str ('marginalize' | 'maximize')
          The operation to do for passing messages between nodes.
          if operation == marginalize, it checks whether the junction tree is calibrated or not
          else if operation == maximize, it checks whether the junction tree is max calibrated or not
  
      Formally, at convergence or at calibration this condition would be satisfied for
  
      .. math:: \sum_{C_i - S_{i, j}} \beta_i = \sum_{C_j - S_{i, j}} \beta_j = \mu_{i, j}
  
      and at max calibration this condition would be satisfied
  
      .. math:: \max_{C_i - S_{i, j}} \beta_i = \max_{C_j - S_{i, j}} \beta_j = \mu_{i, j}
      """
      # If no clique belief, then the clique tree is not calibrated
      if not self.clique_beliefs:
          return False
  
      for edge in self.junction_tree.edges():
          sepset = frozenset(edge[0]).intersection(frozenset(edge[1]))
          sepset_key = frozenset(edge)
          if (
              edge[0] not in self.clique_beliefs
              or edge[1] not in self.clique_beliefs
              or sepset_key not in self.sepset_beliefs
          ):
              return False
  
          marginal_1 = getattr(self.clique_beliefs[edge[0]], operation)(
              list(frozenset(edge[0]) - sepset), inplace=False
          )
          marginal_2 = getattr(self.clique_beliefs[edge[1]], operation)(
              list(frozenset(edge[1]) - sepset), inplace=False
          )
          if (
              marginal_1 != marginal_2
              or marginal_1 != self.sepset_beliefs[sepset_key]
          ):
              return False
      return True
  
imports: import copy
  import itertools
  import networkx
  import numpy
  from opt_einsum import contract
  from tqdm.auto import tqdm
  from pgmpy import config
  from pgmpy.factors import factor_product
  from pgmpy.factors.discrete import DiscreteFactor
  from pgmpy.inference import Inference
  from pgmpy.inference.EliminationOrder import MinFill, MinNeighbors, MinWeight, WeightedMinFill
  from pgmpy.models import BayesianNetwork, DynamicBayesianNetwork, JunctionTree, MarkovNetwork
  from pgmpy.utils import compat_fns
label_desc: Use image node_id 6 for calling the BeliefPropagation obj's underlying member method code with example usage: obj._is_converged(operation) and returns: True, False, False, False