class_docstr: Minimum Variance Distortionless Response (MVDR) module that performs MVDR beamforming with Time-Frequency masks.
  
  .. devices:: CPU CUDA
  
  .. properties:: Autograd TorchScript
  
  Based on https://github.com/espnet/espnet/blob/master/espnet2/enh/layers/beamformer.py
  
  We provide three solutions of MVDR beamforming. One is based on *reference channel selection*
  :cite:`souden2009optimal` (``solution=ref_channel``).
  
  .. math::
      \textbf{w}_{\text{MVDR}}(f) =        \frac{{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bf{\Phi}_{\textbf{SS}}}}(f)}        {\text{Trace}({{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f) \bf{\Phi}_{\textbf{SS}}}(f))}}\bm{u}
  
  where :math:`\bf{\Phi}_{\textbf{SS}}` and :math:`\bf{\Phi}_{\textbf{NN}}` are the covariance        matrices of speech and noise, respectively. :math:`\bf{u}` is an one-hot vector to determine the         reference channel.
  
  The other two solutions are based on the steering vector (``solution=stv_evd`` or ``solution=stv_power``).
  
  .. math::
      \textbf{w}_{\text{MVDR}}(f) =        \frac{{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bm{v}}(f)}}        {{\bm{v}^{\mathsf{H}}}(f){\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bm{v}}(f)}
  
  where :math:`\bm{v}` is the acoustic transfer function or the steering vector.        :math:`.^{\mathsf{H}}` denotes the Hermitian Conjugate operation.
  
  We apply either *eigenvalue decomposition*
  :cite:`higuchi2016robust` or the *power method* :cite:`mises1929praktische` to get the
  steering vector from the PSD matrix of speech.
  
  After estimating the beamforming weight, the enhanced Short-time Fourier Transform (STFT) is obtained by
  
  .. math::
      \hat{\bf{S}} = {\bf{w}^\mathsf{H}}{\bf{Y}}, {\bf{w}} \in \mathbb{C}^{M \times F}
  
  where :math:`\bf{Y}` and :math:`\hat{\bf{S}}` are the STFT of the multi-channel noisy speech and        the single-channel enhanced speech, respectively.
  
  For online streaming audio, we provide a *recursive method* :cite:`higuchi2017online` to update the
  PSD matrices of speech and noise, respectively.
  
  Args:
      ref_channel (int, optional): Reference channel for beamforming. (Default: ``0``)
      solution (str, optional): Solution to compute the MVDR beamforming weights.
          Options: [``ref_channel``, ``stv_evd``, ``stv_power``]. (Default: ``ref_channel``)
      multi_mask (bool, optional): If ``True``, only accepts multi-channel Time-Frequency masks. (Default: ``False``)
      diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to the covariance matrix
          of the noise. (Default: ``True``)
      diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading.
          It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``)
      online (bool, optional): If ``True``, updates the MVDR beamforming weights based on
          the previous covarience matrices. (Default: ``False``)
  
  Note:
      To improve the numerical stability, the input spectrogram will be converted to double precision
      (``torch.complex128`` or ``torch.cdouble``) dtype for internal computation. The output spectrogram
      is converted to the dtype of the input spectrogram to be compatible with other modules.
  
  Note:
      If you use ``stv_evd`` solution, the gradient of the same input may not be identical if the
      eigenvalues of the PSD matrix are not distinct (i.e. some eigenvalues are close or identical).
docstr: Update psd of noise recursively.
  
  Args:
      psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise.
          Tensor with dimensions `(..., freq, channel, channel)`.
      mask_n (torch.Tensor or None, optional): Time-Frequency mask of the noise.
          Tensor with dimensions `(..., freq, time)`.
  
  Returns:
      torch.Tensor:  The updated PSD matrix of noise.
docstr_tok: ["Update","psd","of","noise","recursively",".","Args",":","psd_n","(","torch.Tensor",")",":","The","complex-valued","power","spectral","density","(","PSD",")","matrix","of","noise",".","Tensor","with","dimensions","`","(","...",",","freq",",","channel",",","channel",")","`",".","mask_n","(","torch.Tensor","or","None",",","optional",")",":","Time-Frequency","mask","of","the","noise",".","Tensor","with","dimensions","`","(","...",",","freq",",","time",")","`",".","Returns",":","torch.Tensor",":","The","updated","PSD","matrix","of","noise","."]
code: def _get_updated_psd_noise(
      self, psd_n: torch.Tensor, mask_n: torch.Tensor
  ) -> torch.Tensor:
      r"""Update psd of noise recursively.
  
      Args:
          psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise.
              Tensor with dimensions `(..., freq, channel, channel)`.
          mask_n (torch.Tensor or None, optional): Time-Frequency mask of the noise.
              Tensor with dimensions `(..., freq, time)`.
  
      Returns:
          torch.Tensor:  The updated PSD matrix of noise.
      """
      numerator = self.mask_sum_n / (
          self.mask_sum_n + mask_n.sum(dim=-1)
      )
      denominator = 1 / (self.mask_sum_n + mask_n.sum(dim=-1))
      psd_n = (
          self.psd_n * numerator[..., None, None]
          + psd_n * denominator[..., None, None]
      )
      return psd_n
  
imports: import warnings
  from typing import Optional, Union
  import torch
  from torch import Tensor
  from torchaudio import functional
label_desc: Use image node_id 4 for calling the MVDR obj's underlying member method code with example usage: obj._get_updated_psd_noise(psd_n, mask_n) and returns: psd_n