code: def _compute_euler_from_dcm(dcm, seq, extrinsic=False):
      # The algorithm assumes intrinsic frame transformations. For representation
      # the paper uses transformation matrices, which are transpose of the
      # direction cosine matrices used by our Rotation class.
      # Adapt the algorithm for our case by
      # 1. Instead of transposing our representation, use the transpose of the
      #    O matrix as defined in the paper, and be careful to swap indices
      # 2. Reversing both axis sequence and angles for extrinsic rotations
  
      if extrinsic:
          seq = seq[::-1]
  
      if dcm.ndim == 2:
          dcm = dcm[None, :, :]
      num_rotations = dcm.shape[0]
  
      # Step 0
      # Algorithm assumes axes as column vectors, here we use 1D vectors
      n1 = _elementary_basis_vector(seq[0])
      n2 = _elementary_basis_vector(seq[1])
      n3 = _elementary_basis_vector(seq[2])
  
      # Step 2
      sl = np.dot(np.cross(n1, n2), n3)
      cl = np.dot(n1, n3)
  
      # angle offset is lambda from the paper referenced in [2] from docstring of
      # `as_euler` function
      offset = np.arctan2(sl, cl)
      c = np.vstack((n2, np.cross(n1, n2), n1))
  
      # Step 3
      rot = np.array(
          [
              [1, 0, 0],
              [0, cl, sl],
              [0, -sl, cl],
          ]
      )
      res = np.einsum("...ij,...jk->...ik", c, dcm)
      dcm_transformed = np.einsum(
          "...ij,...jk->...ik", res, c.T.dot(rot)
      )
  
      # Step 4
      angles = np.empty((num_rotations, 3))
      # Ensure less than unit norm
      positive_unity = dcm_transformed[:, 2, 2] > 1
      negative_unity = dcm_transformed[:, 2, 2] < -1
      dcm_transformed[positive_unity, 2, 2] = 1
      dcm_transformed[negative_unity, 2, 2] = -1
      angles[:, 1] = np.arccos(dcm_transformed[:, 2, 2])
  
      # Steps 5, 6
      eps = 1e-7
      safe1 = np.abs(angles[:, 1]) >= eps
      safe2 = np.abs(angles[:, 1] - np.pi) >= eps
  
      # Step 4 (Completion)
      angles[:, 1] += offset
  
      # 5b
      safe_mask = np.logical_and(safe1, safe2)
      angles[safe_mask, 0] = np.arctan2(
          dcm_transformed[safe_mask, 0, 2],
          -dcm_transformed[safe_mask, 1, 2],
      )
      angles[safe_mask, 2] = np.arctan2(
          dcm_transformed[safe_mask, 2, 0],
          dcm_transformed[safe_mask, 2, 1],
      )
  
      if extrinsic:
          # For extrinsic, set first angle to zero so that after reversal we
          # ensure that third angle is zero
          # 6a
          angles[~safe_mask, 0] = 0
          # 6b
          angles[~safe1, 2] = np.arctan2(
              dcm_transformed[~safe1, 1, 0]
              - dcm_transformed[~safe1, 0, 1],
              dcm_transformed[~safe1, 0, 0]
              + dcm_transformed[~safe1, 1, 1],
          )
          # 6c
          angles[~safe2, 2] = -np.arctan2(
              dcm_transformed[~safe2, 1, 0]
              + dcm_transformed[~safe2, 0, 1],
              dcm_transformed[~safe2, 0, 0]
              - dcm_transformed[~safe2, 1, 1],
          )
      else:
          # For instrinsic, set third angle to zero
          # 6a
          angles[~safe_mask, 2] = 0
          # 6b
          angles[~safe1, 0] = np.arctan2(
              dcm_transformed[~safe1, 1, 0]
              - dcm_transformed[~safe1, 0, 1],
              dcm_transformed[~safe1, 0, 0]
              + dcm_transformed[~safe1, 1, 1],
          )
          # 6c
          angles[~safe2, 0] = np.arctan2(
              dcm_transformed[~safe2, 1, 0]
              + dcm_transformed[~safe2, 0, 1],
              dcm_transformed[~safe2, 0, 0]
              - dcm_transformed[~safe2, 1, 1],
          )
  
      # Step 7
      if seq[0] == seq[2]:
          # lambda = 0, so we can only ensure angle2 -> [0, pi]
          adjust_mask = np.logical_or(
              angles[:, 1] < 0, angles[:, 1] > np.pi
          )
      else:
          # lambda = + or - pi/2, so we can ensure angle2 -> [-pi/2, pi/2]
          adjust_mask = np.logical_or(
              angles[:, 1] < -np.pi / 2, angles[:, 1] > np.pi / 2
          )
  
      # Dont adjust gimbal locked angle sequences
      adjust_mask = np.logical_and(adjust_mask, safe_mask)
  
      angles[adjust_mask, 0] += np.pi
      angles[adjust_mask, 1] = 2 * offset - angles[adjust_mask, 1]
      angles[adjust_mask, 2] -= np.pi
  
      angles[angles < -np.pi] += 2 * np.pi
      angles[angles > np.pi] -= 2 * np.pi
  
      # Step 8
      if not np.all(safe_mask):
          warnings.warn(
              "Gimbal lock detected. Setting third angle to zero since"
              " it is not possible to uniquely determine all angles."
          )
  
      # Reverse role of extrinsic and intrinsic rotations, but let third angle be
      # zero for gimbal locked cases
      if extrinsic:
          angles = angles[:, ::-1]
      return angles
  
imports: from __future__ import division, print_function, absolute_import
  import re
  import warnings
  import numpy
  import scipy.linalg
  from scipy._lib._util import check_random_state
label_desc: Use image node_id 2 for calling a global function with example usage: _compute_euler_from_dcm(dcm, seq, extrinsic) and returns: angles