class_docstr: Variational Inference for the Infinite Gaussian Mixture Model.
  
  DPGMM stands for Dirichlet Process Gaussian Mixture Model, and it
  is an infinite mixture model with the Dirichlet Process as a prior
  distribution on the number of clusters. In practice the
  approximate inference algorithm uses a truncated distribution with
  a fixed maximum number of components, but almost always the number
  of components actually used depends on the data.
  
  Stick-breaking Representation of a Gaussian mixture model
  probability distribution. This class allows for easy and efficient
  inference of an approximate posterior distribution over the
  parameters of a Gaussian mixture model with a variable number of
  components (smaller than the truncation parameter n_components).
  
  Initialization is with normally-distributed means and identity
  covariance, for proper convergence.
  
  Read more in the :ref:`User Guide <dpgmm>`.
  
  Parameters
  ----------
  n_components: int, default 1
      Number of mixture components.
  
  covariance_type: string, default 'diag'
      String describing the type of covariance parameters to
      use.  Must be one of 'spherical', 'tied', 'diag', 'full'.
  
  alpha: float, default 1
      Real number representing the concentration parameter of
      the dirichlet process. Intuitively, the Dirichlet Process
      is as likely to start a new cluster for a point as it is
      to add that point to a cluster with alpha elements. A
      higher alpha means more clusters, as the expected number
      of clusters is ``alpha*log(N)``.
  
  tol : float, default 1e-3
      Convergence threshold.
  
  n_iter : int, default 10
      Maximum number of iterations to perform before convergence.
  
  params : string, default 'wmc'
      Controls which parameters are updated in the training
      process.  Can contain any combination of 'w' for weights,
      'm' for means, and 'c' for covars.
  
  init_params : string, default 'wmc'
      Controls which parameters are updated in the initialization
      process.  Can contain any combination of 'w' for weights,
      'm' for means, and 'c' for covars.  Defaults to 'wmc'.
  
  verbose : int, default 0
      Controls output verbosity.
  
  Attributes
  ----------
  covariance_type : string
      String describing the type of covariance parameters used by
      the DP-GMM.  Must be one of 'spherical', 'tied', 'diag', 'full'.
  
  n_components : int
      Number of mixture components.
  
  weights_ : array, shape (`n_components`,)
      Mixing weights for each mixture component.
  
  means_ : array, shape (`n_components`, `n_features`)
      Mean parameters for each mixture component.
  
  precs_ : array
      Precision (inverse covariance) parameters for each mixture
      component.  The shape depends on `covariance_type`::
  
          (`n_components`, 'n_features')                if 'spherical',
          (`n_features`, `n_features`)                  if 'tied',
          (`n_components`, `n_features`)                if 'diag',
          (`n_components`, `n_features`, `n_features`)  if 'full'
  
  converged_ : bool
      True when convergence was reached in fit(), False otherwise.
  
  See Also
  --------
  GMM : Finite Gaussian mixture model fit with EM
  
  VBGMM : Finite Gaussian mixture model fit with a variational
      algorithm, better for situations where there might be too little
      data to get a good estimate of the covariance matrix.
docstr: Update the variational distributions for the precisions
docstr_tok: ["Update","the","variational","distributions","for","the","precisions"]
code: def _update_precisions(self, X, z):
      """Update the variational distributions for the precisions"""
      n_features = X.shape[1]
      if self.covariance_type == "spherical":
          self.dof_ = 0.5 * n_features * np.sum(z, axis=0)
          for k in range(self.n_components):
              # could be more memory efficient ?
              sq_diff = np.sum((X - self.means_[k]) ** 2, axis=1)
              self.scale_[k] = 1.0
              self.scale_[k] += 0.5 * np.sum(
                  z.T[k] * (sq_diff + n_features)
              )
              self.bound_prec_[k] = (
                  0.5
                  * n_features
                  * (digamma(self.dof_[k]) - np.log(self.scale_[k]))
              )
          self.precs_ = np.tile(
              self.dof_ / self.scale_, [n_features, 1]
          ).T
  
      elif self.covariance_type == "diag":
          for k in range(self.n_components):
              self.dof_[k].fill(1.0 + 0.5 * np.sum(z.T[k], axis=0))
              sq_diff = (X - self.means_[k]) ** 2  # see comment above
              self.scale_[k] = np.ones(n_features) + 0.5 * np.dot(
                  z.T[k], (sq_diff + 1)
              )
              self.precs_[k] = self.dof_[k] / self.scale_[k]
              self.bound_prec_[k] = 0.5 * np.sum(
                  digamma(self.dof_[k]) - np.log(self.scale_[k])
              )
              self.bound_prec_[k] -= 0.5 * np.sum(self.precs_[k])
  
      elif self.covariance_type == "tied":
          self.dof_ = 2 + X.shape[0] + n_features
          self.scale_ = (X.shape[0] + 1) * np.identity(n_features)
          for k in range(self.n_components):
              diff = X - self.means_[k]
              self.scale_ += np.dot(diff.T, z[:, k : k + 1] * diff)
          self.scale_ = pinvh(self.scale_)
          self.precs_ = self.dof_ * self.scale_
          self.det_scale_ = linalg.det(self.scale_)
          self.bound_prec_ = 0.5 * wishart_log_det(
              self.dof_, self.scale_, self.det_scale_, n_features
          )
          self.bound_prec_ -= 0.5 * self.dof_ * np.trace(self.scale_)
  
      elif self.covariance_type == "full":
          for k in range(self.n_components):
              sum_resp = np.sum(z.T[k])
              self.dof_[k] = 2 + sum_resp + n_features
              self.scale_[k] = (sum_resp + 1) * np.identity(n_features)
              diff = X - self.means_[k]
              self.scale_[k] += np.dot(diff.T, z[:, k : k + 1] * diff)
              self.scale_[k] = pinvh(self.scale_[k])
              self.precs_[k] = self.dof_[k] * self.scale_[k]
              self.det_scale_[k] = linalg.det(self.scale_[k])
              self.bound_prec_[k] = 0.5 * wishart_log_det(
                  self.dof_[k],
                  self.scale_[k],
                  self.det_scale_[k],
                  n_features,
              )
              self.bound_prec_[k] -= (
                  0.5 * self.dof_[k] * np.trace(self.scale_[k])
              )
  
imports: from __future__ import print_function
  import numpy
  from scipy.special import digamma, gammaln
  from scipy import linalg
  from scipy.spatial.distance import cdist
  from ..externals.six.moves import xrange
  from ..utils import check_random_state, check_array, deprecated
  from ..utils.extmath import logsumexp, pinvh, squared_norm
  from ..utils.validation import check_is_fitted
  from ..None import cluster
  from .gmm import _GMMBase
label_desc: Use image node_id 8 for calling the _DPGMMBase obj's underlying member method code with example usage: obj._update_precisions(X, z) without return types