// File: /workspace/github_cpp_makefile_star2_O1/Luthaf[P]zeopp/rmsd.cc
// Function: fast_rmsd(double (*) [3], double (*) [3], int, double*)
void fast_rmsd(double ref_xlist[][3],
               double mov_xlist[][3], 
               int n_list,
               double* rmsd)
{ 
  double R[3][3];
  double d0,d1,d2,e0,e1,f0;
  double omega;
  double mov_com[3];
  double mov_to_ref[3];

  /* cubic roots */
  double r1,r2,r3;
  double rlow;
  
  double v[3];
  double Eo, residual;
    
  setup_rotation(ref_xlist, mov_xlist, n_list, 
                 mov_com, mov_to_ref, R, &Eo);
  
  /* 
   * check if the determinant is greater than 0 to
   * see if R produces a right-handed or left-handed
   * co-ordinate system.
   */
  cross(v, &R[1][0], &R[2][0]);
  if (dot(&R[0][0], v) > 0.0)
    omega = 1.0;
  else
    omega = -1.0;

  /*
   * get elements we need from tran(R) x R 
   *  (funky matrix naming relic of first attempt using pivots)
   *          matrix = d0 e0 f0
   *                      d1 e1
   *                         d2
   * divide matrix by d0, so that cubic root algorithm can handle it 
   */
   
  d0 =  R[0][0]*R[0][0] + R[1][0]*R[1][0] + R[2][0]*R[2][0];

  d1 = (R[0][1]*R[0][1] + R[1][1]*R[1][1] + R[2][1]*R[2][1])/d0;
  d2 = (R[0][2]*R[0][2] + R[1][2]*R[1][2] + R[2][2]*R[2][2])/d0;

  e0 = (R[0][0]*R[0][1] + R[1][0]*R[1][1] + R[2][0]*R[2][1])/d0;
  e1 = (R[0][1]*R[0][2] + R[1][1]*R[1][2] + R[2][1]*R[2][2])/d0;

  f0 = (R[0][0]*R[0][2] + R[1][0]*R[1][2] + R[2][0]*R[2][2])/d0;

  /* cubic roots */
  {
    double B, C, D, q, q3, r, theta;
    /*
     * solving for eigenvalues as det(A-I*lambda) = 0
     * yeilds the values below corresponding to:
     * lambda**3 + B*lambda**2 + C*lambda + D = 0
     *   (given that d0=1.)
     */
    B = -1.0 - d1 - d2;
    C = d1 + d2 + d1*d2 - e0*e0 - f0*f0 - e1*e1;
    D = e0*e0*d2 + e1*e1 + f0*f0*d1 - d1*d2 - 2*e0*f0*e1;

    /* cubic root method of Viete with all safety belts off */
    q = (B*B - 3.0*C) / 9.0;
    q3 = q*q*q;
    r = (2.0*B*B*B - 9.0*B*C + 27.0*D) / 54.0;
    theta = acos(r/sqrt(q3));
    r1 = r2 = r3 = -2.0*sqrt(q);
    r1 *= cos(theta/3.0);
    r2 *= cos((theta + 2.0*PI) / 3.0);
    r3 *= cos((theta - 2.0*PI) / 3.0);
    r1 -= B / 3.0;
    r2 -= B / 3.0;
    r3 -= B / 3.0;
  }

  /* undo the d0 norm to get eigenvalues */
  r1 = r1*d0;
  r2 = r2*d0;
  r3 = r3*d0;

  /* set rlow to lowest eigenval; set other two to r1,r2 */
  if (r3<r1 && r3<r2)
  {
    rlow = r3;
  }
  else if (r2<r1 && r2<r3)
  {
    rlow = r2; 
    r2 = r3;
  } 
  else 
  { 
    rlow = r1; 
    r1 = r3;
  }

  residual = Eo - sqrt(r1) - sqrt(r2) - omega*sqrt(rlow);
  *rmsd = sqrt( (double) residual*2.0 / ((double) n_list) ); 
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x120, %rsp            # imm = 0x120
movq %rcx, %rbx
movl %edx, %ebp
leaq 0x88(%rsp), %rax
movq %rax, (%rsp)
leaq 0xb0(%rsp), %rcx
leaq 0x90(%rsp), %r8
leaq 0xd0(%rsp), %r14
movq %r14, %r9
callq 0xa3326
movsd 0x20(%r14), %xmm7
movsd 0x40(%r14), %xmm9
movsd 0x28(%r14), %xmm8
movsd 0x38(%r14), %xmm12
movsd 0x30(%r14), %xmm10
movsd 0x18(%r14), %xmm11
movsd (%r14), %xmm5
movsd 0x8(%r14), %xmm4
movsd 0x10(%r14), %xmm6
movapd %xmm11, %xmm0
mulsd %xmm11, %xmm0
movapd %xmm5, %xmm1
mulsd %xmm5, %xmm1
addsd %xmm0, %xmm1
movapd %xmm10, %xmm13
mulsd %xmm10, %xmm13
addsd %xmm1, %xmm13
movapd %xmm7, %xmm0
mulsd %xmm7, %xmm0
movapd %xmm4, %xmm1
mulsd %xmm4, %xmm1
addsd %xmm0, %xmm1
movapd %xmm12, %xmm0
mulsd %xmm12, %xmm0
addsd %xmm1, %xmm0
divsd %xmm13, %xmm0
movapd %xmm8, %xmm1
mulsd %xmm8, %xmm1
movapd %xmm6, %xmm3
mulsd %xmm6, %xmm3
addsd %xmm1, %xmm3
movapd %xmm9, %xmm2
mulsd %xmm9, %xmm2
addsd %xmm3, %xmm2
divsd %xmm13, %xmm2
movapd %xmm11, %xmm1
mulsd %xmm7, %xmm1
movapd %xmm5, %xmm3
mulsd %xmm4, %xmm3
addsd %xmm1, %xmm3
movapd %xmm10, %xmm14
mulsd %xmm12, %xmm14
addsd %xmm3, %xmm14
divsd %xmm13, %xmm14
movsd %xmm7, 0x38(%rsp)
movapd %xmm7, %xmm1
mulsd %xmm8, %xmm1
movsd %xmm4, 0x30(%rsp)
mulsd %xmm6, %xmm4
addsd %xmm1, %xmm4
movsd %xmm12, 0x60(%rsp)
movapd %xmm12, %xmm3
mulsd %xmm9, %xmm3
addsd %xmm4, %xmm3
movsd %xmm11, 0x68(%rsp)
movapd %xmm11, %xmm1
movsd %xmm8, 0x80(%rsp)
mulsd %xmm8, %xmm1
movsd %xmm5, 0x20(%rsp)
movsd %xmm6, 0x28(%rsp)
mulsd %xmm6, %xmm5
addsd %xmm1, %xmm5
movsd %xmm10, 0x70(%rsp)
movapd %xmm10, %xmm4
movsd %xmm9, 0x78(%rsp)
mulsd %xmm9, %xmm4
addsd %xmm5, %xmm4
movsd 0xaf122(%rip), %xmm7    # 0x1532d0
subsd %xmm0, %xmm7
subsd %xmm2, %xmm7
movapd %xmm0, %xmm1
addsd %xmm2, %xmm1
movapd %xmm0, %xmm5
mulsd %xmm2, %xmm5
addsd %xmm5, %xmm1
movapd %xmm14, %xmm6
mulsd %xmm14, %xmm6
subsd %xmm6, %xmm1
mulsd %xmm2, %xmm6
divsd %xmm13, %xmm3
mulsd 0xb44ee(%rip), %xmm14   # 0x1586d8
movsd %xmm13, 0x58(%rsp)
divsd %xmm13, %xmm4
mulsd %xmm4, %xmm14
mulsd %xmm4, %xmm4
subsd %xmm4, %xmm1
mulsd %xmm3, %xmm14
mulsd %xmm3, %xmm3
subsd %xmm3, %xmm1
addsd %xmm3, %xmm6
mulsd %xmm0, %xmm4
addsd %xmm6, %xmm4
subsd %xmm5, %xmm4
movsd 0xb36f8(%rip), %xmm0    # 0x157920
mulsd %xmm1, %xmm0
movapd %xmm7, %xmm2
mulsd %xmm7, %xmm2
addsd %xmm0, %xmm2
divsd 0xaadd0(%rip), %xmm2    # 0x14f010
addsd %xmm4, %xmm14
movsd 0xb4493(%rip), %xmm0    # 0x1586e0
mulsd %xmm7, %xmm0
mulsd %xmm1, %xmm0
movapd %xmm7, %xmm1
addsd %xmm7, %xmm1
mulsd %xmm7, %xmm1
movsd %xmm7, 0x50(%rsp)
mulsd %xmm7, %xmm1
addsd %xmm0, %xmm1
movapd %xmm2, %xmm0
mulsd 0xb446c(%rip), %xmm14   # 0x1586e8
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm14
divsd 0xb4462(%rip), %xmm14   # 0x1586f0
movsd %xmm2, 0x18(%rsp)
mulsd %xmm2, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xa42a8
sqrtsd %xmm0, %xmm0
jmp 0xa42bb
movsd %xmm14, 0x10(%rsp)
callq 0x4350
movsd 0x10(%rsp), %xmm14
divsd %xmm0, %xmm14
movapd %xmm14, %xmm0
callq 0x4400
movsd %xmm0, 0x10(%rsp)
movsd 0x18(%rsp), %xmm0
ucomisd 0xaefe2(%rip), %xmm0    # 0x1532c0
jb 0xa42e6
sqrtsd %xmm0, %xmm0
jmp 0xa42eb
callq 0x4350
mulsd 0xb43e5(%rip), %xmm0    # 0x1586d8
movsd %xmm0, 0x18(%rsp)
movsd 0x10(%rsp), %xmm0
divsd 0xafed9(%rip), %xmm0    # 0x1541e0
callq 0x4800
mulsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0xab798(%rip), %xmm0    # 0x14fab8
addsd 0x10(%rsp), %xmm0
divsd 0xafeb2(%rip), %xmm0    # 0x1541e0
callq 0x4800
mulsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x10(%rsp), %xmm0
addsd 0xb43ab(%rip), %xmm0    # 0x1586f8
divsd 0xafe8b(%rip), %xmm0    # 0x1541e0
callq 0x4800
movsd 0x40(%rsp), %xmm9
mulsd 0x18(%rsp), %xmm0
movsd 0x50(%rsp), %xmm1
divsd 0xafe6b(%rip), %xmm1    # 0x1541e0
movsd 0x48(%rsp), %xmm2
subsd %xmm1, %xmm2
subsd %xmm1, %xmm9
subsd %xmm1, %xmm0
movsd 0x58(%rsp), %xmm1
mulsd %xmm1, %xmm2
mulsd %xmm1, %xmm9
mulsd %xmm1, %xmm0
movapd %xmm2, %xmm1
ucomisd %xmm0, %xmm2
jbe 0xa43c4
ucomisd %xmm0, %xmm9
jbe 0xa43c4
movsd %xmm0, 0x18(%rsp)
movapd %xmm1, %xmm0
movsd 0x20(%rsp), %xmm2
movsd 0x30(%rsp), %xmm3
jmp 0xa43f6
ucomisd %xmm9, %xmm1
movsd 0x20(%rsp), %xmm2
movsd 0x30(%rsp), %xmm3
jbe 0xa43f0
ucomisd %xmm9, %xmm0
jbe 0xa43f0
movsd %xmm9, 0x18(%rsp)
movapd %xmm0, %xmm9
movapd %xmm1, %xmm0
jmp 0xa43f6
movsd %xmm1, 0x18(%rsp)
movsd 0x70(%rsp), %xmm6
movapd %xmm6, %xmm1
movsd 0x38(%rsp), %xmm4
mulsd %xmm4, %xmm1
movsd 0x68(%rsp), %xmm7
movapd %xmm7, %xmm10
movsd 0x60(%rsp), %xmm8
mulsd %xmm8, %xmm10
subsd %xmm1, %xmm10
movsd 0x80(%rsp), %xmm1
mulsd %xmm1, %xmm8
movsd 0x78(%rsp), %xmm5
mulsd %xmm5, %xmm4
subsd %xmm8, %xmm4
mulsd %xmm7, %xmm5
mulsd %xmm6, %xmm1
subsd %xmm5, %xmm1
mulsd %xmm1, %xmm3
mulsd %xmm4, %xmm2
movsd 0x88(%rsp), %xmm4
xorpd %xmm5, %xmm5
ucomisd %xmm5, %xmm0
jb 0xa4470
sqrtsd %xmm0, %xmm0
jmp 0xa44b9
movsd %xmm2, 0x20(%rsp)
movsd %xmm3, 0x30(%rsp)
movsd %xmm9, 0x40(%rsp)
movsd %xmm4, 0x10(%rsp)
movsd %xmm10, 0x38(%rsp)
callq 0x4350
xorpd %xmm5, %xmm5
movsd 0x38(%rsp), %xmm10
movsd 0x10(%rsp), %xmm4
movsd 0x40(%rsp), %xmm9
movsd 0x30(%rsp), %xmm3
movsd 0x20(%rsp), %xmm2
movsd 0x28(%rsp), %xmm1
subsd %xmm0, %xmm4
addsd %xmm3, %xmm2
mulsd %xmm10, %xmm1
ucomisd %xmm5, %xmm9
jb 0xa44dd
xorps %xmm0, %xmm0
sqrtsd %xmm9, %xmm0
jmp 0xa450b
movapd %xmm9, %xmm0
movsd %xmm1, 0x28(%rsp)
movsd %xmm2, 0x20(%rsp)
movsd %xmm4, 0x10(%rsp)
callq 0x4350
movsd 0x10(%rsp), %xmm4
movsd 0x20(%rsp), %xmm2
movsd 0x28(%rsp), %xmm1
subsd %xmm0, %xmm4
addsd %xmm2, %xmm1
xorpd %xmm2, %xmm2
movsd 0x18(%rsp), %xmm0
ucomisd %xmm2, %xmm0
jb 0xa4529
sqrtsd %xmm0, %xmm0
jmp 0xa454a
movsd %xmm1, 0x28(%rsp)
movsd %xmm4, 0x10(%rsp)
callq 0x4350
xorpd %xmm2, %xmm2
movsd 0x10(%rsp), %xmm4
movsd 0x28(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm2, %xmm1
seta %al
leaq 0xb01b6(%rip), %rcx     # 0x154710
mulsd (%rcx,%rax,8), %xmm0
addsd %xmm4, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %ebp, %xmm1
addsd %xmm0, %xmm0
divsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
jb 0xa457e
sqrtsd %xmm0, %xmm0
jmp 0xa4583
callq 0x4350
movsd %xmm0, (%rbx)
addq $0x120, %rsp            # imm = 0x120
popq %rbx
popq %r14
popq %rbp
retq
nop