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: Perform MVDR beamforming.
  
  Args:
      specgram (torch.Tensor): Multi-channel complex-valued spectrum.
          Tensor with dimensions `(..., channel, freq, time)`
      mask_s (torch.Tensor): Time-Frequency mask of target speech.
          Tensor with dimensions `(..., freq, time)` if multi_mask is ``False``
          or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``.
      mask_n (torch.Tensor or None, optional): Time-Frequency mask of noise.
          Tensor with dimensions `(..., freq, time)` if multi_mask is ``False``
          or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``.
          (Default: None)
  
  Returns:
      torch.Tensor: Single-channel complex-valued enhanced spectrum with dimensions `(..., freq, time)`.
docstr_tok: ["Perform","MVDR","beamforming",".","Args",":","specgram","(","torch.Tensor",")",":","Multi-channel","complex-valued","spectrum",".","Tensor","with","dimensions","`","(","...",",","channel",",","freq",",","time",")","`","mask_s","(","torch.Tensor",")",":","Time-Frequency","mask","of","target","speech",".","Tensor","with","dimensions","`","(","...",",","freq",",","time",")","`","if","multi_mask","is","``","False","``","or","with","dimensions","`","(","...",",","channel",",","freq",",","time",")","`","if","multi_mask","is","``","True","``",".","mask_n","(","torch.Tensor","or","None",",","optional",")",":","Time-Frequency","mask","of","noise",".","Tensor","with","dimensions","`","(","...",",","freq",",","time",")","`","if","multi_mask","is","``","False","``","or","with","dimensions","`","(","...",",","channel",",","freq",",","time",")","`","if","multi_mask","is","``","True","``",".","(","Default",":","None",")","Returns",":","torch.Tensor",":","Single-channel","complex-valued","enhanced","spectrum","with","dimensions","`","(","...",",","freq",",","time",")","`","."]
code: def forward(
      self,
      specgram: torch.Tensor,
      mask_s: torch.Tensor,
      mask_n: Optional[torch.Tensor] = None,
  ) -> torch.Tensor:
      """Perform MVDR beamforming.
  
      Args:
          specgram (torch.Tensor): Multi-channel complex-valued spectrum.
              Tensor with dimensions `(..., channel, freq, time)`
          mask_s (torch.Tensor): Time-Frequency mask of target speech.
              Tensor with dimensions `(..., freq, time)` if multi_mask is ``False``
              or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``.
          mask_n (torch.Tensor or None, optional): Time-Frequency mask of noise.
              Tensor with dimensions `(..., freq, time)` if multi_mask is ``False``
              or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``.
              (Default: None)
  
      Returns:
          torch.Tensor: Single-channel complex-valued enhanced spectrum with dimensions `(..., freq, time)`.
      """
      dtype = specgram.dtype
      if specgram.ndim < 3:
          raise ValueError(
              f"Expected at least 3D tensor (..., channel, freq, time). Found: {specgram.shape}"
          )
      if not specgram.is_complex():
          raise ValueError(
              f"The type of ``specgram`` tensor must be ``torch.cfloat`` or ``torch.cdouble``.\
                      Found: {specgram.dtype}"
          )
      if specgram.dtype == torch.cfloat:
          specgram = (
              specgram.cdouble()
          )  # Convert specgram to ``torch.cdouble``.
  
      if mask_n is None:
          warnings.warn(
              "``mask_n`` is not provided, use ``1 - mask_s`` as ``mask_n``."
          )
          mask_n = 1 - mask_s
  
      psd_s = self.psd(
          specgram, mask_s
      )  # (..., freq, time, channel, channel)
      psd_n = self.psd(
          specgram, mask_n
      )  # (..., freq, time, channel, channel)
  
      u = torch.zeros(
          specgram.size()[:-2],
          device=specgram.device,
          dtype=torch.cdouble,
      )  # (..., channel)
      u[..., self.ref_channel].fill_(1)
  
      if self.online:
          w_mvdr = self._get_updated_mvdr_vector(
              psd_s,
              psd_n,
              mask_s,
              mask_n,
              u,
              self.solution,
              self.diag_loading,
              self.diag_eps,
          )
      else:
          w_mvdr = _get_mvdr_vector(
              psd_s,
              psd_n,
              u,
              self.solution,
              self.diag_loading,
              self.diag_eps,
          )
  
      specgram_enhanced = F.apply_beamforming(w_mvdr, specgram)
  
      return specgram_enhanced.to(dtype)
  
imports: import warnings
  from typing import Optional, Union
  import torch
  from torch import Tensor
  from torchaudio import functional
label_desc: Use image node_id 5 for calling the MVDR obj's underlying member method code with example usage: obj.forward(specgram, mask_s, mask_n) and returns: specgram_enhanced