// File: /workspace/github_cpp_makefile_star2_O2/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 0x438e
andq $0x0, 0x308(%rbx)
movq %rbx, %rdi
callq 0x3ee4
movl %eax, %r14d
movsd 0x2a0(%rbx), %xmm0
movsd 0x2b8(%rbx), %xmm1
movsd %xmm0, 0x280(%rbx)
movsd %xmm1, 0x288(%rbx)
movq %rbx, %rdi
callq 0x3a9a
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 0x3a9a
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 0x564c
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x44dd
xorl %eax, %eax
cmpq $0x60, %rax
je 0x44dd
movsd 0x238(%rbx,%rax), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x238(%rbx,%rax)
addq $0x20, %rax
jmp 0x44bb
movsd 0x2e8(%rbx), %xmm0
callq 0x5584
movsd %xmm0, -0x30(%rbp)
movsd 0x2d0(%rbx), %xmm0
callq 0x5584
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1a8(%rbx)
movsd 0x2e8(%rbx), %xmm0
callq 0x5584
movsd %xmm0, -0x30(%rbp)
movsd 0x2d0(%rbx), %xmm0
callq 0x558e
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1c8(%rbx)
movsd 0x2e8(%rbx), %xmm0
callq 0x558e
movsd %xmm0, 0x1e8(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x5584
movsd %xmm0, -0x30(%rbp)
movsd 0x2d8(%rbx), %xmm0
callq 0x5584
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1b0(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x5584
movsd %xmm0, -0x30(%rbp)
movsd 0x2d8(%rbx), %xmm0
callq 0x558e
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x1d0(%rbx)
movsd 0x2f0(%rbx), %xmm0
callq 0x558e
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 0x564c
ucomisd 0x1b9d8(%rip), %xmm0    # 0x20020
jbe 0x466e
xorl %eax, %eax
cmpq $0x60, %rax
je 0x466e
movsd 0x1b8(%rbx,%rax), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x1b8(%rbx,%rax)
addq $0x20, %rax
jmp 0x464c
leaq 0x1a8(%rbx), %rax
pushq $0x1
popq %rcx
cmpq $0x4, %rcx
je 0x46a2
xorl %edx, %edx
cmpq $0x3, %rdx
je 0x4699
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x100(%rax,%rdx,8)
incq %rdx
jmp 0x4680
incq %rcx
addq $0x20, %rax
jmp 0x4678
movq %rbx, %rdi
callq 0x38c0
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)
pushq $0x1
popq %r15
cmpq $0x4, %r15
je 0x47da
movq -0x48(%rbp), %rax
pushq $0x1
popq %rcx
cmpq $0x4, %rcx
je 0x4714
xorl %edx, %edx
cmpq $0x3, %rdx
je 0x470b
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x100(%rax,%rdx,8)
incq %rdx
jmp 0x46f2
incq %rcx
addq $0x20, %rax
jmp 0x46ea
xorl %r13d, %r13d
cmpq $0x18, %r13
je 0x47c8
xorpd %xmm1, %xmm1
movsd -0x30(%rbp), %xmm0
ucomisd %xmm1, %xmm0
setnp %al
sete %r12b
andq $0x0, 0xa0(%rbx,%r15,8)
andb %al, %r12b
andq $0x0, 0xc0(%rbx,%r15,8)
andq $0x0, 0xe0(%rbx,%r15,8)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq -0x38(%rbp), %rcx
movq %rax, (%rcx,%r13,4)
movq %rbx, %rdi
callq 0x38c0
movsd 0x290(%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
setnp %al
sete %cl
andb %al, %cl
andb %r14b, %r12b
andb %cl, %r12b
movsd -0x30(%rbp), %xmm1
ucomisd %xmm2, %xmm1
divsd %xmm1, %xmm0
jne 0x47a4
jp 0x47a4
movsd 0x1b86c(%rip), %xmm0    # 0x20010
movzbl %r14b, %eax
movzbl %r12b, %ecx
cmovnel %eax, %ecx
cmovpl %eax, %ecx
movq -0x40(%rbp), %rax
movsd %xmm0, (%rax,%r13)
addq $0x8, %r13
movl %ecx, %r14d
jmp 0x4717
incq %r15
addq $0x20, -0x40(%rbp)
addq $0x8, -0x38(%rbp)
jmp 0x46d9
leaq 0x100(%rbx), %rax
leaq 0x128(%rbx), %rcx
pushq $0x1
popq %rdx
cmpq $0x4, %rdx
je 0x480c
xorl %esi, %esi
cmpq $0x3, %rsi
je 0x4803
andq $0x0, (%rcx,%rsi,8)
incq %rsi
jmp 0x47f3
incq %rdx
addq $0x20, %rcx
jmp 0x47eb
leaq 0x228(%rbx), %rcx
leaq 0x28(%rbx), %rdx
pushq $0x1
popq %rsi
movq %rsi, %rdi
cmpq $0x4, %rdi
je 0x4878
movq %rdi, %r8
shlq $0x5, %r8
addq %rax, %r8
movq %rdx, %r9
movq %rsi, %r10
cmpq $0x4, %r10
je 0x486f
leaq (%r8,%r10,8), %r11
movsd (%r11), %xmm0
xorl %r15d, %r15d
cmpq $0x18, %r15
je 0x4866
movsd (%rcx,%r15), %xmm1
mulsd (%r9,%r15,4), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%r11)
addq $0x8, %r15
jmp 0x4845
incq %r10
addq $0x8, %r9
jmp 0x4833
incq %rdi
addq $0x20, %rcx
jmp 0x481d
leaq 0x128(%rbx), %rax
movq %rax, -0x48(%rbp)
leaq 0x28(%rbx), %rax
movq %rax, -0x40(%rbp)
leaq 0xa8(%rbx), %rax
movq %rax, -0x38(%rbp)
pushq $0x1
popq %r15
cmpq $0x4, %r15
je 0x49ad
movq -0x48(%rbp), %rax
pushq $0x1
popq %rcx
cmpq $0x4, %rcx
je 0x48d2
xorl %edx, %edx
cmpq $0x3, %rdx
je 0x48c9
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, -0x80(%rax,%rdx,8)
incq %rdx
jmp 0x48b3
incq %rcx
addq $0x20, %rax
jmp 0x48ab
movq %rbx, %rdi
callq 0x38c0
movsd 0x290(%rbx), %xmm0
movsd %xmm0, -0x30(%rbp)
xorl %r13d, %r13d
cmpq $0x18, %r13
je 0x499b
xorpd %xmm1, %xmm1
movsd -0x30(%rbp), %xmm0
ucomisd %xmm1, %xmm0
setnp %al
sete %r12b
andq $0x0, 0xa0(%rbx,%r15,8)
andb %al, %r12b
andq $0x0, 0xc0(%rbx,%r15,8)
andq $0x0, 0xe0(%rbx,%r15,8)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq -0x38(%rbp), %rcx
movq %rax, (%rcx,%r13,4)
movq %rbx, %rdi
callq 0x38c0
movsd 0x290(%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
setnp %al
sete %cl
andb %al, %cl
andb %r14b, %r12b
andb %cl, %r12b
movsd -0x30(%rbp), %xmm1
ucomisd %xmm2, %xmm1
divsd %xmm1, %xmm0
jne 0x4977
jp 0x4977
movsd 0x1b699(%rip), %xmm0    # 0x20010
movzbl %r14b, %eax
movzbl %r12b, %ecx
cmovnel %eax, %ecx
cmovpl %eax, %ecx
movq -0x40(%rbp), %rax
movsd %xmm0, (%rax,%r13)
addq $0x8, %r13
movl %ecx, %r14d
jmp 0x48ea
incq %r15
addq $0x20, -0x40(%rbp)
addq $0x8, -0x38(%rbp)
jmp 0x489a
andb $0x1, %r14b
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop