code: def log_pdf(self, x: np.ndarray) -> np.ndarray:
      batch_size, n_vars = x.shape
      log_pdfs = np.empty(
          (batch_size, len(self.weights), n_vars), dtype=np.float64
      )
      for i, d in enumerate(self.distributions):
          xi = x[:, i]
          if isinstance(d, _BatchedCategoricalDistributions):
              log_pdfs[:, :, i] = np.log(
                  np.take_along_axis(
                      d.weights[None, :, :],
                      xi[:, None, None].astype(np.int64),
                      axis=-1,
                  )
              )[:, :, 0]
          elif isinstance(d, _BatchedTruncNormDistributions):
              log_pdfs[:, :, i] = _truncnorm.logpdf(
                  x=xi[:, None],
                  a=(d.low - d.mu[None, :]) / d.sigma[None, :],
                  b=(d.high - d.mu[None, :]) / d.sigma[None, :],
                  loc=d.mu[None, :],
                  scale=d.sigma[None, :],
              )
          elif isinstance(d, _BatchedDiscreteTruncNormDistributions):
              lower_limit = d.low - d.step / 2
              upper_limit = d.high + d.step / 2
              x_lower = np.maximum(xi - d.step / 2, lower_limit)
              x_upper = np.minimum(xi + d.step / 2, upper_limit)
              log_gauss_mass = _truncnorm._log_gauss_mass(
                  (x_lower[:, None] - d.mu[None, :]) / d.sigma[None, :],
                  (x_upper[:, None] - d.mu[None, :]) / d.sigma[None, :],
              )
              log_p_accept = _truncnorm._log_gauss_mass(
                  (d.low - d.step / 2 - d.mu[None, :])
                  / d.sigma[None, :],
                  (d.high + d.step / 2 - d.mu[None, :])
                  / d.sigma[None, :],
              )
              log_pdfs[:, :, i] = log_gauss_mass - log_p_accept
  
          else:
              assert False
      weighted_log_pdf = np.sum(log_pdfs, axis=-1) + np.log(
          self.weights[None, :]
      )
      max_ = weighted_log_pdf.max(axis=1)
      # We need to avoid (-inf) - (-inf) when the probability is zero.
      max_[np.isneginf(max_)] = 0
      with np.errstate(divide="ignore"):  # Suppress warning in log(0).
          return (
              np.log(
                  np.exp(weighted_log_pdf - max_[:, None]).sum(axis=1)
              )
              + max_
          )
  
file_path: optuna/optuna/samplers/_tpe/probability_distributions.py
imports: from typing import List
  from typing import NamedTuple
  from typing import Union
  import numpy
  from optuna.samplers._tpe import _truncnorm
label_desc: Use image node_id 2 for calling the _MixtureOfProductDistribution obj's underlying member method code with example usage: obj.log_pdf(x) and returns: unknown