class_docstr: Parametric multichannel Wiener filter, with an adjustable
  tradeoff between noise reduction and speech distortion.
  It supports automatic reference channel selection based
  on the estimated output SNR.
  
  Args:
      beta: Parameter of the parameteric filter, tradeoff between noise reduction
            and speech distortion (0: MVDR, 1: MWF).
      rank: Rank assumption for the speech covariance matrix.
      postfilter: Optional postfilter. If None, no postfilter is applied.
      ref_channel: Optional, reference channel. If None, it will be estimated automatically.
      ref_hard: If true, estimate a hard (one-hot) reference. If false, a soft reference.
      ref_hard_use_grad: If true, use straight-through gradient when using the hard reference
      ref_subband_weighting: If true, use subband weighting when estimating reference channel
      num_subbands: Optional, used to determine the parameter size for reference estimation
      diag_reg: Optional, diagonal regularization for the multichannel filter
      eps: Small regularization constant to avoid division by zero
  
  References:
      - Souden et al, On Optimal Frequency-Domain Multichannel Linear Filtering for Noise Reduction, 2010
docstr: Apply the MIMO filter on the input.
  
  Args:
      input: batch with C input channels, shape (B, C, F, T)
      filter: batch of C-input, M-output filters, shape (B, F, C, M)
  
  Returns:
      M-channel filter output, shape (B, M, F, T)
docstr_tok: ["Apply","the","MIMO","filter","on","the","input",".","Args",":","input",":","batch","with","C","input","channels",",","shape","(","B",",","C",",","F",",","T",")","filter",":","batch","of","C-input",",","M-output","filters",",","shape","(","B",",","F",",","C",",","M",")","Returns",":","M-channel","filter","output",",","shape","(","B",",","M",",","F",",","T",")"]
code: def apply_filter(
      self, input: torch.Tensor, filter: torch.Tensor
  ) -> torch.Tensor:
      """Apply the MIMO filter on the input.
  
      Args:
          input: batch with C input channels, shape (B, C, F, T)
          filter: batch of C-input, M-output filters, shape (B, F, C, M)
  
      Returns:
          M-channel filter output, shape (B, M, F, T)
      """
      if not filter.is_complex():
          raise TypeError(
              f"Expecting complex-valued filter, found {filter.dtype}"
          )
  
      if not input.is_complex():
          raise TypeError(
              f"Expecting complex-valued input, found {input.dtype}"
          )
  
      if (
          filter.ndim != 4
          or filter.size(-2) != input.size(-3)
          or filter.size(-3) != input.size(-2)
      ):
          raise ValueError(
              f"Filter shape {filter.shape}, not compatible with input shape {input.shape}"
          )
  
      output = torch.einsum("bfcm,bcft->bmft", filter.conj(), input)
  
      return output
  
imports: import random
  from typing import Callable, Optional
  import torch
  from nemo.collections.asr.parts.submodules.multi_head_attention import MultiHeadAttention
  from nemo.core.classes import NeuralModule, typecheck
  from nemo.core.neural_types import AudioSignal, FloatType, NeuralType, SpectrogramType
  from nemo.utils import logging
label_desc: Use image node_id 4 for calling the ParametricMultichannelWienerFilter obj's underlying member method code with example usage: obj.apply_filter(input, filter) and returns: output