code: def c_standardization(
      input_centred, Vrr, Vii, Vri, layernorm=False, dim=-1
  ):
      """This function is used to standardize a centred tensor of
      complex numbers (mean of the set must be 0).
  
      Arguments
      ---------
      input_centred : torch.Tensor
          It is the tensor to be normalized. The features
          dimension is divided by 2 with the first half
          corresponding to the real-parts and the second half
          to the imaginary parts.
      Vrr : torch.Tensor
          It is a tensor that contains the covariance between real-parts.
      Vii : torch.Tensor
          It is a tensor that contains the covariance between imaginary-parts.
      Vri : torch.Tensor
          It is a tensor that contains the covariance between real-parts and
          imaginary-parts.
      layernorm : bool, optional
          It defines is c_standardization is called from a layernorm or a
          batchnorm layer (default False).
      dim : int, optional
          It defines the axis that should be considered as the complex-valued
          axis (divided by 2 to get r and i) (default -1).
      """
      ndim = input_centred.dim()
      input_dim = input_centred.size(dim) // 2
      variances_broadcast = [1] * ndim
      variances_broadcast[dim] = input_dim
  
      if layernorm:
          variances_broadcast[0] = input_centred.size(0)
  
      # We require the covariance matrix's inverse square root. That requires
      # square rooting, followed by inversion (During the computation of square
      # root we compute the determinant we'll need for inversion as well).
  
      # tau = Vrr + Vii = Trace. Guaranteed >=0 because Positive-definite matrix
      tau = Vrr + Vii
  
      # delta = (Vrr * Vii) - (Vri ** 2) = Determinant
      delta = (Vrr * Vii) - (Vri**2)
  
      s = delta.sqrt()
      t = (tau + 2 * s).sqrt()
  
      # The square root matrix could now be explicitly formed as
      #       [ Vrr+s Vri   ]
      # (1/t) [ Vir   Vii+s ]
      # https://en.wikipedia.org/wiki/Square_root_of_a_2_by_2_matrix
      # but we don't need to do this immediately since we can also simultaneously
      # invert. We can do this because we've already computed the determinant of
      # the square root matrix, and can thus invert it using the analytical
      # solution for 2x2 matrices
      #      [ A B ]             [  D  -B ]
      # inv( [ C D ] ) = (1/det) [ -C   A ]
      # http://mathworld.wolfram.com/MatrixInverse.html
      # Thus giving us
      #           [  Vii+s  -Vri   ]
      # (1/s)(1/t)[ -Vir     Vrr+s ]
      # So we proceed as follows:
  
      inverse_st = 1.0 / (s * t)
      Wrr = (Vii + s) * inverse_st
      Wii = (Vrr + s) * inverse_st
      Wri = -Vri * inverse_st
  
      # And we have computed the inverse square root matrix W = sqrt(V)!
      # Normalization. We multiply, x_normalized = W.x.
  
      # The returned result will be a complex standardized input
      # where the real and imaginary parts are obtained as follows:
      # x_real_normed = Wrr * x_real_centred + Wri * x_imag_centred
      # x_imag_normed = Wri * x_real_centred + Wii * x_imag_centred
  
      broadcast_Wrr = Wrr.view(variances_broadcast)
      broadcast_Wri = Wri.view(variances_broadcast)
      broadcast_Wii = Wii.view(variances_broadcast)
  
      cat_W_4_real = torch.cat([broadcast_Wrr, broadcast_Wii], dim=dim)
      cat_W_4_imag = torch.cat([broadcast_Wri, broadcast_Wri], dim=dim)
  
      if dim == 0:
          centred_real = input_centred[:input_dim]
          centred_imag = input_centred[input_dim:]
      elif dim == 1 or (dim == -1 and ndim == 2):
          centred_real = input_centred[:, :input_dim]
          centred_imag = input_centred[:, input_dim:]
      elif dim == -1 and ndim == 3:
          centred_real = input_centred[:, :, :input_dim]
          centred_imag = input_centred[:, :, input_dim:]
      elif dim == -1 and ndim == 4:
          centred_real = input_centred[:, :, :, :input_dim]
          centred_imag = input_centred[:, :, :, input_dim:]
      else:
          centred_real = input_centred[:, :, :, :, :input_dim]
          centred_imag = input_centred[:, :, :, :, input_dim:]
  
      rolled_input = torch.cat([centred_imag, centred_real], dim=dim)
  
      output = (
          cat_W_4_real * input_centred + cat_W_4_imag * rolled_input
      )
  
      #   Wrr * x_real_centered | Wii * x_imag_centered
      # + Wri * x_imag_centered | Wri * x_real_centered
      # -----------------------------------------------
      # = output
  
      return output
  
file_path: speechbrain/speechbrain/nnet/complex_networks/c_normalization.py
imports: import torch
  from torch.nn import Parameter
  import numpy
  from speechbrain.nnet.complex_networks.c_ops import multi_mean
label_desc: Use image node_id 2 for calling a global function with example usage: c_standardization(input_centred, Vrr, Vii, Vri, layernorm, dim) and returns: output