// File: /workspace/github_cpp_makefile_star2_O3/melop[P]admixem/config.cpp
// Function: RecombProbConfigurations::GetBreakPointsByArm(bool, int, int, std::vector<double, std::allocator<double>>&)
void RecombProbConfigurations::GetBreakPointsByArm(bool bSex, int nChr, int nArm,vector<double> &vRet) { // return a vector of break points for a given arm of a given chromosome for a given sex
	
		#ifdef _OPENMP
		int nCPU = omp_get_thread_num();
			#ifdef DEBUG
			printf("CPU %d: %s : %d\n", nCPU, "SexSelFormulae # ", nCPU);
			#endif
		#else
			int nCPU = 0;
		#endif
	//double nExpectedPoints = (true==bSex? (nArm==1? _nExpectedMaleRecPerMeiosisArm1[nChr] : _nExpectedMaleRecPerMeiosisArm2[nChr]) : (nArm==1? _nExpectedFemaleRecPerMeiosisArm1[nChr] : _nExpectedFemaleRecPerMeiosisArm2[nChr]));
	//int nBreakPointsToPut = (int)nExpectedPoints; // get integral part
	//nBreakPointsToPut += (UniformGen.Next() <= (nExpectedPoints - (double)nBreakPointsToPut)) ? 1:0;
	Poisson * pPoissonGen = (true==bSex? (nArm==1?  pvMaleRecArm1Gen[nCPU][nChr] : pvMaleRecArm2Gen[nCPU][nChr]) : (nArm==1? pvFemaleRecArm1Gen[nCPU][nChr] : pvFemaleRecArm2Gen[nCPU][nChr]));; 
	int nBreakPointsToPut = pPoissonGen->Next();
	
	double nCentromerePos = ((SimulationConfigurations*)this->_pParentConfig)->pMarkerConfig->GetCentromerePosition(nChr);
	double nChrLen = ((SimulationConfigurations*)this->_pParentConfig)->pMarkerConfig->GetChromosomeLength(nChr);

	double nStart = (nArm==1)? 0.0 : nCentromerePos;
	double nEnd   = (nArm==1)? nCentromerePos : nChrLen;

	//vector<double> * pvAccuProb;
	tk::spline * pvAccuProbSpline;
	size_t nCentromereIndex, nLastIndex, nStartIndex, nEndIndex;

	if (!this->_bUseUniform) {
		//pvAccuProb = true==bSex? pvMaleAccuProb : pvFemaleAccuProb;
		if (bSex) {
			pvAccuProbSpline = nArm==1? &vMaleAccuProbSplineArm1[nChr] : &vMaleAccuProbSplineArm2[nChr];
		}
		else {
			pvAccuProbSpline = nArm==1? &vFemaleAccuProbSplineArm1[nChr] : &vFemaleAccuProbSplineArm2[nChr];
		}
		//nCentromereIndex = std::distance( pvBreakpointSamplePositions[nChr].begin(), lower_bound(pvBreakpointSamplePositions[nChr].begin(),pvBreakpointSamplePositions[nChr].end(), nCentromerePos));
		//nLastIndex = std::distance(pvBreakpointSamplePositions[nChr].begin() , pvBreakpointSamplePositions[nChr].end());
		//nStartIndex = (nArm==1)? 0 : nCentromereIndex + 1;
		//nEndIndex = (nArm==1)? nCentromereIndex : nLastIndex;
	}
	
	//printf("Breakpointstoput for sex %d Chr %d Arm %d: %d\n", bSex, nChr, nArm, nBreakPointsToPut);
	//vector<double>::iterator it_start = lower_bound(pvAccuProb[nChr]begin(), pvAccuProb->end(), nStart);

	for (int i=0;i<nBreakPointsToPut;i++) {

		double nRand = vUniformGen[nCPU]->Next();
		if (!this->_bUseUniform) {
			/*
			std::vector<double>::iterator oLowerBound;
			oLowerBound = lower_bound( pvAccuProb[nChr].begin() + nStartIndex, pvAccuProb[nChr].begin() + nEndIndex, nRand);
			size_t nLowerBoundIndex = std::distance(pvAccuProb[nChr].begin(), oLowerBound);
			if (nLowerBoundIndex == 0 || nLowerBoundIndex==nEndIndex) {
				// the first element
				i--;
				continue; //break point cannot be inserted at the tips
			}
			//vector<double>::iterator oPreviousPoint = oLowerBound - 1;
			double nPos1 = pvBreakpointSamplePositions[nChr].at(nLowerBoundIndex - 1);
			double nPos2 = pvBreakpointSamplePositions[nChr].at(nLowerBoundIndex);
			//interpolate
			vRet.push_back( (nPos1 + nPos2) / 2 );
			*/
			//new code that uses spline interpolation
			vRet.push_back((*pvAccuProbSpline)(nRand));
		} else {
			double nArmLen = nEnd - nStart;
			double nBpPos = (nArm==1)? (nArmLen * nRand) : (nCentromerePos + nArmLen * nRand);
			vRet.push_back(nBpPos);
		}
		
	}

	sort(vRet.begin(), vRet.end());


}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movl %esi, %r15d
movq %rdi, %r14
xorl %eax, %eax
movl %ecx, 0xc(%rsp)
cmpl $0x1, %ecx
setne %al
movslq %edx, %rbp
movl %r15d, %ecx
xorb $0x1, %cl
movzbl %cl, %ecx
shll $0x4, %ecx
leal (%rcx,%rax,8), %eax
movq 0x50(%rax,%rdi), %rax
movq (%rax), %rax
movq (%rax,%rbp,8), %rdi
movq (%rdi), %rax
callq *(%rax)
cvttsd2si %xmm0, %r12d
cmpb $0x0, 0x70(%r14)
je 0x13593
testl %r12d, %r12d
jle 0x1354b
movq (%r14), %rax
movq (%rax), %rax
movq 0x48(%rax), %rcx
movsd (%rcx,%rbp,8), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd %xmm0, 0x20(%rsp)
cmpl $0x1, 0xc(%rsp)
je 0x133cc
movq 0x30(%rax), %rax
movsd (%rax,%rbp,8), %xmm0
subsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
xorl %r15d, %r15d
leaq 0x356ba(%rip), %rbp     # 0x48a90
movq (%rbp), %rax
movq (%rax), %rdi
movq (%rdi), %rax
callq *(%rax)
cmpb $0x0, 0x70(%r14)
je 0x13405
cmpl $0x1, 0xc(%rsp)
je 0x13488
mulsd 0x20(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
jmp 0x1348e
movq (%r13), %rdx
movq 0x8(%r13), %rax
subq %rdx, %rax
sarq $0x3, %rax
movq %rdx, %rcx
testq %rax, %rax
jle 0x13445
movq %rax, %rdi
movq %rdx, %rcx
movq %rax, %rsi
shrq %rsi
ucomisd (%rcx,%rsi,8), %xmm0
jbe 0x1343d
leaq (%rcx,%rsi,8), %rcx
addq $0x8, %rcx
notq %rsi
addq %rdi, %rsi
movq %rsi, %rdi
testq %rsi, %rsi
jg 0x13425
subq %rdx, %rcx
shrq $0x3, %rcx
cmpl $0x2, %ecx
movl $0x1, %esi
cmovll %esi, %ecx
decl %ecx
movapd %xmm0, %xmm1
subsd (%rdx,%rcx,8), %xmm1
movsd (%rdx), %xmm2
ucomisd %xmm0, %xmm2
jbe 0x134b4
movsd 0x78(%r13), %xmm0
mulsd %xmm1, %xmm0
addsd 0x80(%r13), %xmm0
movq 0x18(%r13), %rax
jmp 0x1350c
mulsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
jne 0x13524
movq %rbx, %rdi
leaq 0x18(%rsp), %rdx
callq 0x1d008
jmp 0x1353f
ucomisd -0x8(%rdx,%rax,8), %xmm0
jbe 0x134dd
movq 0x48(%r13), %rcx
movq 0x60(%r13), %rdx
movsd -0x8(%rcx,%rax,8), %xmm0
mulsd %xmm1, %xmm0
addsd -0x8(%rdx,%rax,8), %xmm0
decq %rax
shlq $0x3, %rax
jmp 0x13508
leaq (,%rcx,8), %rax
movq 0x30(%r13), %rdx
movq 0x48(%r13), %rsi
movsd (%rdx,%rcx,8), %xmm0
mulsd %xmm1, %xmm0
addsd (%rsi,%rcx,8), %xmm0
movq 0x60(%r13), %rdx
mulsd %xmm1, %xmm0
addsd (%rdx,%rcx,8), %xmm0
addq 0x18(%r13), %rax
mulsd %xmm1, %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x13532
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x8(%rbx)
jmp 0x1353f
movq %rbx, %rdi
leaq 0x18(%rsp), %rdx
callq 0x1d1c4
incl %r15d
cmpl %r12d, %r15d
jne 0x133d6
movq (%rbx), %r14
movq 0x8(%rbx), %rbx
cmpq %rbx, %r14
je 0x13584
movq %rbx, %rax
subq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1d2a3
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1d39c
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb %r15b, %r15b
je 0x135b2
cmpl $0x1, 0xc(%rsp)
jne 0x135cc
imulq $0xa8, %rbp, %r13
addq 0x90(%r14), %r13
jmp 0x1338c
cmpl $0x1, 0xc(%rsp)
jne 0x135df
imulq $0xa8, %rbp, %r13
addq 0xa8(%r14), %r13
jmp 0x1338c
imulq $0xa8, %rbp, %r13
addq 0xc0(%r14), %r13
jmp 0x1338c
imulq $0xa8, %rbp, %r13
addq 0xd8(%r14), %r13
jmp 0x1338c