class_docstr: Class for sampling methods specific to Bayesian Models
  
  Parameters
  ----------
  model: instance of BayesianNetwork
      model on which inference queries will be computed
class_docstr_tok: ["Class","for","sampling","methods","specific","to","Bayesian","Models","Parameters","--","--","--","--","--","model",":","instance","of","BayesianNetwork","model","on","which","inference","queries","will","be","computed"]
docstr: Generates sample(s) from joint distribution of the Bayesian Network.
  
  Parameters
  ----------
  size: int
      size of sample to be generated
  
  include_latents: boolean
      Whether to include the latent variable values in the generated samples.
  
  seed: int (default: None)
      If a value is provided, sets the seed for numpy.random.
  
  show_progress: boolean
      Whether to show a progress bar of samples getting generated.
  
  partial_samples: pandas.DataFrame
      A pandas dataframe specifying samples on some of the variables in the model. If
      specified, the sampling procedure uses these sample values, instead of generating them.
  
  n_jobs: int (default: -1)
      The number of CPU cores to use. Default uses all cores.
  
  Returns
  -------
  sampled: pandas.DataFrame
      The generated samples
  
  Examples
  --------
  >>> from pgmpy.models import BayesianNetwork
  >>> from pgmpy.factors.discrete import TabularCPD
  >>> from pgmpy.sampling import BayesianModelSampling
  >>> student = BayesianNetwork([('diff', 'grade'), ('intel', 'grade')])
  >>> cpd_d = TabularCPD('diff', 2, [[0.6], [0.4]])
  >>> cpd_i = TabularCPD('intel', 2, [[0.7], [0.3]])
  >>> cpd_g = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25,
  ...                0.08, 0.3], [0.3, 0.7, 0.02, 0.2]],
  ...                ['intel', 'diff'], [2, 2])
  >>> student.add_cpds(cpd_d, cpd_i, cpd_g)
  >>> inference = BayesianModelSampling(student)
  >>> inference.forward_sample(size=2)
  rec.array([(0, 0, 1), (1, 0, 2)], dtype=
            [('diff', '<i8'), ('intel', '<i8'), ('grade', '<i8')])
docstr_tok: ["Generates","sample","(","s",")","from","joint","distribution","of","the","Bayesian","Network",".","Parameters","--","--","--","--","--","size",":","int","size","of","sample","to","be","generated","include_latents",":","boolean","Whether","to","include","the","latent","variable","values","in","the","generated","samples",".","seed",":","int","(","default",":","None",")","If","a","value","is","provided",",","sets","the","seed","for","numpy.random",".","show_progress",":","boolean","Whether","to","show","a","progress","bar","of","samples","getting","generated",".","partial_samples",":","pandas.DataFrame","A","pandas","dataframe","specifying","samples","on","some","of","the","variables","in","the","model",".","If","specified",",","the","sampling","procedure","uses","these","sample","values",",","instead","of","generating","them",".","n_jobs",":","int","(","default",":","-1",")","The","number","of","CPU","cores","to","use",".","Default","uses","all","cores",".","Returns","--","--","--","-","sampled",":","pandas.DataFrame","The","generated","samples","Examples","--","--","--","--",">",">",">","from","pgmpy.models","import","BayesianNetwork",">",">",">","from","pgmpy.factors.discrete","import","TabularCPD",">",">",">","from","pgmpy.sampling","import","BayesianModelSampling",">",">",">","student","=","BayesianNetwork","(","[","(","'diff","'",",","'grade","'",")",",","(","'intel","'",",","'grade","'",")","]",")",">",">",">","cpd_d","=","TabularCPD","(","'diff","'",",","2",",","[","[","0.6","]",",","[","0.4","]","]",")",">",">",">","cpd_i","=","TabularCPD","(","'intel","'",",","2",",","[","[","0.7","]",",","[","0.3","]","]",")",">",">",">","cpd_g","=","TabularCPD","(","'grade","'",",","3",",","[","[","0.3",",","0.05",",","0.9",",","0.5","]",",","[","0.4",",","0.25",",","...","0.08",",","0.3","]",",","[","0.3",",","0.7",",","0.02",",","0.2","]","]",",","...","[","'intel","'",",","'diff","'","]",",","[","2",",","2","]",")",">",">",">","student.add_cpds","(","cpd_d",",","cpd_i",",","cpd_g",")",">",">",">","inference","=","BayesianModelSampling","(","student",")",">",">",">","inference.forward_sample","(","size=2",")","rec.array","(","[","(","0",",","0",",","1",")",",","(","1",",","0",",","2",")","]",",","dtype=","[","(","'diff","'",",","'","<","i8","'",")",",","(","'intel","'",",","'","<","i8","'",")",",","(","'grade","'",",","'","<","i8","'",")","]",")"]
code: def forward_sample(
      self,
      size=1,
      include_latents=False,
      seed=None,
      show_progress=True,
      partial_samples=None,
      n_jobs=-1,
  ):
      """
      Generates sample(s) from joint distribution of the Bayesian Network.
  
      Parameters
      ----------
      size: int
          size of sample to be generated
  
      include_latents: boolean
          Whether to include the latent variable values in the generated samples.
  
      seed: int (default: None)
          If a value is provided, sets the seed for numpy.random.
  
      show_progress: boolean
          Whether to show a progress bar of samples getting generated.
  
      partial_samples: pandas.DataFrame
          A pandas dataframe specifying samples on some of the variables in the model. If
          specified, the sampling procedure uses these sample values, instead of generating them.
  
      n_jobs: int (default: -1)
          The number of CPU cores to use. Default uses all cores.
  
      Returns
      -------
      sampled: pandas.DataFrame
          The generated samples
  
      Examples
      --------
      >>> from pgmpy.models import BayesianNetwork
      >>> from pgmpy.factors.discrete import TabularCPD
      >>> from pgmpy.sampling import BayesianModelSampling
      >>> student = BayesianNetwork([('diff', 'grade'), ('intel', 'grade')])
      >>> cpd_d = TabularCPD('diff', 2, [[0.6], [0.4]])
      >>> cpd_i = TabularCPD('intel', 2, [[0.7], [0.3]])
      >>> cpd_g = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25,
      ...                0.08, 0.3], [0.3, 0.7, 0.02, 0.2]],
      ...                ['intel', 'diff'], [2, 2])
      >>> student.add_cpds(cpd_d, cpd_i, cpd_g)
      >>> inference = BayesianModelSampling(student)
      >>> inference.forward_sample(size=2)
      rec.array([(0, 0, 1), (1, 0, 2)], dtype=
                [('diff', '<i8'), ('intel', '<i8'), ('grade', '<i8')])
      """
      sampled = pd.DataFrame(columns=list(self.model.nodes()))
  
      if show_progress and config.SHOW_PROGRESS:
          pbar = tqdm(self.topological_order)
      else:
          pbar = self.topological_order
  
      if seed is not None:
          np.random.seed(seed)
  
      for node in pbar:
          if show_progress and config.SHOW_PROGRESS:
              pbar.set_description(f"Generating for node: {node}")
          # If values specified in partial_samples, use them. Else generate the values.
          if (partial_samples is not None) and (
              node in partial_samples.columns
          ):
              sampled[node] = partial_samples.loc[:, node].values
          else:
              cpd = self.model.get_cpds(node)
              states = range(self.cardinality[node])
              evidence = cpd.variables[1:]
              if evidence:
                  evidence_values = np.vstack(
                      [sampled[i] for i in evidence]
                  )
                  unique, inverse = np.unique(
                      evidence_values.T, axis=0, return_inverse=True
                  )
                  unique = [tuple(u) for u in unique]
                  (
                      state_to_index,
                      index_to_weight,
                  ) = self.pre_compute_reduce_maps(
                      variable=node,
                      evidence=evidence,
                      state_combinations=unique,
                  )
                  if config.get_backend() == "numpy":
                      weight_index = np.array(
                          [state_to_index[u] for u in unique]
                      )[inverse]
                  else:
                      weight_index = torch.Tensor(
                          [state_to_index[u] for u in unique]
                      )[inverse]
                  sampled[node] = sample_discrete_maps(
                      states, weight_index, index_to_weight, size
                  )
              else:
                  weights = cpd.values
                  sampled[node] = sample_discrete(states, weights, size)
  
      samples_df = _return_samples(sampled, self.state_names_map)
      if not include_latents:
          samples_df.drop(self.model.latents, axis=1, inplace=True)
      return samples_df
  
imports: import itertools
  from collections import namedtuple
  import networkx
  import numpy
  import pandas
  import torch
  from joblib import Parallel, delayed
  from tqdm.auto import tqdm
  from pgmpy import config
  from pgmpy.factors import factor_product
  from pgmpy.models import BayesianNetwork, MarkovChain, MarkovNetwork
  from pgmpy.sampling import BayesianModelInference, _return_samples
  from pgmpy.utils.mathext import sample_discrete, sample_discrete_maps
label_desc: Use image node_id 2 for calling the BayesianModelSampling obj's underlying member method code with example usage: obj.forward_sample(size, include_latents, seed, show_progress, partial_samples, n_jobs) and returns: samples_df