// File: /workspace/github_cpp_makefile_star2_O2/istellartech[P]OpenTsiolkovsky/src/../lib/Eigen/src/Geometry/EulerAngles.h
// Function: Eigen::MatrixBase<Eigen::Transpose<Eigen::Matrix<double, 3, 3, 0, 3, 3>>>::eulerAngles(long, long, long) const
inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const
{
  using std::atan2;
  using std::sin;
  using std::cos;
  /* Implemented from Graphics Gems IV */
  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)

  Matrix<Scalar,3,1> res;
  typedef Matrix<typename Derived::Scalar,2,1> Vector2;

  const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
  const Index i = a0;
  const Index j = (a0 + 1 + odd)%3;
  const Index k = (a0 + 2 - odd)%3;
  
  if (a0==a2)
  {
    res[0] = atan2(coeff(j,i), coeff(k,i));
    if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0)))
    {
      res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
      Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
      res[1] = -atan2(s2, coeff(i,i));
    }
    else
    {
      Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
      res[1] = atan2(s2, coeff(i,i));
    }
    
    // With a=(0,1,0), we have i=0; j=1; k=2, and after computing the first two angles,
    // we can compute their respective rotation, and apply its inverse to M. Since the result must
    // be a rotation around x, we have:
    //
    //  c2  s1.s2 c1.s2                   1  0   0 
    //  0   c1    -s1       *    M    =   0  c3  s3
    //  -s2 s1.c2 c1.c2                   0 -s3  c3
    //
    //  Thus:  m11.c1 - m21.s1 = c3  &   m12.c1 - m22.s1 = s3
    
    Scalar s1 = sin(res[0]);
    Scalar c1 = cos(res[0]);
    res[2] = atan2(c1*coeff(j,k)-s1*coeff(k,k), c1*coeff(j,j) - s1 * coeff(k,j));
  } 
  else
  {
    res[0] = atan2(coeff(j,k), coeff(k,k));
    Scalar c2 = Vector2(coeff(i,i), coeff(i,j)).norm();
    if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0))) {
      res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
      res[1] = atan2(-coeff(i,k), -c2);
    }
    else
      res[1] = atan2(-coeff(i,k), c2);
    Scalar s1 = sin(res[0]);
    Scalar c1 = cos(res[0]);
    res[2] = atan2(s1*coeff(k,i)-c1*coeff(j,i), c1*coeff(j,j) - s1 * coeff(k,j));
  }
  if (!odd)
    res = -res;
  
  return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %r12
movq %rdx, %rbp
movq %rsi, %r13
movq %rdi, %r14
leaq 0x1(%rdx), %rax
pushq $0x3
popq %rcx
cqto
idivq %rcx
movq %rdx, %rbx
xorl %esi, %esi
cmpq %r12, %rdx
setne %sil
leaq (%rsi,%rbp), %rax
incq %rax
cqto
idivq %rcx
movq %rdx, %r15
movq %rbp, %rax
subq %rsi, %rax
addq $0x2, %rax
cqto
idivq %rcx
movq (%r13), %rax
imulq $0x18, %r15, %rcx
movq %rcx, (%rsp)
addq %rax, %rcx
imulq $0x18, %rdx, %rsi
movq %rsi, 0x10(%rsp)
addq %rsi, %rax
cmpq %r8, %rbp
movq %rdi, 0x18(%rsp)
movq %rbx, 0x30(%rsp)
movq %r12, 0x28(%rsp)
movq %rdx, 0x8(%rsp)
jne 0x1e47e
movsd (%rcx,%rbp,8), %xmm0
movsd (%rax,%rbp,8), %xmm1
callq 0x5090
movsd %xmm0, (%r14)
xorpd %xmm1, %xmm1
cmpq %r12, %rbx
je 0x1e4fb
ucomisd %xmm0, %xmm1
jmp 0x1e4ff
movsd (%rcx,%rdx,8), %xmm0
movsd (%rax,%rdx,8), %xmm1
callq 0x5090
movapd %xmm0, %xmm2
movsd %xmm0, (%r14)
imulq $0x18, %rbp, %rax
addq (%r13), %rax
movsd (%rax,%rbp,8), %xmm0
movhpd (%rax,%r15,8), %xmm0    # xmm0 = xmm0[0],mem[0]
mulpd %xmm0, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
sqrtsd %xmm1, %xmm1
xorpd %xmm0, %xmm0
cmpq %r12, %rbx
je 0x1e57b
ucomisd %xmm2, %xmm0
ja 0x1e585
movq 0x8(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
xorpd 0xb2a(%rip), %xmm0      # 0x1f010
movsd %xmm2, 0x20(%rsp)
callq 0x5090
movq 0x18(%rsp), %r12
jmp 0x1e5ca
ucomisd %xmm1, %xmm0
movq (%rsp), %r14
movq 0x10(%rsp), %rbx
jbe 0x1e631
xorl %eax, %eax
ucomisd %xmm1, %xmm0
seta %al
leaq 0x4c52(%rip), %rcx      # 0x23170
addsd (%rcx,%rax,8), %xmm0
movsd %xmm0, (%rsp)
movq 0x18(%rsp), %r12
movsd %xmm0, (%r12)
movq (%r13), %rax
leaq (%rax,%r14), %rcx
leaq (%rax,%rbx), %rdx
movsd (%rcx,%rbp,8), %xmm2
movhpd (%rdx,%rbp,8), %xmm2    # xmm2 = xmm2[0],mem[0]
mulpd %xmm2, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
sqrtsd %xmm1, %xmm0
imulq $0x18, %rbp, %rcx
addq %rax, %rcx
movsd (%rcx,%rbp,8), %xmm1
callq 0x5090
xorpd 0xa9a(%rip), %xmm0      # 0x1f010
jmp 0x1e676
ucomisd %xmm0, %xmm2
jbe 0x1e4d4
xorl %ecx, %ecx
ucomisd %xmm0, %xmm2
seta %cl
leaq 0x4bdb(%rip), %rdx      # 0x23170
addsd (%rdx,%rcx,8), %xmm2
movsd %xmm2, 0x20(%rsp)
movq 0x18(%rsp), %r12
movsd %xmm2, (%r12)
movq 0x8(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movapd 0xa53(%rip), %xmm2      # 0x1f010
xorpd %xmm2, %xmm0
xorpd %xmm2, %xmm1
callq 0x5090
movsd %xmm0, 0x8(%r12)
movsd 0x20(%rsp), %xmm0
callq 0x50e0
movsd %xmm0, 0x8(%rsp)
movsd 0x20(%rsp), %xmm0
callq 0x5680
movapd %xmm0, %xmm1
movq (%r13), %rax
movq 0x10(%rsp), %rdx
addq %rax, %rdx
movq (%rsp), %rcx
addq %rax, %rcx
movsd (%rcx,%rbp,8), %xmm2
mulsd %xmm0, %xmm2
movsd (%rdx,%rbp,8), %xmm0
movsd 0x8(%rsp), %xmm3
mulsd %xmm3, %xmm0
mulsd (%rdx,%r15,8), %xmm3
subsd %xmm2, %xmm0
mulsd (%rcx,%r15,8), %xmm1
jmp 0x1e6d3
movq (%r13), %rax
leaq (%rax,%r14), %rcx
leaq (%rax,%rbx), %rdx
movsd (%rcx,%rbp,8), %xmm2
movhpd (%rdx,%rbp,8), %xmm2    # xmm2 = xmm2[0],mem[0]
mulpd %xmm2, %xmm2
movsd %xmm0, (%rsp)
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
sqrtsd %xmm1, %xmm0
imulq $0x18, %rbp, %rcx
addq %rax, %rcx
movsd (%rcx,%rbp,8), %xmm1
callq 0x5090
movq 0x18(%rsp), %r12
movsd %xmm0, 0x8(%r12)
movsd (%rsp), %xmm0
callq 0x50e0
movsd %xmm0, 0x10(%rsp)
movsd (%rsp), %xmm0
callq 0x5680
movapd %xmm0, %xmm1
movq (%r13), %rax
addq %rax, %r14
addq %rax, %rbx
movq 0x8(%rsp), %rax
movsd (%rbx,%rax,8), %xmm2
movsd 0x10(%rsp), %xmm3
mulsd %xmm3, %xmm2
movsd (%r14,%rax,8), %xmm0
mulsd %xmm1, %xmm0
mulsd (%rbx,%r15,8), %xmm3
subsd %xmm2, %xmm0
mulsd (%r14,%r15,8), %xmm1
subsd %xmm3, %xmm1
callq 0x5090
movsd %xmm0, 0x10(%r12)
movq 0x28(%rsp), %rax
cmpq %rax, 0x30(%rsp)
jne 0x1e6ff
leaq 0x38(%rsp), %rsi
movq %r12, (%rsi)
movq %r12, %rdi
callq 0x1e7b8
movq %r12, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop