// File: /workspace/github_cpp_makefile_star2_O2/Altius[P]hotspot2/src/hotspot2_part1.cpp
// Function: BackgroundRegionManager::getPvalue(unsigned int const&)
long double BackgroundRegionManager::getPvalue(const unsigned int& k)
{
  if (k < m_distn.size()) // Yes, m_distn.size(), not m_sampledDataDistnSize
    return m_distn[k].pval;

  // k is greater than all count values in the distribution, so we need to add bin(s) for it.
  // This can only happen if the user has specified a sampling interval
  // and k happens to have not been sampled.

  if (NULL == m_pmf || m_pmfParams.empty())
    {
      cerr << "Coding error:  BRM::getPvalue(" << k << ") was called when m_pmf == NULL and/or m_pmfParams.empty() == true." << endl;
      exit(1);
    }

  StatsForCount sc;
  sc.numOccs = 0;
  sc.pmf = sc.pval = -1.;
  sc.MAxN = -1;

  const int prev_max_k(static_cast<int>(m_distn.size()) - 1), MAlenOver2(m_MAlength / 2); // Yes, m_distn.size(), not m_sampledDataDistnSize.
  int kk = prev_max_k;
  long double curPMF(m_distn[kk].pmf);
  while (k >= m_distn.size()) // Yes, k, not kk.  We're growing the vector until k fits into its highest bin.
    {
      curPMF = m_pmf(++kk, curPMF, m_pmfParams);
      sc.pmf = curPMF;
      m_distn.push_back(sc);
      if (kk >= m_MAlength)
        m_distn[kk - MAlenOver2].MAxN = m_distn[kk - MAlenOver2 - 1].MAxN - m_distn[kk - m_MAlength].numOccs + m_distn[kk].numOccs;
      else
        {
          if (m_MAlength - 1 == kk)
            {
              int sum(0);
              for (int j = 0; j <= kk; j++)
                sum += m_distn[j].numOccs;
              m_distn[MAlenOver2].MAxN = sum;
            }
        }
    }
  // Compute the P-value.  See comments in method computeStats() for further info.
  // kk == k at this point.
  long double sum(1.), prevTerm(1.), curTerm;
  const long double SMALL_VALUE(5.0e-7); // restrict the correctness of the final P-value to ~5 significant digits
  while ((curTerm = m_pmf(++kk, prevTerm, m_pmfParams)) > SMALL_VALUE)
    {
      sum += curTerm;
      prevTerm = curTerm;
    }
  m_distn[k].pval = m_distn[k].pmf * sum;
  //  if (m_distn[k].pval < numeric_limits<double>::min())
  //    m_distn[k].pval = numeric_limits<double>::min();
  // Fill in P-values for any bins that were added between prev_max_k and k.
  kk = k;
  while (kk > prev_max_k + 1)
    {
      m_distn[kk - 1].pval = m_distn[kk - 1].pmf + m_distn[kk].pval;
      //      if (m_distn[k].pval < numeric_limits<double>::min())
      //	m_distn[k].pval = numeric_limits<double>::min();
      kk--;
    }

  return m_distn[k].pval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl (%rsi), %ecx
movq 0x50(%rdi), %rsi
movq 0x58(%rdi), %rdi
movq %rdi, %rdx
subq %rsi, %rdx
movq %rdx, %rax
sarq $0x6, %rax
cmpq %rcx, %rax
jbe 0x3860
shlq $0x6, %rcx
fldt 0x20(%rsi,%rcx)
jmp 0x3a49
movq %rdx, 0x18(%rsp)
cmpq $0x0, 0x168(%r14)
je 0x3a5b
movq 0x170(%r14), %rdx
cmpq 0x178(%r14), %rdx
je 0x3a5b
leaq 0x50(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0x50(%r14), %r15
fld1
fchs
fld %st(0)
fstpt 0x70(%rsp)
fstpt 0x60(%rsp)
orl $-0x1, 0x30(%rdx)
leaq 0x170(%r14), %r12
movslq %eax, %r8
movq %r8, %r9
shlq $0x6, %r9
decl %r8d
movl 0x3c(%r14), %eax
pushq $0x2
popq %r10
cltd
idivl %r10d
movl %eax, %ebp
leaq 0x4(%rsp), %rax
movl %r8d, (%rax)
fldt -0x30(%r9,%rsi)
fstpt 0x30(%rsp)
movl %ebp, %r13d
notl %r13d
movslq %ebp, %rax
shlq $0x6, %rax
movq %rax, 0x8(%rsp)
subq %rsi, %rdi
movl %ecx, %eax
sarq $0x6, %rdi
cmpq %rax, %rdi
ja 0x39aa
movq 0x168(%r14), %rax
incl 0x4(%rsp)
leaq 0x4(%rsp), %rdi
leaq 0x30(%rsp), %rsi
movq %r12, %rdx
callq *%rax
fld %st(0)
fstpt 0x30(%rsp)
fstpt 0x60(%rsp)
movq %r15, %rdi
leaq 0x50(%rsp), %rsi
callq 0x5dc4
movslq 0x4(%rsp), %rax
movl 0x3c(%r14), %ecx
cmpl %ecx, %eax
jge 0x395a
decl %ecx
cmpl %eax, %ecx
jne 0x399b
movq (%r15), %rcx
xorl %edx, %edx
movq %rcx, %rsi
xorl %edi, %edi
cmpq %rax, %rdx
jg 0x3992
addl (%rsi), %edi
incq %rdx
addq $0x40, %rsi
jmp 0x394a
leal (%rax,%r13), %edx
movslq %edx, %rdx
movq (%r15), %rsi
shlq $0x6, %rdx
movl 0x30(%rsi,%rdx), %edx
movl %eax, %edi
subl %ecx, %edi
movslq %edi, %rcx
shlq $0x6, %rcx
subl (%rsi,%rcx), %edx
movq %rax, %rcx
shlq $0x6, %rcx
addl (%rsi,%rcx), %edx
subl %ebp, %eax
cltq
shlq $0x6, %rax
movl %edx, 0x30(%rsi,%rax)
jmp 0x399b
movq 0x8(%rsp), %rax
movl %edi, 0x30(%rcx,%rax)
movl (%rbx), %ecx
movq 0x50(%r14), %rsi
movq 0x58(%r14), %rdi
jmp 0x38ea
leaq 0x4(%rsp), %r13
leaq 0x40(%rsp), %rbp
fldl 0x466e(%rip)            # 0x8028
fstpt 0x24(%rsp)
fld1
fld %st(0)
fstpt 0x8(%rsp)
fstpt 0x40(%rsp)
movq 0x168(%r14), %rax
incl 0x4(%rsp)
movq %r13, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq *%rax
fldt 0x24(%rsp)
fxch %st(1)
fucomi %st(1), %st
fstp %st(1)
jbe 0x39f4
fldt 0x8(%rsp)
fadd %st(1), %st
jmp 0x39c2
fstp %st(0)
movslq (%rbx), %rax
movl %eax, %edx
movq (%r15), %rsi
shlq $0x6, %rdx
leaq (%rsi,%rdx), %rcx
fldt 0x10(%rsi,%rdx)
fldt 0x8(%rsp)
fmulp %st, %st(1)
fstpt 0x20(%rsi,%rdx)
movq 0x18(%rsp), %rdx
shrq $0x6, %rdx
movslq %edx, %rdx
movq %rax, %rdi
shlq $0x6, %rdi
addq %rdi, %rsi
addq $-0x30, %rsi
cmpq %rdx, %rax
jle 0x3a46
decq %rax
fldt (%rsi)
fldt 0x50(%rsi)
faddp %st, %st(1)
fstpt 0x10(%rsi)
addq $-0x40, %rsi
jmp 0x3a2e
fldt 0x20(%rcx)
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x858e(%rip), %rdi      # 0xbff0
leaq 0x4b85(%rip), %rsi      # 0x85ee
callq 0x21e0
movl (%rbx), %esi
movq %rax, %rdi
callq 0x2290
leaq 0x4b8e(%rip), %rsi      # 0x860d
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x20e0
pushq $0x1
popq %rdi
callq 0x2280
nop