code: def GMM1_lpdf(
      samples, weights, mus, sigmas, low=None, high=None, q=None
  ):
      verbose = 0
      samples, weights, mus, sigmas = list(
          map(np.asarray, (samples, weights, mus, sigmas))
      )
      if samples.size == 0:
          return np.asarray([])
      if weights.ndim != 1:
          raise TypeError("need vector of weights", weights.shape)
      if mus.ndim != 1:
          raise TypeError("need vector of mus", mus.shape)
      if sigmas.ndim != 1:
          raise TypeError("need vector of sigmas", sigmas.shape)
      assert len(weights) == len(mus) == len(sigmas)
      _samples = samples
      samples = _samples.flatten()
  
      if verbose:
          print("GMM1_lpdf:samples", set(samples))
          print("GMM1_lpdf:weights", weights)
          print("GMM1_lpdf:mus", mus)
          print("GMM1_lpdf:sigmas", sigmas)
          print("GMM1_lpdf:low", low)
          print("GMM1_lpdf:high", high)
          print("GMM1_lpdf:q", q)
  
      if low is None and high is None:
          p_accept = 1
      else:
          p_accept = np.sum(
              weights
              * (
                  normal_cdf(high, mus, sigmas)
                  - normal_cdf(low, mus, sigmas)
              )
          )
  
      if q is None:
          dist = samples[:, None] - mus
          mahal = (old_div(dist, np.maximum(sigmas, EPS))) ** 2
          # mahal shape is (n_samples, n_components)
          Z = np.sqrt(2 * np.pi * sigmas**2)
          coef = weights / Z / p_accept
          rval = logsum_rows(-0.5 * mahal + np.log(coef))
      else:
          prob = np.zeros(samples.shape, dtype="float64")
          for w, mu, sigma in zip(weights, mus, sigmas):
              if high is None:
                  ubound = samples + old_div(q, 2.0)
              else:
                  ubound = np.minimum(samples + old_div(q, 2.0), high)
              if low is None:
                  lbound = samples - old_div(q, 2.0)
              else:
                  lbound = np.maximum(samples - old_div(q, 2.0), low)
              # -- two-stage addition is slightly more numerically accurate
              inc_amt = w * normal_cdf(ubound, mu, sigma)
              inc_amt -= w * normal_cdf(lbound, mu, sigma)
              prob += inc_amt
          rval = np.log(prob) - np.log(p_accept)
  
      if verbose:
          print("GMM1_lpdf:rval:", dict(list(zip(samples, rval))))
  
      rval.shape = _samples.shape
      return rval
  
imports: from __future__ import print_function
  from __future__ import absolute_import
  from __future__ import division
  from builtins import str
  from builtins import map
  from builtins import zip
  from builtins import range
  from past.utils import old_div
  import logging
  import time
  import numpy
  from scipy.special import erf
  from .None import pyll
  from .pyll import scope
  from .pyll.stochastic import implicit_stochastic
  from .base import miscs_to_idxs_vals
  from .base import miscs_update_idxs_vals
  from .None import rand
label_desc: Use image node_id 5 for calling a global function with example usage: GMM1_lpdf(samples, weights, mus, sigmas, low, high, q) and returns: rval, np