// File: /workspace/github_cpp_makefile_star2_O2/jamesgrimmett[P]orbital_determination/ex10-1_linear_least_squares.cc
// Function: main
int main() {

  int i;

  // The state vector (alpha and beta)
  std::vector<double> state;
  // The inverse of the information matrix (A^T * A)^-1
  std::vector<std::vector<double> > inv;

  // The observed values of x and y
  std::vector<double> x_obs = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
  std::vector<double> y_obs = {1.0, 1.0, 2.0, 3.0, 3.0, 4.0, 4.0, 6.0};

  // The two components of the general solution (A^T * A, and A^T * B)
  std::vector<std::vector<double> > ata = {{0.0, 0.0},{0.0, 0.0}};
  std::vector<double> atb = {0.0, 0.0};

  // fill ata and atb
  for ( i = 0; i < 8; i++ ) {
    ata[0][0] += 1.0;
    ata[0][1] += x_obs[i];
    ata[1][0] += x_obs[i];
    ata[1][1] += pow(x_obs[i], 2);

    atb[0] += y_obs[i];
    atb[1] += x_obs[i] * y_obs[i];
  }

  inv = inverse(ata);
  state = dot_product(inv, atb);

  std::cout << "ATA matrix  " << ata[0][0] << "  " << ata[0][1] << std::endl;
  std::cout << "            " << ata[1][0] << "  " << ata[1][1] << std::endl;
  std::cout << "ATb matrix  " << atb[0] << "  " << atb[1] << std::endl; 
  
  std::cout << "\nState:" << std::endl;
  std::cout << "alpha " << state[0] << std::endl;
  std::cout << "beta  " << state[1] << std::endl;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
movaps %xmm0, 0xa0(%rsp)
andq $0x0, 0xb0(%rsp)
movups 0xdd4(%rip), %xmm0      # 0x2060
leaq 0x60(%rsp), %rsi
movaps %xmm0, 0x30(%rsi)
movups 0xdb4(%rip), %xmm0      # 0x2050
movaps %xmm0, 0x20(%rsi)
movups 0xd99(%rip), %xmm0      # 0x2040
movaps %xmm0, 0x10(%rsi)
movupd 0xd7d(%rip), %xmm0      # 0x2030
movapd %xmm0, (%rsi)
leaq 0x118(%rsp), %rdi
pushq $0x8
popq %rdx
leaq 0xb8(%rsp), %rcx
callq 0x19ae
movups 0xdca(%rip), %xmm0      # 0x20a0
leaq 0x60(%rsp), %rsi
movaps %xmm0, 0x30(%rsi)
movups 0xdaa(%rip), %xmm0      # 0x2090
movaps %xmm0, 0x20(%rsi)
movups 0xd8f(%rip), %xmm0      # 0x2080
movaps %xmm0, 0x10(%rsi)
movupd 0xd73(%rip), %xmm0      # 0x2070
movapd %xmm0, (%rsi)
leaq 0xb8(%rsp), %rdi
pushq $0x8
popq %rdx
leaq 0x8(%rsp), %rcx
callq 0x19ae
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %rsi
movapd %xmm0, (%rsi)
leaq 0x60(%rsp), %rdi
pushq $0x2
popq %rdx
leaq 0x7(%rsp), %rcx
callq 0x19ae
leaq 0x78(%rsp), %rdi
leaq 0x130(%rsp), %rsi
xorpd %xmm0, %xmm0
movapd %xmm0, (%rsi)
pushq $0x2
popq %rdx
leaq 0x6(%rsp), %rcx
callq 0x19ae
leaq 0x8(%rsp), %rdi
leaq 0x60(%rsp), %rsi
pushq $0x2
popq %rdx
leaq 0x5(%rsp), %rcx
callq 0x19e4
pushq $0x18
popq %rbx
leaq (%rsp,%rbx), %rdi
addq $0x60, %rdi
callq 0x1af2
addq $-0x18, %rbx
cmpq $-0x18, %rbx
jne 0x1371
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %rsi
movapd %xmm0, (%rsi)
leaq 0x60(%rsp), %rdi
pushq $0x2
popq %rdx
leaq 0x130(%rsp), %rcx
callq 0x19ae
movq 0x8(%rsp), %rcx
movq (%rcx), %rax
movq 0x18(%rcx), %rcx
movq 0x118(%rsp), %rdx
movq 0xb8(%rsp), %rsi
movq 0x60(%rsp), %rdi
xorl %r8d, %r8d
movsd 0xc32(%rip), %xmm0      # 0x2008
cmpq $0x8, %r8
je 0x1443
movsd (%rax), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, (%rax)
movsd (%rdx,%r8,8), %xmm1
addsd 0x8(%rax), %xmm1
movsd %xmm1, 0x8(%rax)
movsd (%rdx,%r8,8), %xmm1
addsd (%rcx), %xmm1
movsd %xmm1, (%rcx)
movsd (%rdx,%r8,8), %xmm1
mulsd %xmm1, %xmm1
addsd 0x8(%rcx), %xmm1
movsd %xmm1, 0x8(%rcx)
movsd (%rsi,%r8,8), %xmm1
addsd (%rdi), %xmm1
movsd %xmm1, (%rdi)
movsd (%rdx,%r8,8), %xmm1
mulsd (%rsi,%r8,8), %xmm1
addsd 0x8(%rdi), %xmm1
movsd %xmm1, 0x8(%rdi)
incq %r8
jmp 0x13d6
leaq 0x100(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x1a1e
leaq 0x40(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x1787
leaq 0xa0(%rsp), %rbx
leaq 0x40(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1e08
movq %r14, %rdi
callq 0x1a78
leaq 0x100(%rsp), %rdi
callq 0x1a78
leaq 0xe8(%rsp), %rdi
movq %rbx, %rsi
callq 0x1a1e
leaq 0xd0(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x1a9a
leaq 0x40(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0x185f
leaq 0x20(%rsp), %rdi
leaq 0x40(%rsp), %rbx
movq %rbx, %rsi
callq 0x1e80
movq %rbx, %rdi
callq 0x1af2
leaq 0xd0(%rsp), %rdi
callq 0x1af2
leaq 0xe8(%rsp), %rdi
callq 0x1a78
movq 0x2acd(%rip), %rdi      # 0x3fd8
leaq 0xb9e(%rip), %rsi       # 0x20b0
callq 0x10a0
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movsd (%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
leaq 0xb95(%rip), %rsi       # 0x20c7
movq %rax, %rdi
callq 0x10a0
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movsd 0x8(%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
callq 0x1060
movq 0x2a7a(%rip), %rdi      # 0x3fd8
leaq 0xb58(%rip), %rsi       # 0x20bd
callq 0x10a0
movq 0x8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movsd (%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
leaq 0xb41(%rip), %rsi       # 0x20c7
movq %rax, %rdi
callq 0x10a0
movq 0x8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movsd 0x8(%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
callq 0x1060
movq 0x2a25(%rip), %rdi      # 0x3fd8
leaq 0xb10(%rip), %rsi       # 0x20ca
callq 0x10a0
movq 0x60(%rsp), %rcx
movsd (%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
leaq 0xaf0(%rip), %rsi       # 0x20c7
movq %rax, %rdi
callq 0x10a0
movq 0x60(%rsp), %rcx
movsd 0x8(%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
callq 0x1060
movq 0x29d8(%rip), %rdi      # 0x3fd8
leaq 0xad0(%rip), %rsi       # 0x20d7
callq 0x10a0
movq %rax, %rdi
callq 0x1060
movq 0x29bd(%rip), %rdi      # 0x3fd8
leaq 0xabd(%rip), %rsi       # 0x20df
callq 0x10a0
movq 0x20(%rsp), %rcx
movsd (%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
callq 0x1060
movq 0x2991(%rip), %rdi      # 0x3fd8
leaq 0xa98(%rip), %rsi       # 0x20e6
callq 0x10a0
movq 0x20(%rsp), %rcx
movsd 0x8(%rcx), %xmm0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
callq 0x1060
leaq 0x60(%rsp), %rdi
callq 0x1af2
leaq 0x8(%rsp), %rdi
callq 0x1a78
leaq 0xb8(%rsp), %rdi
callq 0x1af2
leaq 0x118(%rsp), %rdi
callq 0x1af2
leaq 0xa0(%rsp), %rdi
callq 0x1a78
leaq 0x20(%rsp), %rdi
callq 0x1af2
xorl %eax, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r14
retq
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x1af2
jmp 0x16d4
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
jmp 0x16eb
jmp 0x1737
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x1a78
jmp 0x173a
jmp 0x1737
movq %rax, %rbx
jmp 0x1744
movq %rax, %rbx
pushq $0x18
popq %r14
leaq (%rsp,%r14), %rdi
addq $0x60, %rdi
callq 0x1af2
addq $-0x18, %r14
cmpq $-0x18, %r14
jne 0x1700
jmp 0x174e
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x1af2
jmp 0x174e
movq %rax, %rbx
jmp 0x174e
movq %rax, %rbx
jmp 0x175b
movq %rax, %rbx
jmp 0x1768
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x1af2
leaq 0x8(%rsp), %rdi
callq 0x1a78
leaq 0xb8(%rsp), %rdi
callq 0x1af2
leaq 0x118(%rsp), %rdi
callq 0x1af2
leaq 0xa0(%rsp), %rdi
callq 0x1a78
leaq 0x20(%rsp), %rdi
callq 0x1af2
movq %rbx, %rdi
callq 0x1120