code: def compose_heterogeneous(
      dprvs: List[DiscretePRV], num_self_compositions: List[int]
  ) -> DiscretePRV:
      r"""
      Compose a heterogenous list of PRVs with multiplicity. We use FFT to compose
      identical PRVs with themselves first, then pairwise convolve the remaining PRVs.
  
      This is the approach taken in https://github.com/microsoft/prv_accountant
      """
      if len(dprvs) != len(num_self_compositions):
          raise ValueError(
              "dprvs and num_self_compositions must have the same length"
          )
  
      dprvs = [
          _compose_fourier(dprv, num_self_composition)
          for dprv, num_self_composition in zip(
              dprvs, num_self_compositions
          )
      ]
      return _compose_convolution_tree(dprvs)
  
file_path: opacus/opacus/accountants/analysis/prv/compose.py
imports: from typing import List
  import numpy
  from scipy.fft import irfft, rfft
  from scipy.signal import convolve
  from .prvs import DiscretePRV
label_desc: Use image node_id 4 for calling a global function with example usage: compose_heterogeneous(dprvs, num__compositions) and returns: _compose_convolution_tree