code: def _calc_oa_lens(s1, s2):
      """Calculate the optimal FFT lengths for overlapp-add convolution.
  
      The calculation is done for a single dimension.
  
      Parameters
      ----------
      s1 : int
          Size of the dimension for the first array.
      s2 : int
          Size of the dimension for the second array.
  
      Returns
      -------
      block_size : int
          The size of the FFT blocks.
      overlap : int
          The amount of overlap between two blocks.
      in1_step : int
          The size of each step for the first array.
      in2_step : int
          The size of each step for the first array.
  
      """
      # Set up the arguments for the conventional FFT approach.
      fallback = (s1 + s2 - 1, None, s1, s2)
  
      # Use conventional FFT convolve if sizes are same.
      if s1 == s2 or s1 == 1 or s2 == 1:
          return fallback
  
      if s2 > s1:
          s1, s2 = s2, s1
          swapped = True
      else:
          swapped = False
  
      # There cannot be a useful block size if s2 is more than half of s1.
      if s2 >= s1 / 2:
          return fallback
  
      # Derivation of optimal block length
      # For original formula see:
      # https://en.wikipedia.org/wiki/Overlap-add_method
      #
      # Formula:
      # K = overlap = s2-1
      # N = block_size
      # C = complexity
      # e = exponential, exp(1)
      #
      # C = (N*(log2(N)+1))/(N-K)
      # C = (N*log2(2N))/(N-K)
      # C = N/(N-K) * log2(2N)
      # C1 = N/(N-K)
      # C2 = log2(2N) = ln(2N)/ln(2)
      #
      # dC1/dN = (1*(N-K)-N)/(N-K)^2 = -K/(N-K)^2
      # dC2/dN = 2/(2*N*ln(2)) = 1/(N*ln(2))
      #
      # dC/dN = dC1/dN*C2 + dC2/dN*C1
      # dC/dN = -K*ln(2N)/(ln(2)*(N-K)^2) + N/(N*ln(2)*(N-K))
      # dC/dN = -K*ln(2N)/(ln(2)*(N-K)^2) + 1/(ln(2)*(N-K))
      # dC/dN = -K*ln(2N)/(ln(2)*(N-K)^2) + (N-K)/(ln(2)*(N-K)^2)
      # dC/dN = (-K*ln(2N) + (N-K)/(ln(2)*(N-K)^2)
      # dC/dN = (N - K*ln(2N) - K)/(ln(2)*(N-K)^2)
      #
      # Solve for minimum, where dC/dN = 0
      # 0 = (N - K*ln(2N) - K)/(ln(2)*(N-K)^2)
      # 0 * ln(2)*(N-K)^2 = N - K*ln(2N) - K
      # 0 = N - K*ln(2N) - K
      # 0 = N - K*(ln(2N) + 1)
      # 0 = N - K*ln(2Ne)
      # N = K*ln(2Ne)
      # N/K = ln(2Ne)
      #
      # e^(N/K) = e^ln(2Ne)
      # e^(N/K) = 2Ne
      # 1/e^(N/K) = 1/(2*N*e)
      # e^(N/-K) = 1/(2*N*e)
      # e^(N/-K) = K/N*1/(2*K*e)
      # N/K*e^(N/-K) = 1/(2*e*K)
      # N/-K*e^(N/-K) = -1/(2*e*K)
      #
      # Using Lambert W function
      # https://en.wikipedia.org/wiki/Lambert_W_function
      # x = W(y) It is the solution to y = x*e^x
      # x = N/-K
      # y = -1/(2*e*K)
      #
      # N/-K = W(-1/(2*e*K))
      #
      # N = -K*W(-1/(2*e*K))
      overlap = s2 - 1
      opt_size = (
          -overlap * lambertw(-1 / (2 * math.e * overlap), k=-1).real
      )
      block_size = sp_fft.next_fast_len(math.ceil(opt_size))
  
      # Use conventional FFT convolve if there is only going to be one block.
      if block_size >= s1:
          return fallback
  
      if not swapped:
          in1_step = block_size - s2 + 1
          in2_step = s2
      else:
          in1_step = s2
          in2_step = block_size - s2 + 1
  
      return block_size, overlap, in1_step, in2_step
  
imports: import operator
  import math
  import timeit
  from scipy.spatial import cKDTree
  from .None import sigtools, dlti
  from ._upfirdn import upfirdn, _output_len, _upfirdn_modes
  from scipy import linalg, fft
  from scipy.fft._helper import _init_nd_shape_and_axes
  from scipy._lib._util import prod
  import numpy
  from scipy.special import lambertw
  from .windows import get_window
  from ._arraytools import axis_slice, axis_reverse, odd_ext, even_ext, const_ext
  from .filter_design import cheby1, _validate_sos
  from .fir_filter_design import firwin
  from ._sosfilt import _sosfilt
  import warnings
label_desc: Use image node_id 11 for calling a global function with example usage: _calc_oa_lens(s1, s2) and returns: block_size,  overlap,  in1_step,  in2_step, fallback, fallback, fallback