code: def absorption(
      lam: float,
      epsilon: np.ndarray,
      mu: np.ndarray,
      type_: np.ndarray,
      hauteur: np.ndarray,
      pol: int,
      theta: float,
  ) -> np.ndarray:
      f = mu if not pol else epsilon
      k0 = 2 * np.pi / lam
      g = type_.size
      alpha = (
          np.sqrt(epsilon[type_[0]] * mu[type_[0]]) * k0 * np.sin(theta)
      )
      gamma = np.sqrt(
          epsilon[type_] * mu[type_] * k0**2 - np.ones(g) * alpha**2
      )
      if np.real(epsilon[type_[0]]) < 0 and np.real(mu[type_[0]]) < 0:
          gamma[0] = -gamma[0]
      if g > 2:
          gamma[1 : g - 2] = gamma[1 : g - 2] * (
              1 - 2 * (np.imag(gamma[1 : g - 2]) < 0)
          )
      if (
          np.real(epsilon[type_[g - 1]]) < 0
          and np.real(mu[type_[g - 1]]) < 0
          and np.real(
              np.sqrt(
                  epsilon[type_[g - 1]] * mu[type_[g - 1]] * k0**2
                  - alpha**2
              )
          )
          != 0
      ):
          gamma[g - 1] = -np.sqrt(
              epsilon[type_[g - 1]] * mu[type_[g - 1]] * k0**2
              - alpha**2
          )
      else:
          gamma[g - 1] = np.sqrt(
              epsilon[type_[g - 1]] * mu[type_[g - 1]] * k0**2
              - alpha**2
          )
      T = np.zeros(((2 * g, 2, 2)), dtype=complex)
      T[0] = [[0, 1], [1, 0]]
      for k2 in range(g - 1):
          t = np.exp(i * gamma[k2] * hauteur[k2])
          T[2 * k2 + 1] = [[0, t], [t, 0]]
          # Interface scattering matrix
          b1 = gamma[k2] / f[type_[k2]]
          b2 = gamma[k2 + 1] / f[type_[k2 + 1]]
          T[2 * k2 + 2] = [
              [(b1 - b2) / (b1 + b2), 2 * b2 / (b1 + b2)],
              [2 * b1 / (b1 + b2), (b2 - b1) / (b1 + b2)],
          ]
          t = np.exp(i * gamma[g - 1] * hauteur[g - 1])
          T[2 * g - 1] = [[0, t], [t, 0]]
      H = np.zeros(((2 * g - 1, 2, 2)), dtype=complex)
      A = np.zeros(((2 * g - 1, 2, 2)), dtype=complex)
      H[0] = T[2 * g - 1]
      A[0] = T[0]
      for j in range(2 * g - 2):
          A[j + 1] = cascade2(A[j], T[j + 1])
          H[j + 1] = cascade2(T[2 * g - 2 - j], H[j])
      # r = A[len(A) - 1][0, 0]  # TODO: unused
      t = A[len(A) - 1][1, 0]
      I = np.zeros(((2 * g, 2, 2)), dtype=complex)  # noqa
      for j in range(len(T) - 1):
          I[j][0, 0] = A[j][1, 0] / (
              1 - A[j][1, 1] * H[len(T) - 2 - j][0, 0]
          )
          I[j][0, 1] = (
              A[j][1, 1]
              * H[len(T) - 2 - j][0, 1]
              / (1 - A[j][1, 1] * H[len(T) - 2 - j][0, 0])
          )
          I[j][1, 0] = (
              A[j][1, 0]
              * H[len(T) - 2 - j][0, 0]
              / (1 - A[j][1, 1] * H[len(T) - 2 - j][0, 0])
          )
          I[j][1, 1] = H[len(T) - 2 - j][0, 1] / (
              1 - A[j][1, 1] * H[len(T) - 2 - j][0, 0]
          )
      I[2 * g - 1][0, 0] = I[2 * g - 2][0, 0] * np.exp(
          i * gamma[g - 1] * hauteur[g - 1]
      )
      I[2 * g - 1][0, 1] = I[2 * g - 2][0, 1] * np.exp(
          i * gamma[g - 1] * hauteur[g - 1]
      )
      I[2 * g - 1][1, 0] = 0
      I[2 * g - 1][1, 1] = 0
      w = 0
      poynting = np.zeros(2 * g, dtype=complex)
      if pol == 0:  # TE
          for j in range(2 * g):
              poynting[j] = np.real(
                  (I[j][0, 0] + I[j][1, 0])
                  * np.conj(
                      (I[j][0, 0] - I[j][1, 0])
                      * gamma[w]
                      / mu[type_[w]]
                  )
                  * mu[type_[0]]
                  / (gamma[0])
              )
              w = w + 1 - np.mod(j + 1, 2)
      else:  # TM
          for j in range(2 * g):
              poynting[j] = np.real(
                  (I[j][0, 0] - I[j][1, 0])
                  * np.conj(
                      (I[j][0, 0] + I[j][1, 0])
                      * gamma[w]
                      / epsilon[type_[w]]
                  )
                  * epsilon[type_[0]]
                  / (gamma[0])
              )
              w = w + 1 - np.mod(j + 1, 2)
      tmp = abs(-np.diff(poynting))
      absorb = tmp[np.arange(0, 2 * g, 2)]
      return absorb
  
file_path: nevergrad/nevergrad/functions/photonics/photonics.py
imports: import typing
  from pathlib import Path
  import numpy
  from scipy.linalg import toeplitz
label_desc: Use image node_id 13 for calling a global function with example usage: absorption(lam, epsilon, mu, type_, hauteur, pol, theta) and returns: absorb