// File: /workspace/github_cpp_makefile_star2_O1/j-faria[P]kima/src/RVmodel.cpp
// Function: RVmodel::log_likelihood() const
double RVmodel::log_likelihood() const
{
    auto data = Data::get_instance();
    int N = data.N();
    auto y = data.get_y();
    auto sig = data.get_sig();
    auto obsi = data.get_obsi();

    double logL = 0.;

    #if TIMING
    auto begin = std::chrono::high_resolution_clock::now();  // start timing
    #endif

    if(GP)
    {
        /** The following code calculates the log likelihood in the case of a GP model */
        // residual vector (observed y minus model y)
        VectorXd residual(y.size());
        for(size_t i=0; i<y.size(); i++)
            residual(i) = y[i] - mu[i];

        switch (kernel)
        {
            case standard:
            {
                // perform the cholesky decomposition of C
                Eigen::LLT<Eigen::MatrixXd> cholesky = C.llt();
                // get the lower triangular matrix L
                MatrixXd L = cholesky.matrixL();

                double logDeterminant = 0.;
                for(size_t i=0; i<y.size(); i++)
                    logDeterminant += 2.*log(L(i,i));

                VectorXd solution = cholesky.solve(residual);

                // y*solution
                double exponent = 0.;
                for(size_t i=0; i<y.size(); i++)
                    exponent += residual(i)*solution(i);

                logL = -0.5*y.size()*log(2*M_PI)
                        - 0.5*logDeterminant - 0.5*exponent;

                break;
            }

            case celerite:
            {
                logL = -0.5 * (solver.dot_solve(residual) +
                    solver.log_determinant() +
                    y.size()*log(2*M_PI)); 
    
                break;
            }
        
            default:
                break;
        }

    }
    else
    {
        if (studentt){
            // The following code calculates the log likelihood 
            // in the case of a t-Student model
            double var, jit;
            for(size_t i=0; i<N; i++)
            {
                if(multi_instrument)
                {
                    jit = jitters[obsi[i]-1];
                    var = sig[i]*sig[i] + jit*jit;
                }
                else
                    var = sig[i]*sig[i] + extra_sigma*extra_sigma;

                logL += std::lgamma(0.5*(nu + 1.)) - std::lgamma(0.5*nu)
                        - 0.5*log(M_PI*nu) - 0.5*log(var)
                        - 0.5*(nu + 1.)*log(1. + pow(y[i] - mu[i], 2)/var/nu);
            }

        }

        else{
            // The following code calculates the log likelihood
            // in the case of a Gaussian likelihood
            double var, jit;
            for(size_t i=0; i<N; i++)
            {
                if(multi_instrument)
                {
                    jit = jitters[obsi[i]-1];
                    var = sig[i]*sig[i] + jit*jit;
                }
                else
                    var = sig[i]*sig[i] + extra_sigma*extra_sigma;

                logL += - halflog2pi - 0.5*log(var)
                        - 0.5*(pow(y[i] - mu[i], 2)/var);
            }
        }

    }

    #if TIMING
    auto end = std::chrono::high_resolution_clock::now();
    cout << "Likelihood took " << std::chrono::duration_cast<std::chrono::nanoseconds>(end-begin).count()*1E-6 << " ms" << std::endl;
    #endif

    if(std::isnan(logL) || std::isinf(logL))
    {
        logL = std::numeric_limits<double>::infinity();
    }
    return logL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movq %rdi, %rbx
leaq 0x41ef1(%rip), %rsi     # 0x53400
leaq 0x160(%rsp), %r14
movq %r14, %rdi
callq 0x1560c
movq 0x8(%r14), %r15
subq (%r14), %r15
leaq 0x178(%rsp), %rsi
leaq 0x40(%rsp), %rdi
callq 0xc1e6
leaq 0x190(%rsp), %rsi
leaq 0x80(%rsp), %rdi
callq 0xc1e6
leaq 0x1a8(%rsp), %rsi
leaq 0x98(%rsp), %rdi
callq 0x15e96
leaq 0x33e17(%rip), %rax     # 0x45380
cmpb $0x1, (%rax)
jne 0x115f3
movq 0x40(%rsp), %r12
movq 0x48(%rsp), %r13
movq %r13, %r14
subq %r12, %r14
movq %r14, %r15
sarq $0x3, %r15
xorpd %xmm0, %xmm0
movapd %xmm0, 0x30(%rsp)
js 0x11d97
cmpq %r15, 0x38(%rsp)
je 0x1190f
movq 0x30(%rsp), %rdi
callq 0x64d0
cmpq %r12, %r13
je 0x11906
movq %r15, %rax
shrq $0x3d, %rax
jne 0x11db6
movq %r14, %rdi
callq 0x6520
cmpq $0x8, %r14
setne %cl
testb $0xf, %al
setne %dl
testb %dl, %cl
jne 0x11de4
testq %rax, %rax
je 0x11db6
movq %rax, 0x30(%rsp)
jmp 0x1190f
leaq 0x33d96(%rip), %rax     # 0x45390
shlq $0x1d, %r15
cmpb $0x0, (%rax)
je 0x117e6
movq %r15, %rax
shrq $0x20, %rax
pxor %xmm0, %xmm0
je 0x11ca5
sarq $0x20, %r15
leaq 0x33d65(%rip), %rax     # 0x45388
cmpq $0x1, %r15
adcq $0x0, %r15
movb (%rax), %bpl
xorl %r14d, %r14d
testb %bpl, %bpl
movdqa %xmm0, 0x10(%rsp)
je 0x11665
movq 0x98(%rsp), %rax
movslq (%rax,%r14), %rax
movq 0x140(%rbx), %rcx
movsd -0x8(%rcx,%rax,8), %xmm0
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm1
jmp 0x1167b
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm1
movsd 0x198(%rbx), %xmm0
mulsd %xmm0, %xmm0
mulsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x58(%rsp)
movsd 0x1a0(%rbx), %xmm0
movsd 0x2d993(%rip), %xmm1    # 0x3f030
addsd %xmm1, %xmm0
movsd 0x2daef(%rip), %xmm1    # 0x3f198
mulsd %xmm1, %xmm0
callq 0x6380
movsd %xmm0, 0x78(%rsp)
movsd 0x1a0(%rbx), %xmm0
mulsd 0x2dad0(%rip), %xmm0    # 0x3f198
callq 0x6380
movsd %xmm0, 0xb8(%rsp)
movsd 0x1a0(%rbx), %xmm0
mulsd 0x2dfd2(%rip), %xmm0    # 0x3f6b8
callq 0x63c0
movsd %xmm0, 0xb0(%rsp)
movsd 0x58(%rsp), %xmm0
callq 0x63c0
movsd 0x1a0(%rbx), %xmm1
movq 0x40(%rsp), %rax
movq 0x380(%rbx), %rcx
fldt (%rcx,%r14,4)
fsubrl (%rax,%r14,2)
fmul %st, %st(0)
movapd %xmm1, %xmm2
addsd 0x2d907(%rip), %xmm2    # 0x3f030
movsd 0x2d907(%rip), %xmm3    # 0x3f038
mulsd %xmm3, %xmm2
movsd %xmm2, 0xd0(%rsp)
movsd 0x78(%rsp), %xmm2
subsd 0xb8(%rsp), %xmm2
movsd 0xb0(%rsp), %xmm4
mulsd %xmm3, %xmm4
addsd %xmm2, %xmm4
mulsd %xmm3, %xmm0
addsd %xmm4, %xmm0
movsd %xmm0, 0xc8(%rsp)
movsd 0x58(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
fdivl 0xe8(%rsp)
movsd %xmm1, 0xd8(%rsp)
fdivl 0xd8(%rsp)
fld1
faddp %st, %st(1)
fstpt (%rsp)
callq 0x61e0
fmull 0xd0(%rsp)
faddl 0xc8(%rsp)
movaps 0x10(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
faddl 0xe0(%rsp)
fstpl 0xc0(%rsp)
movq 0xc0(%rsp), %xmm0
addq $0x4, %r14
decq %r15
jne 0x11631
jmp 0x11ca5
movq %r15, %rax
shrq $0x20, %rax
pxor %xmm0, %xmm0
je 0x11ca5
sarq $0x20, %r15
leaq 0x33b86(%rip), %rax     # 0x45388
cmpq $0x1, %r15
adcq $0x0, %r15
movb (%rax), %bpl
xorl %r14d, %r14d
testb %bpl, %bpl
movdqa %xmm0, 0x10(%rsp)
je 0x11844
movq 0x98(%rsp), %rax
movslq (%rax,%r14), %rax
movq 0x140(%rbx), %rcx
movsd -0x8(%rcx,%rax,8), %xmm1
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm0
jmp 0x1185a
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm0
movsd 0x198(%rbx), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x41c9c(%rip), %xmm1    # 0x53510
movsd %xmm1, 0x58(%rsp)
callq 0x63c0
movq 0x40(%rsp), %rax
movq 0x380(%rbx), %rcx
fldt (%rcx,%r14,4)
fsubrl (%rax,%r14,2)
fmul %st, %st(0)
mulsd 0x2d79b(%rip), %xmm0    # 0x3f038
subsd 0x58(%rsp), %xmm0
movsd %xmm0, 0xf8(%rsp)
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x108(%rsp)
fdivl 0x108(%rsp)
fmuls 0x2de98(%rip)           # 0x3f760
faddl 0xf8(%rsp)
movaps 0x10(%rsp), %xmm0
movsd %xmm0, 0x100(%rsp)
faddl 0x100(%rsp)
fstpl 0xf0(%rsp)
movq 0xf0(%rsp), %xmm0
addq $0x4, %r14
decq %r15
jne 0x11810
jmp 0x11ca5
movq $0x0, 0x30(%rsp)
movq %r15, 0x38(%rsp)
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
subq %rax, %rcx
je 0x1195a
sarq $0x3, %rcx
movq 0x380(%rbx), %rdx
movq 0x30(%rsp), %rsi
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edi, %edi
cmpq %rdi, %r15
je 0x11d59
fldt (%rdx)
fsubrl (%rax,%rdi,8)
fstpl (%rsi,%rdi,8)
incq %rdi
addq $0x10, %rdx
cmpq %rdi, %rcx
jne 0x1193d
movl 0x1a8(%rbx), %eax
testl %eax, %eax
je 0x119f5
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
cmpl $0x1, %eax
jne 0x11c95
addq $0x220, %rbx            # imm = 0x220
leaq 0x30(%rsp), %rsi
movq %rbx, %rdi
callq 0x15f16
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
callq 0x1830c
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
sarq $0x3, %rax
movq %rax, %xmm1
punpckldq 0x2d658(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x2d660(%rip), %xmm1    # 0x3f020
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
mulsd 0x2dd04(%rip), %xmm2    # 0x3f6d8
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
addsd %xmm1, %xmm2
mulsd 0x2d64e(%rip), %xmm2    # 0x3f038
movapd %xmm2, 0x10(%rsp)
jmp 0x11c95
addq $0x398, %rbx            # imm = 0x398
leaq 0x138(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x19ac0
cmpb $0x0, 0x158(%rsp)
je 0x11e03
leaq 0x60(%rsp), %rsi
movq %r14, (%rsi)
leaq 0x110(%rsp), %rdi
callq 0x1eb1e
movq 0x48(%rsp), %rax
cmpq 0x40(%rsp), %rax
je 0x11acd
xorpd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
xorl %ebx, %ebx
movq %rbx, %rax
negq %rax
jo 0x11d78
movq 0x118(%rsp), %rax
cmpq %rbx, %rax
jle 0x11d78
cmpq %rbx, 0x120(%rsp)
jle 0x11d78
imulq %rbx, %rax
shlq $0x3, %rax
addq 0x110(%rsp), %rax
movsd (%rax,%rbx,8), %xmm0
callq 0x63c0
addsd %xmm0, %xmm0
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
incq %rbx
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
sarq $0x3, %rax
cmpq %rax, %rbx
jb 0x11a4e
movsd 0x10(%rsp), %xmm0
mulsd 0x2d56d(%rip), %xmm0    # 0x3f038
jmp 0x11ad5
movsd 0x2dc0b(%rip), %xmm0    # 0x3f6e0
movsd %xmm0, 0x10(%rsp)
leaq 0x138(%rsp), %rbx
leaq 0x30(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1ee98
movq %rbx, 0x128(%rsp)
movq %r14, 0x130(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x60(%rsp)
movq 0x148(%rsp), %rbx
testq %rbx, %rbx
js 0x11e22
cmpq %rbx, 0x68(%rsp)
je 0x11b7b
movq 0x60(%rsp), %rdi
callq 0x64d0
testq %rbx, %rbx
je 0x11b72
movq %rbx, %rax
shrq $0x3d, %rax
jne 0x11e41
leaq (,%rbx,8), %rdi
callq 0x6520
cmpq $0x1, %rbx
setne %cl
testb $0xf, %al
setne %dl
testb %dl, %cl
jne 0x11de4
testq %rax, %rax
je 0x11e41
movq %rax, 0x60(%rsp)
jmp 0x11b7b
movq $0x0, 0x60(%rsp)
leaq 0x60(%rsp), %rdi
movq %rbx, 0x8(%rdi)
leaq 0x128(%rsp), %rsi
leaq 0x2f(%rsp), %rdx
callq 0x1eeea
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %rdx
movq %rcx, %rax
subq %rdx, %rax
sarq $0x3, %rax
cmpq %rdx, %rcx
je 0x11c24
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rdx
movq 0x60(%rsp), %rsi
xorl %edi, %edi
testq %rdx, %rdx
movl $0x0, %r8d
cmovgq %rdx, %r8
cmpq $0x1, %rax
movq %rax, %r9
adcq $0x0, %r9
movq 0x68(%rsp), %r10
testq %r10, %r10
cmovleq %rdi, %r10
leaq -0x1(%r9), %r11
cmpq %r10, %r11
cmovaeq %r10, %r11
cmpq %r8, %r11
cmovbq %r11, %r8
xorpd %xmm2, %xmm2
cmpq %r11, %rdx
jle 0x11d59
cmpq %r8, %r10
je 0x11d59
movsd (%rcx,%rdi,8), %xmm0
mulsd (%rsi,%rdi,8), %xmm0
addsd %xmm0, %xmm2
incq %rdi
cmpq %rdi, %r9
jne 0x11bfa
jmp 0x11c28
xorpd %xmm2, %xmm2
movq %rax, %xmm0
punpckldq 0x2d3db(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x2d3e3(%rip), %xmm0    # 0x3f020
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x2d3e7(%rip), %xmm0    # 0x3f038
mulsd %xmm0, %xmm1
mulsd 0x2da7b(%rip), %xmm1    # 0x3f6d8
addsd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm2
addsd %xmm1, %xmm2
movapd %xmm2, 0x10(%rsp)
movq 0x60(%rsp), %rdi
callq 0x64d0
movq 0x110(%rsp), %rdi
callq 0x64d0
movq 0x138(%rsp), %rdi
callq 0x64d0
movq 0x30(%rsp), %rdi
callq 0x64d0
movdqa 0x10(%rsp), %xmm0
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
movdqa %xmm0, 0x10(%rsp)
je 0x11cce
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
movdqa 0x10(%rsp), %xmm0
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x11cf1
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
movdqa 0x10(%rsp), %xmm0
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x11d0e
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
movdqa 0x10(%rsp), %xmm0
movq %xmm0, %rax
btrq $0x3f, %rax
movabsq $0x7ff0000000000000, %rcx # imm = 0x7FF0000000000000
cmpq %rcx, %rax
jl 0x11d2f
movq 0x2d9b9(%rip), %xmm0    # 0x3f6e8
movdqa %xmm0, 0x10(%rsp)
leaq 0x160(%rsp), %rdi
callq 0xb832
movaps 0x10(%rsp), %xmm0
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2e59f(%rip), %rdi     # 0x402ff
leaq 0x34494(%rip), %rsi     # 0x461fb
leaq 0x2e5ae(%rip), %rcx     # 0x4031c
movl $0x1ab, %edx            # imm = 0x1AB
callq 0x62b0
leaq 0x2e03d(%rip), %rdi     # 0x3fdbc
leaq 0x34475(%rip), %rsi     # 0x461fb
leaq 0x2e064(%rip), %rcx     # 0x3fdf1
movl $0x16f, %edx            # imm = 0x16F
callq 0x62b0
leaq 0x2e0e3(%rip), %rdi     # 0x3fe81
leaq 0x335f9(%rip), %rsi     # 0x4539e
leaq 0x2e15f(%rip), %rcx     # 0x3ff0b
movl $0x138, %edx            # imm = 0x138
callq 0x62b0
movl $0x8, %edi
callq 0x61d0
movq 0x411a1(%rip), %rcx     # 0x52f68
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0x411cb(%rip), %rsi     # 0x52fa0
movq 0x41174(%rip), %rdx     # 0x52f50
movq %rax, %rdi
callq 0x66c0
leaq 0x2e192(%rip), %rdi     # 0x3ff7d
leaq 0x335d9(%rip), %rsi     # 0x453cb
leaq 0x2e23f(%rip), %rcx     # 0x40038
movl $0xb8, %edx
callq 0x62b0
leaq 0x30a7b(%rip), %rdi     # 0x42885
leaq 0x2ea57(%rip), %rsi     # 0x40868
leaq 0x30a9a(%rip), %rcx     # 0x428b2
movl $0x89, %edx
callq 0x62b0
leaq 0x2e57a(%rip), %rdi     # 0x403a3
leaq 0x3356e(%rip), %rsi     # 0x4539e
leaq 0x2e85b(%rip), %rcx     # 0x40692
movl $0x11d, %edx            # imm = 0x11D
callq 0x62b0
movl $0x8, %edi
callq 0x61d0
movq 0x41116(%rip), %rcx     # 0x52f68
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0x41140(%rip), %rsi     # 0x52fa0
movq 0x410e9(%rip), %rdx     # 0x52f50
movq %rax, %rdi
callq 0x66c0
movq %rax, %rbx
jmp 0x11e88
movq %rax, %rbx
jmp 0x11e95
jmp 0x11ea6
movq %rax, %rbx
movq 0x60(%rsp), %rdi
callq 0x64d0
movq 0x110(%rsp), %rdi
callq 0x64d0
movq 0x138(%rsp), %rdi
callq 0x64d0
jmp 0x11ea9
jmp 0x11ea6
movq %rax, %rbx
movq 0x30(%rsp), %rdi
callq 0x64d0
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x11ed5
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11ed5
movq %rax, %rbx
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x11ef7
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11ef7
movq %rax, %rbx
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x11f13
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11f13
movq %rax, %rbx
leaq 0x160(%rsp), %rdi
callq 0xb832
movq %rbx, %rdi
callq 0x6710