docs: def _get_kernel_from_bayesian_model(self, model):
          """
          Computes the Gibbs transition models from a Bayesian Network.
          'Probabilistic Graphical Model Principles and Techniques', Koller and
          Friedman, Section 12.3.3 pp 512-513.
  
          Parameters:
          -----------
          model: BayesianModel
              The model from which probabilities will be computed.
          """
          self.variables = np.array(model.nodes())
          self.cardinalities = {var: model.get_cpds(var).variable_card for var in self.variables}
  
          for var in self.variables:
              other_vars = [v for v in self.variables if var != v]
              other_cards = [self.cardinalities[v] for v in other_vars]
              cpds = [cpd for cpd in model.cpds if var in cpd.scope()]
              prod_cpd = factor_product(*cpds)
              kernel = {}
              scope = set(prod_cpd.scope())
              for tup in itertools.product(*[range(card) for card in other_cards]):
                  states = [State(v, s) for v, s in zip(other_vars, tup) if v in scope]
                  prod_cpd_reduced = prod_cpd.reduce(states, inplace=False)
                  kernel[tup] = prod_cpd_reduced.values / sum(prod_cpd_reduced.values)
              self.transition_models[var] = kernel