// File: Pyboon[P]sage/isi_sage.cpp
// Function: IsiSage::ObjectiveFunction(Eigen::Matrix<std::complex<double>, 1, -1, 1, 1, -1>, double, Eigen::Matrix<std::complex<double>, -1, 2, 0, -1, 2>, Eigen::Matrix<std::complex<double>, -1, 2, 0, -1, 2>, int)
double IsiSage::ObjectiveFunction(RowVectorXcd tau_data, double doppler, MatrixX2cd C1, MatrixX2cd C2, const int iL){
    // X 
    MatrixXcd X(config.Rx, config.Tx);
    complex<double> cycle_data = 0;
    complex<double> temp = 0;
    for(int i_tx = 0; i_tx < config.Tx; ++i_tx){
        for(int i_rx = 0; i_rx < config.Rx; ++i_rx){
            cycle_data = 0;
            temp = 0;
            for(int i_cyc = 0; i_cyc < config.cycle_num; ++i_cyc){
                double t = (i_cyc * config.Tcy + i_tx * config.Tt + i_rx * config.Tr) * config.T; 
                temp.real(cos(2*PI* doppler *t));
                temp.imag(-sin(2*PI* doppler *t));
                cycle_data += temp * tau_data(i_cyc * config.subchannel_num + i_tx * config.Rx + i_rx);
            }
            X(i_rx, i_tx) = cycle_data;
        }
    }
    // f 
    RowVectorXcd c_2_1_H = C2.col(0).adjoint();
    RowVectorXcd c_2_2_H = C2.col(1).adjoint();
    VectorXcd c_1_1_conj = C1.col(0).conjugate();
    VectorXcd c_1_2_conj = C1.col(1).conjugate();
    Vector4cd f;
    f(0) = c_2_1_H * X * c_1_1_conj;
    f(1) = c_2_1_H * X * c_1_2_conj;
    f(2) = c_2_2_H * X * c_1_1_conj;
    f(3) = c_2_2_H * X * c_1_2_conj;
    // D
    Matrix2cd part1 = C2.adjoint() * C2;
    Matrix2cd part2 = C1.adjoint() * C1;
    MatrixXcd D = kroneckerProduct(part1, part2);
    complex<double> z = f.adjoint() * D.inverse() * f;
    return sqrt(norm(z));

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x660, %rsp            # imm = 0x660
movq %rsi, -0x560(%rbp)
movq %rdx, -0x558(%rbp)
movq %rcx, -0x550(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movq -0x8(%rbp), %rdx
movq %rdx, -0x548(%rbp)
movq %rdx, %rsi
addq $0x8, %rsi
addq $0xc, %rdx
leaq -0x48(%rbp), %rdi
callq 0x20450
leaq -0x58(%rbp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x14330
jmp 0x1eb39
leaq -0x78(%rbp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x14330
jmp 0x1eb4a
movl $0x0, -0x7c(%rbp)
movq -0x548(%rbp), %rcx
movl -0x7c(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0x1ed70
movl $0x0, -0x80(%rbp)
movq -0x548(%rbp), %rcx
movl -0x80(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x1ed60
leaq -0x58(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0x202e0
jmp 0x1eb8c
leaq -0x78(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0x202e0
jmp 0x1eb9a
movl $0x0, -0x84(%rbp)
movq -0x548(%rbp), %rcx
movl -0x84(%rbp), %eax
cmpl 0x10(%rcx), %eax
jge 0x1ed22
movq -0x548(%rbp), %rax
movl -0x84(%rbp), %ecx
movl 0xbc(%rax), %edx
imull %edx, %ecx
movl -0x7c(%rbp), %edx
movl 0xb4(%rax), %esi
imull %esi, %edx
addl %edx, %ecx
movl -0x80(%rbp), %edx
movl 0xb8(%rax), %esi
imull %esi, %edx
addl %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd 0xa8(%rax), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x18(%rbp), %xmm0
movsd 0x50c5f(%rip), %xmm1    # 0x6f870
mulsd %xmm1, %xmm0
movsd -0x90(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x9e90
leaq -0x78(%rbp), %rdi
callq 0x13d00
jmp 0x1ec31
movsd -0x18(%rbp), %xmm0
movsd 0x50c32(%rip), %xmm1    # 0x6f870
mulsd %xmm1, %xmm0
movsd -0x90(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x9180
movaps 0x50c36(%rip), %xmm1    # 0x6f890
pxor %xmm1, %xmm0
leaq -0x78(%rbp), %rdi
callq 0x13d20
jmp 0x1ec69
movq -0x560(%rbp), %rdi
movq -0x548(%rbp), %rcx
movl -0x84(%rbp), %eax
movl 0x8(%rcx), %edx
movl 0xa0(%rcx), %ecx
imull %ecx, %eax
movl -0x7c(%rbp), %ecx
imull %edx, %ecx
addl %ecx, %eax
movl -0x80(%rbp), %ecx
addl %ecx, %eax
movslq %eax, %rsi
callq 0x215f0
movq %rax, -0x568(%rbp)
jmp 0x1eca7
movq -0x568(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x20310
movsd %xmm1, -0x578(%rbp)
movsd %xmm0, -0x570(%rbp)
jmp 0x1ecc9
movsd -0x578(%rbp), %xmm0
movsd -0x570(%rbp), %xmm1
movsd %xmm1, -0xa0(%rbp)
movsd %xmm0, -0x98(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x203e0
jmp 0x1ecfb
jmp 0x1ecfd
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x1eba4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1f41e
movslq -0x80(%rbp), %rsi
movslq -0x7c(%rbp), %rdx
leaq -0x48(%rbp), %rdi
callq 0x13c40
movq %rax, -0x580(%rbp)
jmp 0x1ed3c
movq -0x580(%rbp), %rax
movq -0x58(%rbp), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x1eb6b
jmp 0x1ed62
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x1eb51
movq -0x550(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x128(%rbp), %rdi
callq 0x20580
jmp 0x1ed89
leaq -0xf0(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x218c0
jmp 0x1ed9e
leaq -0xb0(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x21910
jmp 0x1edb3
movq -0x550(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
movl $0x1, %edx
callq 0x20580
jmp 0x1edcd
leaq -0x178(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x218c0
jmp 0x1ede2
leaq -0x138(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x21910
jmp 0x1edf7
movq -0x558(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x238(%rbp), %rdi
callq 0x20580
jmp 0x1ee10
leaq -0x200(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x20e60
jmp 0x1ee25
leaq -0x1c0(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x20eb0
jmp 0x1ee3a
movq -0x558(%rbp), %rsi
leaq -0x2c0(%rbp), %rdi
movl $0x1, %edx
callq 0x20580
jmp 0x1ee54
leaq -0x288(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x20e60
jmp 0x1ee69
leaq -0x248(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x20eb0
jmp 0x1ee7e
leaq -0x300(%rbp), %rdi
callq 0x20cf0
jmp 0x1ee8c
leaq -0xb0(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x21950
movq %rdx, -0x590(%rbp)
movq %rax, -0x588(%rbp)
jmp 0x1eeac
movq -0x590(%rbp), %rax
movq -0x588(%rbp), %rcx
movq %rcx, -0x338(%rbp)
movq %rax, -0x330(%rbp)
leaq -0x328(%rbp), %rdi
leaq -0x338(%rbp), %rsi
leaq -0x1c0(%rbp), %rdx
callq 0x219a0
jmp 0x1eee4
leaq -0x328(%rbp), %rdi
callq 0x219f0
movsd %xmm1, -0x5a0(%rbp)
movsd %xmm0, -0x598(%rbp)
jmp 0x1ef02
movsd -0x5a0(%rbp), %xmm0
movsd -0x598(%rbp), %xmm1
movsd %xmm1, -0x310(%rbp)
movsd %xmm0, -0x308(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x300(%rbp), %rdi
callq 0x20fa0
movq %rax, -0x5a8(%rbp)
jmp 0x1ef3b
movq -0x5a8(%rbp), %rax
movups -0x310(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0xb0(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x21950
movq %rdx, -0x5b8(%rbp)
movq %rax, -0x5b0(%rbp)
jmp 0x1ef6c
movq -0x5b8(%rbp), %rax
movq -0x5b0(%rbp), %rcx
movq %rcx, -0x370(%rbp)
movq %rax, -0x368(%rbp)
leaq -0x360(%rbp), %rdi
leaq -0x370(%rbp), %rsi
leaq -0x248(%rbp), %rdx
callq 0x219a0
jmp 0x1efa4
leaq -0x360(%rbp), %rdi
callq 0x219f0
movsd %xmm1, -0x5c8(%rbp)
movsd %xmm0, -0x5c0(%rbp)
jmp 0x1efc2
movsd -0x5c8(%rbp), %xmm0
movsd -0x5c0(%rbp), %xmm1
movsd %xmm1, -0x348(%rbp)
movsd %xmm0, -0x340(%rbp)
leaq -0x300(%rbp), %rdi
movl $0x1, %esi
callq 0x20fa0
movq %rax, -0x5d0(%rbp)
jmp 0x1effc
movq -0x5d0(%rbp), %rax
movups -0x348(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x138(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x21950
movq %rdx, -0x5e0(%rbp)
movq %rax, -0x5d8(%rbp)
jmp 0x1f02d
movq -0x5e0(%rbp), %rax
movq -0x5d8(%rbp), %rcx
movq %rcx, -0x3a8(%rbp)
movq %rax, -0x3a0(%rbp)
leaq -0x398(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
leaq -0x1c0(%rbp), %rdx
callq 0x219a0
jmp 0x1f065
leaq -0x398(%rbp), %rdi
callq 0x219f0
movsd %xmm1, -0x5f0(%rbp)
movsd %xmm0, -0x5e8(%rbp)
jmp 0x1f083
movsd -0x5f0(%rbp), %xmm0
movsd -0x5e8(%rbp), %xmm1
movsd %xmm1, -0x380(%rbp)
movsd %xmm0, -0x378(%rbp)
leaq -0x300(%rbp), %rdi
movl $0x2, %esi
callq 0x20fa0
movq %rax, -0x5f8(%rbp)
jmp 0x1f0bd
movq -0x5f8(%rbp), %rax
movups -0x380(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x138(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x21950
movq %rdx, -0x608(%rbp)
movq %rax, -0x600(%rbp)
jmp 0x1f0ee
movq -0x608(%rbp), %rax
movq -0x600(%rbp), %rcx
movq %rcx, -0x3e0(%rbp)
movq %rax, -0x3d8(%rbp)
leaq -0x3d0(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
leaq -0x248(%rbp), %rdx
callq 0x219a0
jmp 0x1f126
leaq -0x3d0(%rbp), %rdi
callq 0x219f0
movsd %xmm1, -0x618(%rbp)
movsd %xmm0, -0x610(%rbp)
jmp 0x1f144
movsd -0x618(%rbp), %xmm0
movsd -0x610(%rbp), %xmm1
movsd %xmm1, -0x3b8(%rbp)
movsd %xmm0, -0x3b0(%rbp)
leaq -0x300(%rbp), %rdi
movl $0x3, %esi
callq 0x20fa0
movq %rax, -0x620(%rbp)
jmp 0x1f17e
movq -0x550(%rbp), %rsi
movq -0x620(%rbp), %rax
movups -0x3b8(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x448(%rbp), %rdi
callq 0x21030
jmp 0x1f1a4
movq -0x550(%rbp), %rdx
leaq -0x438(%rbp), %rdi
leaq -0x448(%rbp), %rsi
callq 0x21080
jmp 0x1f1c0
leaq -0x420(%rbp), %rdi
leaq -0x438(%rbp), %rsi
callq 0x210d0
jmp 0x1f1d5
movq -0x558(%rbp), %rsi
leaq -0x4b8(%rbp), %rdi
callq 0x21030
jmp 0x1f1ea
movq -0x558(%rbp), %rdx
leaq -0x4a8(%rbp), %rdi
leaq -0x4b8(%rbp), %rsi
callq 0x21080
jmp 0x1f206
leaq -0x490(%rbp), %rdi
leaq -0x4a8(%rbp), %rsi
callq 0x210d0
jmp 0x1f21b
leaq -0x420(%rbp), %rdi
leaq -0x490(%rbp), %rsi
callq 0x21110
movq %rdx, -0x630(%rbp)
movq %rax, -0x628(%rbp)
jmp 0x1f23e
movq -0x630(%rbp), %rax
movq -0x628(%rbp), %rcx
movq %rcx, -0x4e0(%rbp)
movq %rax, -0x4d8(%rbp)
leaq -0x4d0(%rbp), %rdi
leaq -0x4e0(%rbp), %rsi
callq 0x21160
jmp 0x1f26f
leaq -0x538(%rbp), %rdi
leaq -0x300(%rbp), %rsi
callq 0x211a0
jmp 0x1f284
leaq -0x4d0(%rbp), %rdi
callq 0x21240
movq %rax, -0x638(%rbp)
jmp 0x1f299
movq -0x638(%rbp), %rax
movq %rax, -0x540(%rbp)
leaq -0x528(%rbp), %rdi
leaq -0x538(%rbp), %rsi
leaq -0x540(%rbp), %rdx
callq 0x211f0
jmp 0x1f2c3
leaq -0x510(%rbp), %rdi
leaq -0x528(%rbp), %rsi
leaq -0x300(%rbp), %rdx
callq 0x212c0
jmp 0x1f2df
leaq -0x510(%rbp), %rdi
callq 0x21310
movsd %xmm1, -0x648(%rbp)
movsd %xmm0, -0x640(%rbp)
jmp 0x1f2fd
movsd -0x648(%rbp), %xmm0
movsd -0x640(%rbp), %xmm1
movsd %xmm1, -0x4f0(%rbp)
movsd %xmm0, -0x4e8(%rbp)
leaq -0x4f0(%rbp), %rdi
callq 0x20430
movsd %xmm0, -0x650(%rbp)
jmp 0x1f333
movsd -0x650(%rbp), %xmm0
callq 0x95e0
movsd %xmm0, -0x658(%rbp)
leaq -0x4d0(%rbp), %rdi
callq 0xfac0
leaq -0x248(%rbp), %rdi
callq 0x20c20
leaq -0x1c0(%rbp), %rdi
callq 0x20c20
leaq -0x138(%rbp), %rdi
callq 0x20040
leaq -0xb0(%rbp), %rdi
callq 0x20040
leaq -0x48(%rbp), %rdi
callq 0xfac0
movsd -0x658(%rbp), %xmm0
addq $0x660, %rsp            # imm = 0x660
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1f412
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1f406
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1f3fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1f3ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x4d0(%rbp), %rdi
callq 0xfac0
leaq -0x248(%rbp), %rdi
callq 0x20c20
leaq -0x1c0(%rbp), %rdi
callq 0x20c20
leaq -0x138(%rbp), %rdi
callq 0x20040
leaq -0xb0(%rbp), %rdi
callq 0x20040
leaq -0x48(%rbp), %rdi
callq 0xfac0
movq -0x60(%rbp), %rdi
callq 0x9dc0