class_docstr: Class that defines operations using a Poincare ball.
class_docstr_tok: ["Class","that","defines","operations","using","a","Poincare","ball","."]
docstr: Compute normalization factor and its gradient.
  
  Compute normalization factor given current variance
  and dimensionality.
  
  Parameters
  ----------
  variances : array-like, shape=[n]
      Value of variance.
  
  Returns
  -------
  norm_factor : array-like, shape=[n]
      Normalisation factor.
  norm_factor_gradient : array-like, shape=[n]
      Gradient of the normalization factor.
docstr_tok: ["Compute","normalization","factor","and","its","gradient",".","Compute","normalization","factor","given","current","variance","and","dimensionality",".","Parameters","--","--","--","--","--","variances",":","array-like",",","shape=","[","n","]","Value","of","variance",".","Returns","--","--","--","-","norm_factor",":","array-like",",","shape=","[","n","]","Normalisation","factor",".","norm_factor_gradient",":","array-like",",","shape=","[","n","]","Gradient","of","the","normalization","factor","."]
code: def norm_factor_gradient(self, variances):
      """Compute normalization factor and its gradient.
  
      Compute normalization factor given current variance
      and dimensionality.
  
      Parameters
      ----------
      variances : array-like, shape=[n]
          Value of variance.
  
      Returns
      -------
      norm_factor : array-like, shape=[n]
          Normalisation factor.
      norm_factor_gradient : array-like, shape=[n]
          Gradient of the normalization factor.
      """
      dim = self._space.dim
      variances = gs.transpose(gs.to_ndarray(variances, to_ndim=2))
      dim_range = gs.arange(0, dim, 1.0)
      alpha = self._compute_alpha(dim_range)
  
      binomial_coefficient = gs.ones(dim)
      binomial_coefficient[1:] = (
          dim - 1 + 1 - dim_range[1:]
      ) / dim_range[1:]
      binomial_coefficient = gs.cumprod(binomial_coefficient)
  
      beta = ((-gs.ones(dim)) ** dim_range) * binomial_coefficient
  
      sigma_repeated = gs.repeat(variances, dim, -1)
      prod_alpha_sigma = gs.einsum("ij,j->ij", sigma_repeated, alpha)
      term_2 = gs.exp((prod_alpha_sigma) ** 2) * (
          1 + gs.erf(prod_alpha_sigma)
      )
      term_1 = gs.sqrt(gs.pi / 2.0) * (1.0 / (2 ** (dim - 1)))
      term_2 = gs.einsum("ij,j->ij", term_2, beta)
      norm_factor = (
          term_1 * variances * gs.sum(term_2, axis=-1, keepdims=True)
      )
      grad_term_1 = 1 / variances
  
      grad_term_21 = 1 / gs.sum(term_2, axis=-1, keepdims=True)
  
      grad_term_211 = (
          gs.exp((prod_alpha_sigma) ** 2)
          * (1 + gs.erf(prod_alpha_sigma))
          * gs.einsum("ij,j->ij", sigma_repeated, alpha**2)
          * 2
      )
  
      grad_term_212 = gs.repeat(
          gs.expand_dims((2 / gs.sqrt(gs.pi)) * alpha, axis=0),
          variances.shape[0],
          axis=0,
      )
  
      grad_term_22 = grad_term_211 + grad_term_212
      grad_term_22 = gs.einsum("ij, j->ij", grad_term_22, beta)
      grad_term_22 = gs.sum(grad_term_22, axis=-1, keepdims=True)
  
      norm_factor_gradient = grad_term_1 + (grad_term_21 * grad_term_22)
  
      return gs.squeeze(norm_factor), gs.squeeze(norm_factor_gradient)
  
imports: import math
  import geomstats.algebra_utils
  import geomstats.backend
  from geomstats.geometry._hyperbolic import _Hyperbolic
  from geomstats.geometry.base import VectorSpaceOpenSet
  from geomstats.geometry.euclidean import Euclidean
  from geomstats.geometry.riemannian_metric import RiemannianMetric
  from geomstats.vectorization import repeat_out
label_desc: Use image node_id 10 for calling the PoincareBallMetric obj's underlying member method code with example usage: obj.norm_factor_gradient(variances) and returns: gs,  gs