// File: /workspace/github_cpp_makefile_star2_O3/Altius[P]hotspot2/src/findVarWidthPeaks.cpp
// Function: getPeakBoundaries(Region const&, int&, int&, long const&)
bool getPeakBoundaries(const Region& r, int& idxL, int& idxR, const long& minWidth)
{
  float maxY(r.posns[idxL].y), halfmaxY(r.posns[idxL].y/2.0), minY(maxY);
  const float secondaryCutoff(999999. * maxY); // ensures we always return the local min when we fail to achieve half-max
  const int maxIdx = static_cast<int>(r.posns.size()) - 1; // in English: "maximum index," not "idx of max"
  int idxOfLocalMin(idxL);

  if (idxL > 0)
    idxL--; // begin our search at the first site to the left of the local maximum
  while (idxL > 0 && (r.posns[idxL].y - halfmaxY) > 0.0001) // the L boundary of the Region has index = 0
    {
      if (r.posns[idxL].y < minY || r.posns[idxL].y - minY < 0.0001) // i.e., "if y <= minY"
	{
	  minY = r.posns[idxL].y;
	  idxOfLocalMin = idxL;
	}
      if (r.posns[idxL].y - maxY > -0.0001) // i.e., "if y >= maxY"
	{
	  // While searching for the half-max point to the left of the local max,
	  // we climbed above the local max, so this is a subset of another peak...
	  // but we want to give it a chance to get called as a peak, so we backtrack to the local min.
	  idxL = idxOfLocalMin;
	  if (secondaryCutoff - r.posns[idxL].y > 0.0001)
	    break;
	  else
	    return false; // we'll actually never hit this line unless we change the algorithm
	}
      else
	idxL--;
    }
  if (halfmaxY - r.posns[idxL].y > -0.0001) // i.e., "if halfmaxY >= y"
    idxL++;
  else
    {
      if (0 == idxL && r.posns[idxL].y > minY)
	idxL = idxOfLocalMin;
    }

  idxOfLocalMin = idxR;
  minY = maxY;
  if (idxR < maxIdx)
    idxR++; // begin our search at the first site to the right of the local maximum
  while (idxR < maxIdx && (r.posns[idxR].y - halfmaxY) > 0.0001) // the R boundary of the Region has index = maxIdx
    {
      if (r.posns[idxR].y < minY || r.posns[idxR].y - minY < 0.0001) // i.e., "if y <= minY"
	{
	  minY = r.posns[idxR].y;
	  idxOfLocalMin = idxR;
	}
      if (r.posns[idxR].y - maxY > - 0.0001) // i.e., "if y >= maxY"
	{
	  // While searching for the half-max point to the left of the local max,
	  // we climbed above the local max, so this is a subset of another peak...
	  // but we want to give it a chance to get called as a peak, so we backtrack to the local min.
	  idxR = idxOfLocalMin;
	  if (secondaryCutoff - r.posns[idxR].y > 0.0001)
	    break;
	  else
	    return false; // we'll actually never hit this line unless we change the algorithm
	}
      else
	idxR++;
    }
  if (halfmaxY - r.posns[idxR].y > -0.0001) // i.e., "if halfmax >= y"
    idxR--;
  else
    {
      if (maxIdx == idxR && r.posns[idxR].y > minY)
	idxR = idxOfLocalMin;
    }

  // Require the peak to contain the posSummit received for this region.
  if (r.posSummit < r.posns[idxL].x || r.posSummit > r.posns[idxR].x)
    return false;
  if (idxR - idxL + 1 >= minWidth) // 0-based sites (100,120] are the 20 sites from 101-120; could have, e.g., idxL = 0 and idxR = 19 in this case
    return true;
  return false;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movslq (%rsi), %r9
movq %r9, %r10
shlq $0x4, %r10
movq 0x48(%rdi), %rax
movq 0x50(%rdi), %r8
movss 0x8(%rax,%r10), %xmm1
movss 0x3af9(%rip), %xmm0     # 0x6038
mulss %xmm1, %xmm0
movss 0x3af1(%rip), %xmm2     # 0x603c
mulss %xmm1, %xmm2
movl %r9d, %r11d
testq %r9, %r9
jle 0x2614
decl %r11d
movl %r11d, (%rsi)
je 0x260b
movl %r11d, %r10d
movq %r10, %rbx
shlq $0x4, %rbx
movss 0x8(%rax,%rbx), %xmm4
movaps %xmm4, %xmm3
subss %xmm0, %xmm3
cvtss2sd %xmm3, %xmm3
ucomisd 0x3a96(%rip), %xmm3     # 0x6020
jbe 0x2614
addq %rax, %rbx
addq $-0x8, %rbx
leal -0x2(%r9), %ebp
movsd 0x3a85(%rip), %xmm5     # 0x6028
movsd 0x3a75(%rip), %xmm6     # 0x6020
movaps %xmm1, %xmm3
movl %ebp, %r11d
ucomiss %xmm4, %xmm3
ja 0x25c7
movaps %xmm4, %xmm7
subss %xmm3, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm6
jbe 0x25ce
leal 0x1(%r11), %r9d
movaps %xmm4, %xmm3
subss %xmm1, %xmm4
cvtss2sd %xmm4, %xmm4
ucomisd %xmm5, %xmm4
ja 0x27bd
movl %r11d, (%rsi)
cmpq $0x1, %r10
jle 0x2617
movss (%rbx), %xmm4
movaps %xmm4, %xmm7
subss %xmm0, %xmm7
cvtss2sd %xmm7, %xmm7
addq $-0x10, %rbx
leal -0x1(%r11), %ebp
decq %r10
ucomisd %xmm6, %xmm7
ja 0x25ae
jmp 0x2617
xorl %r11d, %r11d
movl $0x1, %r9d
movaps %xmm1, %xmm3
subq %rax, %r8
shrq $0x4, %r8
leal -0x1(%r8), %r10d
movslq %r11d, %rbx
shlq $0x4, %rbx
movaps %xmm0, %xmm4
subss 0x8(%rax,%rbx), %xmm4
cvtss2sd %xmm4, %xmm4
ucomisd 0x39ea(%rip), %xmm4     # 0x6028
jbe 0x264b
incl %r11d
movl %r11d, %r9d
movl %r9d, (%rsi)
jmp 0x265a
testl %r11d, %r11d
jne 0x265a
movss 0x8(%rax), %xmm4
ucomiss %xmm3, %xmm4
ja 0x2646
movl (%rdx), %r9d
movl %r9d, %ebx
cmpl %r10d, %r9d
jge 0x266b
leal 0x1(%r9), %ebx
movl %ebx, (%rdx)
cmpl %r10d, %ebx
jge 0x2713
movslq %ebx, %r11
shlq $0x4, %r11
movss 0x8(%rax,%r11), %xmm6
movaps %xmm6, %xmm3
subss %xmm0, %xmm3
cvtss2sd %xmm3, %xmm3
ucomisd 0x398b(%rip), %xmm3     # 0x6020
jbe 0x2713
leaq (%r11,%rax), %r14
addq $0x18, %r14
addl $-0x2, %r8d
movsd 0x397d(%rip), %xmm4     # 0x6028
movsd 0x396d(%rip), %xmm5     # 0x6020
movaps %xmm1, %xmm3
ucomiss %xmm6, %xmm3
ja 0x26cc
movaps %xmm6, %xmm7
subss %xmm3, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm5
jbe 0x26d2
movaps %xmm6, %xmm3
movl %ebx, %r9d
subss %xmm1, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
ja 0x278a
leal 0x1(%rbx), %r11d
movl %r11d, (%rdx)
cmpl %ebx, %r8d
je 0x27b5
movss (%r14), %xmm6
movaps %xmm6, %xmm7
subss %xmm0, %xmm7
cvtss2sd %xmm7, %xmm7
addq $0x10, %r14
ucomisd %xmm5, %xmm7
movl %r11d, %ebx
ja 0x26b6
jmp 0x2719
movl %ebx, %r11d
movaps %xmm1, %xmm3
movslq %r11d, %r8
shlq $0x4, %r8
movss 0x8(%rax,%r8), %xmm1
subss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
ucomisd 0x38f1(%rip), %xmm0     # 0x6028
jbe 0x2741
decl %r11d
movl %r11d, %r9d
jmp 0x274b
cmpl %r11d, %r10d
jne 0x2751
ucomiss %xmm3, %xmm1
jbe 0x2751
movl %r9d, (%rdx)
movl %r9d, %r11d
movq 0x40(%rdi), %rdi
movslq (%rsi), %rdx
movq %rdx, %rsi
shlq $0x4, %rsi
cmpq (%rax,%rsi), %rdi
jl 0x2772
movslq %r11d, %rsi
shlq $0x4, %rsi
cmpq (%rax,%rsi), %rdi
jle 0x2776
xorl %eax, %eax
jmp 0x2785
subl %edx, %r11d
incl %r11d
movslq %r11d, %rax
cmpq %rax, (%rcx)
setle %al
popq %rbx
popq %r14
popq %rbp
retq
movl %r9d, (%rdx)
movslq %r9d, %r8
shlq $0x4, %r8
subss 0x8(%rax,%r8), %xmm2
xorps %xmm1, %xmm1
cvtss2sd %xmm2, %xmm1
ucomisd 0x3876(%rip), %xmm1     # 0x6020
movl %r9d, %r11d
ja 0x2719
jmp 0x2772
movl %r10d, %r11d
jmp 0x2719
movl %r9d, (%rsi)
movslq %r9d, %r10
shlq $0x4, %r10
movaps %xmm2, %xmm4
subss 0x8(%rax,%r10), %xmm4
cvtss2sd %xmm4, %xmm4
ucomisd 0x3843(%rip), %xmm4     # 0x6020
movl %r9d, %r11d
ja 0x2617
jmp 0x2772