// File: /workspace/github_cpp_makefile_star2_O3/philipperemy[P]digital-setting-circles/Calc.cpp
// Function: Calc::finalizeAlignment(bool)
bool Calc::finalizeAlignment(bool optimize_z3)
{
  int I, J, L, M, N;
  double A;
  double E;
  bool status;

  if (optimize_z3) {
    Z3 = 0.0;   // If optimization fails, leave Z3 set to 0.0
    status = optimizeZ3();
  } else
    status = true;

  // Keep going even if the Z3 optimization fails.

  // Initialize columns 1 and 2 of YY with the alignment az/el data,
  // corrected with Z123.

  F = alignAz[1];
  H = alignEl[1];
  AzEltoYY0();
  YY[1][1] = YY[1][0]; YY[2][1] = YY[2][0]; YY[3][1] = YY[3][0];

  F = alignAz[2];
  H = alignEl[2];
  AzEltoYY0();
  YY[1][2] = YY[1][0]; YY[2][2] = YY[2][0]; YY[3][2] = YY[3][0];

  // Set third column of array YY.
  YY[1][3]=YY[2][1]*YY[3][2]-YY[3][1]*YY[2][2];
  YY[2][3]=YY[3][1]*YY[1][2]-YY[1][1]*YY[3][2];
  YY[3][3]=YY[1][1]*YY[2][2]-YY[2][1]*YY[1][2];

  // Normalize third column of array YY.
  A=MathLib::sqrt(sqr(YY[1][3])+sqr(YY[2][3])+sqr(YY[3][3]));
  if (A > 0.0) {
    // Avoid 0/0 error if third column is all zeros
    for (I=1; I<=3; I++) {
      YY[I][3] /= A;
    }
  }


  // Initialize columns 1 and 2 of XX with the star RA/Dec data.
  XX[1][1] = MathLib::cos(alignDec[1])*MathLib::cos(alignRA[1]);
  XX[2][1] = MathLib::cos(alignDec[1])*MathLib::sin(alignRA[1]);
  XX[3][1] = MathLib::sin(alignDec[1]);
  XX[1][2] = MathLib::cos(alignDec[2])*MathLib::cos(alignRA[2]);
  XX[2][2] = MathLib::cos(alignDec[2])*MathLib::sin(alignRA[2]);
  XX[3][2] = MathLib::sin(alignDec[2]);

  // Set third column of array XX.
  XX[1][3]=XX[2][1]*XX[3][2]-XX[3][1]*XX[2][2];
  XX[2][3]=XX[3][1]*XX[1][2]-XX[1][1]*XX[3][2];
  XX[3][3]=XX[1][1]*XX[2][2]-XX[2][1]*XX[1][2];

  // Normalize third column of array XX.
  A=MathLib::sqrt(sqr(XX[1][3])+sqr(XX[2][3])+sqr(XX[3][3]));
  if (A > 0.0) {
    // Avoid 0/0 error if third column is all zeros
    for (I=1; I<=3; I++) {
      XX[I][3] /= A;
    }
  }



  //       TRANSFORM MATRIX
  for (I=1; I<=3; I++) {
    for (J=1; J<=3; J++) {
      VV[I][J]=XX[I][J];
    }
  }
  VVtoW(); E=W;

  for (M=1; M<=3; M++) {

    for (I=1; I<=3; I++) {
      for (J=1; J<=3; J++) {
	 VV[I][J]=XX[I][J];
      }
    }

    for (N=1; N<= 3; N++) {
      VV[1][M]=0; VV[2][M]=0; VV[3][M]=0; VV[N][M]=1;
      VVtoW();

      // Avoid problems with divide-by-zero.  Am not sure
      // under what conditions this could actually happen...
      if (W==0 && E==0) {
        QQ[M][N]=1;
      } else if (E==0) {
        QQ[M][N]=1;
        status = false;
      } else {
        QQ[M][N]=W/E;
      }
    }
  }


  for (I=1; I<=3; I++) {
    for (J=1; J<=3; J++) {
       RR[I][J]=0;
    }
  }

  for (I=1; I<=3; I++) {
    for (J=1; J<=3; J++) {
      for (L=1; L<=3; L++) {
	RR[I][J] += (YY[I][L]*QQ[L][J]);
      }
    }
  }

  for (M=1; M<=3; M++) {

     for (I=1; I<=3; I++) {
       for (J=1; J<=3; J++) {
	 VV[I][J]=RR[I][J];
       }
     }

     VVtoW(); E=W;
     for (N=1; N<=3; N++) {
       VV[1][M]=0; VV[2][M]=0; VV[3][M]=0; VV[N][M]=1;
       VVtoW();
       // Avoid problems with divide-by-zero.  Am not sure
       // under what conditions this could actually happen...
       if (W==0 && E==0) {
	 QQ[M][N]=1;
       } else if (E==0) {
	 QQ[M][N]=1;
	 status = false;
       } else {
	 QQ[M][N]=W/E;
       }
     }
  }

  return status;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movb $0x1, %r14b
testl %esi, %esi
je 0x45df
movq $0x0, 0x308(%rbx)
movq %rbx, %rdi
callq 0x3fdc
movl %eax, %r14d
movsd 0x2a0(%rbx), %xmm0
movsd 0x2b8(%rbx), %xmm1
movsd %xmm0, 0x280(%rbx)
movsd %xmm1, 0x288(%rbx)
movq %rbx, %rdi
callq 0x3b0c
movsd 0x220(%rbx), %xmm0
movsd 0x240(%rbx), %xmm1
movsd %xmm0, 0x228(%rbx)
movsd %xmm1, 0x248(%rbx)
movsd 0x260(%rbx), %xmm0
movsd %xmm0, 0x268(%rbx)
movsd 0x2a8(%rbx), %xmm0
movsd %xmm0, 0x280(%rbx)
movsd 0x2c0(%rbx), %xmm0
movsd %xmm0, 0x288(%rbx)
movq %rbx, %rdi
callq 0x3b0c
movsd 0x220(%rbx), %xmm2
movsd 0x228(%rbx), %xmm0
movsd %xmm2, 0x230(%rbx)
movsd 0x240(%rbx), %xmm3
movsd %xmm3, 0x250(%rbx)
movsd 0x260(%rbx), %xmm4
movsd %xmm4, 0x270(%rbx)
movsd 0x248(%rbx), %xmm5
movsd 0x268(%rbx), %xmm1
movapd %xmm5, %xmm6
mulsd %xmm4, %xmm6
mulsd %xmm0, %xmm4
mulsd %xmm3, %xmm0
mulsd %xmm1, %xmm3
subsd %xmm3, %xmm6
movsd %xmm6, 0x238(%rbx)
mulsd %xmm2, %xmm1
subsd %xmm4, %xmm1
movsd %xmm1, 0x258(%rbx)
mulsd %xmm5, %xmm2
subsd %xmm2, %xmm0
movsd %xmm0, 0x278(%rbx)
mulsd %xmm6, %xmm6
mulsd %xmm1, %xmm1
addsd %xmm6, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
callq 0x5920
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x472c
xorl %eax, %eax
movsd 0x238(%rbx,%rax), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x238(%rbx,%rax)
addq $0x20, %rax
cmpq $0x60, %rax
jne 0x470c
movsd 0x2e8(%rbx), %xmm0
callq 0x5858
movsd %xmm0, -0x30(%rbp)
movsd 0x2d0(%rbx), %xmm0
callq 0x5858
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1a8(%rbx)
movsd 0x2e8(%rbx), %xmm0
callq 0x5858
movsd %xmm0, -0x30(%rbp)
movsd 0x2d0(%rbx), %xmm0
callq 0x5862
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1c8(%rbx)
movsd 0x2e8(%rbx), %xmm0
callq 0x5862
movsd %xmm0, 0x1e8(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x5858
movsd %xmm0, -0x30(%rbp)
movsd 0x2d8(%rbx), %xmm0
callq 0x5858
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1b0(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x5858
movsd %xmm0, -0x30(%rbp)
movsd 0x2d8(%rbx), %xmm0
callq 0x5862
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1d0(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x5862
movsd %xmm0, 0x1f0(%rbx)
movsd 0x1c8(%rbx), %xmm3
movsd 0x1e8(%rbx), %xmm2
movsd 0x1d0(%rbx), %xmm4
movapd %xmm4, %xmm1
mulsd %xmm2, %xmm1
movapd %xmm3, %xmm5
mulsd %xmm0, %xmm5
subsd %xmm1, %xmm5
movsd %xmm5, 0x1b8(%rbx)
movsd 0x1a8(%rbx), %xmm1
movsd 0x1b0(%rbx), %xmm6
mulsd %xmm1, %xmm0
mulsd %xmm6, %xmm2
subsd %xmm0, %xmm2
movsd %xmm2, 0x1d8(%rbx)
mulsd %xmm3, %xmm6
mulsd %xmm4, %xmm1
subsd %xmm6, %xmm1
movsd %xmm1, 0x1f8(%rbx)
mulsd %xmm5, %xmm5
mulsd %xmm2, %xmm2
addsd %xmm5, %xmm2
mulsd %xmm1, %xmm1
addsd %xmm2, %xmm1
movapd %xmm1, %xmm0
callq 0x5920
ucomisd 0x27789(%rip), %xmm0    # 0x2c020
jbe 0x48bb
xorl %eax, %eax
movsd 0x1b8(%rbx,%rax), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x1b8(%rbx,%rax)
addq $0x20, %rax
cmpq $0x60, %rax
jne 0x489b
leaq 0x1a8(%rbx), %rax
movl $0x1, %ecx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x100(%rax,%rdx,8)
incq %rdx
cmpq $0x3, %rdx
jne 0x48c9
incq %rcx
addq $0x20, %rax
cmpq $0x4, %rcx
jne 0x48c7
movq %rbx, %rdi
callq 0x3932
movsd 0x290(%rbx), %xmm0
movsd %xmm0, -0x30(%rbp)
leaq 0x1a8(%rbx), %rax
movq %rax, -0x48(%rbp)
leaq 0x28(%rbx), %rax
movq %rax, -0x40(%rbp)
leaq 0xa8(%rbx), %rax
movq %rax, -0x38(%rbp)
movl $0x1, %r12d
movq -0x48(%rbp), %rax
movl $0x1, %ecx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x100(%rax,%rdx,8)
incq %rdx
cmpq $0x3, %rdx
jne 0x4931
incq %rcx
addq $0x20, %rax
cmpq $0x4, %rcx
jne 0x492f
xorl %r15d, %r15d
xorpd %xmm1, %xmm1
movsd -0x30(%rbp), %xmm0
ucomisd %xmm1, %xmm0
setnp %al
sete %r13b
andb %al, %r13b
xorl %eax, %eax
movq %rax, 0xa0(%rbx,%r12,8)
movq %rax, 0xc0(%rbx,%r12,8)
movq %rax, 0xe0(%rbx,%r12,8)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq -0x38(%rbp), %rcx
movq %rax, (%rcx,%r15,4)
movq %rbx, %rdi
callq 0x3932
movsd 0x290(%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
setnp %al
sete %cl
andb %al, %cl
andb %r14b, %r13b
andb %cl, %r13b
movsd -0x30(%rbp), %xmm1
ucomisd %xmm2, %xmm1
divsd %xmm1, %xmm0
jne 0x49da
jp 0x49da
movsd 0x27636(%rip), %xmm0    # 0x2c010
movzbl %r14b, %eax
movzbl %r13b, %ecx
cmovnel %eax, %ecx
cmovpl %eax, %ecx
movl %ecx, %r14d
movq -0x40(%rbp), %rax
movsd %xmm0, (%rax,%r15)
addq $0x8, %r15
cmpq $0x18, %r15
jne 0x4958
incq %r12
addq $0x20, -0x40(%rbp)
addq $0x8, -0x38(%rbp)
cmpq $0x4, %r12
jne 0x4926
xorpd %xmm0, %xmm0
movupd %xmm0, 0x128(%rbx)
xorl %eax, %eax
movq %rax, 0x138(%rbx)
movupd %xmm0, 0x148(%rbx)
movq %rax, 0x158(%rbx)
movupd %xmm0, 0x168(%rbx)
movq %rax, 0x178(%rbx)
leaq 0x100(%rbx), %rax
leaq 0x228(%rbx), %rcx
leaq 0x28(%rbx), %rdx
movl $0x1, %esi
movq %rsi, %rdi
shlq $0x5, %rdi
addq %rax, %rdi
movq %rdx, %r8
movl $0x1, %r9d
leaq (%rdi,%r9,8), %r10
movsd (%r10), %xmm0
xorl %r11d, %r11d
movsd (%rcx,%r11), %xmm1
mulsd (%r8,%r11,4), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%r10)
addq $0x8, %r11
cmpq $0x18, %r11
jne 0x4a83
incq %r9
addq $0x8, %r8
cmpq $0x4, %r9
jne 0x4a77
incq %rsi
addq $0x20, %rcx
cmpq $0x4, %rsi
jne 0x4a64
leaq 0x128(%rbx), %rax
movq %rax, -0x48(%rbp)
leaq 0x28(%rbx), %rax
movq %rax, -0x40(%rbp)
leaq 0xa8(%rbx), %rax
movq %rax, -0x38(%rbp)
movl $0x1, %r15d
movq -0x48(%rbp), %rax
movl $0x1, %ecx
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x80(%rax,%rdx,8)
incq %rdx
cmpq $0x3, %rdx
jne 0x4aeb
incq %rcx
addq $0x20, %rax
cmpq $0x4, %rcx
jne 0x4ae9
movq %rbx, %rdi
callq 0x3932
movsd 0x290(%rbx), %xmm0
movsd %xmm0, -0x30(%rbp)
xorl %r12d, %r12d
xorpd %xmm1, %xmm1
movsd -0x30(%rbp), %xmm0
ucomisd %xmm1, %xmm0
setnp %al
sete %r13b
andb %al, %r13b
xorl %eax, %eax
movq %rax, 0xa0(%rbx,%r15,8)
movq %rax, 0xc0(%rbx,%r15,8)
movq %rax, 0xe0(%rbx,%r15,8)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq -0x38(%rbp), %rcx
movq %rax, (%rcx,%r12,4)
movq %rbx, %rdi
callq 0x3932
movsd 0x290(%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
setnp %al
sete %cl
andb %al, %cl
andb %r14b, %r13b
andb %cl, %r13b
movsd -0x30(%rbp), %xmm1
ucomisd %xmm2, %xmm1
divsd %xmm1, %xmm0
jne 0x4ba6
jp 0x4ba6
movsd 0x2746a(%rip), %xmm0    # 0x2c010
movzbl %r14b, %eax
movzbl %r13b, %ecx
cmovnel %eax, %ecx
cmovpl %eax, %ecx
movl %ecx, %r14d
movq -0x40(%rbp), %rax
movsd %xmm0, (%rax,%r12)
addq $0x8, %r12
cmpq $0x18, %r12
jne 0x4b24
incq %r15
addq $0x20, -0x40(%rbp)
addq $0x8, -0x38(%rbp)
cmpq $0x4, %r15
jne 0x4ae0
andb $0x1, %r14b
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq