// File: /workspace/github_cpp_makefile_star2_O3/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 0x3ee9d(%rip), %rsi     # 0x50400
leaq 0x160(%rsp), %r14
movq %r14, %rdi
callq 0x15552
movq 0x8(%r14), %r15
subq (%r14), %r15
leaq 0x178(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0xc290
leaq 0x190(%rsp), %rsi
leaq 0x80(%rsp), %rdi
callq 0xc290
leaq 0x1a8(%rsp), %rsi
leaq 0x98(%rsp), %rdi
callq 0x15de2
leaq 0x3131f(%rip), %rax     # 0x428dc
cmpb $0x1, (%rax)
jne 0x11621
movq 0x38(%rsp), %r15
movq 0x40(%rsp), %r13
movq %r13, %r14
subq %r15, %r14
movq %r14, %r12
sarq $0x3, %r12
xorpd %xmm0, %xmm0
movapd %xmm0, 0x50(%rsp)
js 0x11d50
cmpq %r15, %r13
je 0x11934
movq %r14, %rdi
callq 0x6520
cmpq $0x8, %r14
setne %cl
testb $0xf, %al
setne %dl
testb %dl, %cl
jne 0x11d6f
testq %rax, %rax
je 0x11d8e
movq %rax, 0x50(%rsp)
jmp 0x11936
leaq 0x312c4(%rip), %rax     # 0x428ec
shlq $0x1d, %r15
cmpb $0x0, (%rax)
je 0x11814
movq %r15, %rax
shrq $0x20, %rax
pxor %xmm0, %xmm0
je 0x11c5e
sarq $0x20, %r15
leaq 0x31293(%rip), %rax     # 0x428e4
cmpq $0x1, %r15
adcq $0x0, %r15
movb (%rax), %bpl
xorl %r14d, %r14d
testb %bpl, %bpl
movdqa %xmm0, 0x10(%rsp)
je 0x11693
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 0x116a9
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm1
movsd 0x198(%rbx), %xmm0
mulsd %xmm0, %xmm0
mulsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x30(%rsp)
movsd 0x1a0(%rbx), %xmm0
movsd 0x2b965(%rip), %xmm1    # 0x3d030
addsd %xmm1, %xmm0
movsd 0x2bac1(%rip), %xmm1    # 0x3d198
mulsd %xmm1, %xmm0
callq 0x6380
movsd %xmm0, 0x68(%rsp)
movsd 0x1a0(%rbx), %xmm0
mulsd 0x2baa2(%rip), %xmm0    # 0x3d198
callq 0x6380
movsd %xmm0, 0xb8(%rsp)
movsd 0x1a0(%rbx), %xmm0
mulsd 0x2bfcc(%rip), %xmm0    # 0x3d6e0
callq 0x63c0
movsd %xmm0, 0xb0(%rsp)
movsd 0x30(%rsp), %xmm0
callq 0x63c0
movsd 0x1a0(%rbx), %xmm1
movq 0x38(%rsp), %rax
movq 0x380(%rbx), %rcx
fldt (%rcx,%r14,4)
fsubrl (%rax,%r14,2)
fmul %st, %st(0)
movapd %xmm1, %xmm2
addsd 0x2b8d9(%rip), %xmm2    # 0x3d030
movsd 0x2b8d9(%rip), %xmm3    # 0x3d038
mulsd %xmm3, %xmm2
movsd %xmm2, 0xd0(%rsp)
movsd 0x68(%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 0x30(%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 0x1165f
jmp 0x11c5e
movq %r15, %rax
shrq $0x20, %rax
pxor %xmm0, %xmm0
je 0x11c5e
sarq $0x20, %r15
leaq 0x310b4(%rip), %rax     # 0x428e4
cmpq $0x1, %r15
adcq $0x0, %r15
movb (%rax), %bpl
xorl %r14d, %r14d
testb %bpl, %bpl
movdqa %xmm0, 0x10(%rsp)
je 0x11872
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 0x11888
movq 0x80(%rsp), %rax
movsd (%rax,%r14,2), %xmm0
movsd 0x198(%rbx), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x3ec6e(%rip), %xmm1    # 0x50510
movsd %xmm1, 0x30(%rsp)
callq 0x63c0
movq 0x38(%rsp), %rax
movq 0x380(%rbx), %rcx
fldt (%rcx,%r14,4)
fsubrl (%rax,%r14,2)
fmul %st, %st(0)
mulsd 0x2b76d(%rip), %xmm0    # 0x3d038
subsd 0x30(%rsp), %xmm0
movsd %xmm0, 0xf8(%rsp)
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x108(%rsp)
fdivl 0x108(%rsp)
fmuls 0x2beaa(%rip)           # 0x3d7a0
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 0x1183e
jmp 0x11c5e
xorl %eax, %eax
movq %r12, 0x58(%rsp)
cmpq %r15, %r13
je 0x11972
movq 0x380(%rbx), %rcx
cmpq $0x1, %r12
movq %r12, %rdx
adcq $0x0, %rdx
xorl %esi, %esi
cmpq %rsi, %r12
je 0x11d12
fldt (%rcx)
fsubrl (%r15,%rsi,8)
fstpl (%rax,%rsi,8)
incq %rsi
addq $0x10, %rcx
cmpq %rsi, %rdx
jne 0x11954
movl 0x1a8(%rbx), %eax
testl %eax, %eax
je 0x11a0d
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
cmpl $0x1, %eax
jne 0x11c4e
addq $0x220, %rbx            # imm = 0x220
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0x15e62
movsd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
callq 0x17c44
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
sarq $0x3, %rax
movq %rax, %xmm1
punpckldq 0x2b640(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x2b648(%rip), %xmm1    # 0x3d020
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
mulsd 0x2bd14(%rip), %xmm2    # 0x3d700
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
addsd %xmm1, %xmm2
mulsd 0x2b636(%rip), %xmm2    # 0x3d038
movapd %xmm2, 0x10(%rsp)
jmp 0x11c4e
addq $0x398, %rbx            # imm = 0x398
leaq 0x138(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x193d6
cmpb $0x0, 0x158(%rsp)
je 0x11dea
leaq 0x70(%rsp), %rsi
movq %r14, (%rsi)
leaq 0x110(%rsp), %rdi
callq 0x1e2b2
movq 0x40(%rsp), %rax
cmpq 0x38(%rsp), %rax
je 0x11ad5
xorpd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
xorl %ebx, %ebx
movq 0x118(%rsp), %rax
cmpq %rbx, %rax
jle 0x11d31
cmpq %rbx, 0x120(%rsp)
jle 0x11d31
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 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
sarq $0x3, %rax
cmpq %rax, %rbx
jb 0x11a62
movsd 0x10(%rsp), %xmm0
mulsd 0x2b565(%rip), %xmm0    # 0x3d038
jmp 0x11add
movsd 0x2bc2b(%rip), %xmm0    # 0x3d708
movsd %xmm0, 0x10(%rsp)
leaq 0x138(%rsp), %rbx
leaq 0x50(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1e58a
movq %rbx, 0x128(%rsp)
movq %r14, 0x130(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x70(%rsp)
movq 0x148(%rsp), %rbx
testq %rbx, %rbx
js 0x11e09
je 0x11b64
movq %rbx, %rax
shrq $0x3d, %rax
jne 0x11dbc
leaq (,%rbx,8), %rdi
callq 0x6520
cmpq $0x1, %rbx
setne %cl
testb $0xf, %al
setne %dl
testb %dl, %cl
jne 0x11d6f
testq %rax, %rax
je 0x11dbc
movq %rax, 0x70(%rsp)
leaq 0x70(%rsp), %rdi
movq %rbx, 0x8(%rdi)
leaq 0x128(%rsp), %rsi
leaq 0x2f(%rsp), %rdx
callq 0x1e5dc
movq 0x40(%rsp), %rcx
movq 0x38(%rsp), %rdx
movq %rcx, %rax
subq %rdx, %rax
sarq $0x3, %rax
movq 0x70(%rsp), %rdi
cmpq %rdx, %rcx
je 0x11bfb
cmpq $0x1, %rax
movq %rax, %rcx
adcq $0x0, %rcx
movq 0x78(%rsp), %r8
leaq -0x1(%rcx), %rdx
xorl %esi, %esi
testq %r8, %r8
cmovgq %r8, %rsi
cmpq %rsi, %rdx
movq %rsi, %r8
cmovbq %rdx, %r8
cmpq %r8, 0x58(%rsp)
jle 0x11d12
cmpq %rdx, %rsi
jbe 0x11d12
movq 0x50(%rsp), %rdx
xorpd %xmm2, %xmm2
xorl %esi, %esi
movsd (%rdx,%rsi,8), %xmm0
mulsd (%rdi,%rsi,8), %xmm0
addsd %xmm0, %xmm2
incq %rsi
cmpq %rsi, %rcx
jne 0x11be3
jmp 0x11bff
xorpd %xmm2, %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movsd 0x2b429(%rip), %xmm1    # 0x3d038
mulsd %xmm1, %xmm0
mulsd 0x2bae5(%rip), %xmm0    # 0x3d700
addsd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm2
addsd %xmm0, %xmm2
movapd %xmm2, 0x10(%rsp)
callq 0x64d0
movq 0x110(%rsp), %rdi
callq 0x64d0
movq 0x138(%rsp), %rdi
callq 0x64d0
movq 0x50(%rsp), %rdi
callq 0x64d0
movdqa 0x10(%rsp), %xmm0
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
movdqa %xmm0, 0x10(%rsp)
je 0x11c87
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
movdqa 0x10(%rsp), %xmm0
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x11caa
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
movdqa 0x10(%rsp), %xmm0
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x11cc7
movq 0x48(%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 0x11ce8
movq 0x2ba28(%rip), %xmm0    # 0x3d710
movdqa %xmm0, 0x10(%rsp)
leaq 0x160(%rsp), %rdi
callq 0xb8d2
movaps 0x10(%rsp), %xmm0
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2c622(%rip), %rdi     # 0x3e33b
leaq 0x31a37(%rip), %rsi     # 0x43757
leaq 0x2c631(%rip), %rcx     # 0x3e358
movl $0x1ab, %edx            # imm = 0x1AB
callq 0x62b0
leaq 0x2c0c0(%rip), %rdi     # 0x3ddf8
leaq 0x31a18(%rip), %rsi     # 0x43757
leaq 0x2c0e7(%rip), %rcx     # 0x3de2d
movl $0x16f, %edx            # imm = 0x16F
callq 0x62b0
leaq 0x2c166(%rip), %rdi     # 0x3debd
leaq 0x30b9c(%rip), %rsi     # 0x428fa
leaq 0x2c1e2(%rip), %rcx     # 0x3df47
movl $0x138, %edx            # imm = 0x138
callq 0x62b0
leaq 0x2c243(%rip), %rdi     # 0x3dfb9
leaq 0x30baa(%rip), %rsi     # 0x42927
leaq 0x2c2f0(%rip), %rcx     # 0x3e074
movl $0xb8, %edx
callq 0x62b0
movl $0x8, %edi
callq 0x61d0
movq 0x3e1c9(%rip), %rcx     # 0x4ff68
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0x3e1f3(%rip), %rsi     # 0x4ffa0
movq 0x3e19c(%rip), %rdx     # 0x4ff50
movq %rax, %rdi
callq 0x66c0
movl $0x8, %edi
callq 0x61d0
movq 0x3e19b(%rip), %rcx     # 0x4ff68
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0x3e1c5(%rip), %rsi     # 0x4ffa0
movq 0x3e16e(%rip), %rdx     # 0x4ff50
movq %rax, %rdi
callq 0x66c0
leaq 0x2ead0(%rip), %rdi     # 0x408c1
leaq 0x2caac(%rip), %rsi     # 0x3e8a4
leaq 0x2eaef(%rip), %rcx     # 0x408ee
movl $0x89, %edx
callq 0x62b0
leaq 0x2c5cf(%rip), %rdi     # 0x3e3df
leaq 0x30ae3(%rip), %rsi     # 0x428fa
leaq 0x2c8b0(%rip), %rcx     # 0x3e6ce
movl $0x11d, %edx            # imm = 0x11D
callq 0x62b0
movq %rax, %rbx
jmp 0x11e48
movq %rax, %rbx
jmp 0x11e55
jmp 0x11e36
jmp 0x11e36
movq %rax, %rbx
jmp 0x11e62
movq %rax, %rbx
movq 0x70(%rsp), %rdi
callq 0x64d0
movq 0x110(%rsp), %rdi
callq 0x64d0
movq 0x138(%rsp), %rdi
callq 0x64d0
movq 0x50(%rsp), %rdi
callq 0x64d0
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x11e8e
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11e8e
movq %rax, %rbx
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x11eb0
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11eb0
movq %rax, %rbx
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x11ecc
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0x6460
jmp 0x11ecc
movq %rax, %rbx
leaq 0x160(%rsp), %rdi
callq 0xb8d2
movq %rbx, %rdi
callq 0x6710
nop