// File: j-faria[P]kima/src/distributions/Empirical.cpp
// Function: DNest4::Empirical::cdf_inverse(double) const
double Empirical::cdf_inverse(double p) const
{
    if(p < 0.0 || p > 1.0)
        throw std::domain_error("Input to cdf_inverse must be in [0, 1].");
    
    double poi = -0.5*(1 - p) + p*(data.size()-0.5);

    size_t left = max(int64_t(floor(poi)), int64_t(0));
    size_t right = min(int64_t(ceil(poi)), int64_t(data.size() - 1));

    double datLeft = data.at(left);
    double datRight = data.at(right);

    double t = poi - left;
    double quantile = (1 - t)*datLeft + t*datRight;

    return quantile;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x10(%rbp), %xmm0
ja 0x7529
movsd -0x10(%rbp), %xmm0
movsd 0xafb0d(%rip), %xmm1    # 0xb7030
ucomisd %xmm1, %xmm0
jbe 0x7585
movl $0x10, %edi
callq 0x6250
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x88(%rbp)
leaq 0xafaf9(%rip), %rsi     # 0xb7040
callq 0x6310
jmp 0x754e
movq -0x88(%rbp), %rdi
movq 0x1129c4(%rip), %rsi    # 0x119f20
movq 0x1129f5(%rip), %rdx    # 0x119f58
callq 0x67e0
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x63b0
jmp 0x7722
movq -0x80(%rbp), %rdi
movsd -0x10(%rbp), %xmm1
movsd %xmm1, -0xc8(%rbp)
movsd 0xafa92(%rip), %xmm0    # 0xb7030
subsd %xmm1, %xmm0
movsd %xmm0, -0xc0(%rbp)
addq $0x8, %rdi
movq %rdi, -0xb8(%rbp)
callq 0x7c90
movsd -0xc8(%rbp), %xmm1
movsd -0xc0(%rbp), %xmm0
movq %rax, %xmm3
movaps 0xafa3a(%rip), %xmm2    # 0xb7010
movaps %xmm2, -0xb0(%rbp)
punpckldq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movapd 0xafa37(%rip), %xmm2    # 0xb7020
movaps %xmm2, -0xa0(%rbp)
subpd %xmm2, %xmm3
movaps %xmm3, %xmm2
unpckhpd %xmm3, %xmm3            # xmm3 = xmm3[1,1]
addsd %xmm2, %xmm3
movsd 0xafa31(%rip), %xmm2    # 0xb7038
addsd %xmm2, %xmm3
mulsd %xmm3, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x67b0
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
leaq -0x38(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x7cb0
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x60a0
movq -0xb8(%rbp), %rdi
cvttsd2si %xmm0, %rax
movq %rax, -0x50(%rbp)
callq 0x7c90
decq %rax
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x7cf0
movq -0xb8(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rsi
callq 0x7d30
movq -0xb8(%rbp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x48(%rbp), %rsi
callq 0x7d30
movaps -0xb0(%rbp), %xmm3
movaps -0xa0(%rbp), %xmm2
movsd (%rax), %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x28(%rbp), %xmm0
movq -0x30(%rbp), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
movsd 0xaf93d(%rip), %xmm0    # 0xb7030
subsd -0x70(%rbp), %xmm0
movsd -0x60(%rbp), %xmm2
movsd -0x70(%rbp), %xmm1
mulsd -0x68(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
addq $0xd0, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x6830
nopl (%rax,%rax)