// File: /workspace/github_cpp_makefile_star2_O3/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::crossoverParticleDE(unsigned int, std::vector<double, std::allocator<double>>, float, bool)
vector<double> Swarm::crossoverParticleDE(unsigned int particle, vector<double> mutationSet, float crossoverRate, bool normalize) {
	if (options.verbosity >= 3) {
		cout << "Crossing over particle " << particle << endl;
	}

	// Uses binomial crossover
	boost::random::uniform_int_distribution<int> intDist(0, this->getNumFreeParams() - 1);//boost::random::uniform_int_distribution<int> intDist(0, options.model->getNumFreeParams() - 1);
	unsigned int randParam = intDist(generalRand);
	boost::random::uniform_real_distribution<float> floatDist(0, 1);

	float cr;
	if (crossoverRate) {
		cr = crossoverRate;
	}
	else {
		cr = options.cr;
	}

	//cout << "crossing over particle " << particle << ". randParam is " << randParam << endl;
	vector<double> newParamSet;
	unsigned int p = 0;
	for (auto param = this->getFreeParams_().begin(); param != this->getFreeParams_().end(); ++param) { //for (auto param = options.model->getFreeParams_().begin(); param != options.model->getFreeParams_().end(); ++param) {
		//for (unsigned int p = 0; p < options.model->getNumFreeParams(); ++p) {
		float rand = floatDist(generalRand);
		//cout << "p: " << p << ". rand: " << rand << endl;

		if (rand < cr || p == randParam) {
			newParamSet.push_back(mutationSet[p]);
			//cout << "pushing back " << mutationSet[p] << " from mutation set" << endl;
		}
		else {
			if (normalize) {
				newParamSet.push_back(normalizeParam(particleCurrParamSets_.at(particle)[p], param->second->getGenMin(), param->second->getGenMax(), param->second->getIsLog()));
			}
			else {
				newParamSet.push_back(particleCurrParamSets_.at(particle)[p]);
			}
			//cout << "pushing back " << particleCurrParamSets_.at(particle)[p] << " from current set" << endl;
		}
		++p;
	}

	return newParamSet;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %r8d, 0x1c(%rsp)
movaps %xmm0, 0x20(%rsp)
movq %rcx, 0x38(%rsp)
movq %rsi, %r15
movq %rdi, %rbx
movl %edx, 0xc(%rsp)
cmpl $0x3, 0x1614(%rsi)
jb 0xa14cb
movl %edx, %ebp
movq 0xd4b25(%rip), %r12     # 0x175fa8
leaq 0x603b9(%rip), %rsi     # 0x101843
movl $0x17, %edx
movq %r12, %rdi
callq 0x22ab0
movl %ebp, %esi
movq %r12, %rdi
callq 0x22650
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r12, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
movl 0x15b8(%r15), %edx
decl %edx
js 0xa1638
leaq 0x58(%r15), %r12
xorl %r14d, %r14d
movq %r12, %rdi
xorl %esi, %esi
callq 0xbbd9b
movss 0x1704(%r15), %xmm0
xorps %xmm1, %xmm1
movups %xmm1, (%rbx)
movq $0x0, 0x10(%rbx)
movq 0x15a8(%r15), %rbp
movq %r15, 0x10(%rsp)
addq $0x1598, %r15           # imm = 0x1598
cmpq %r15, %rbp
je 0xa1626
movl %eax, %r13d
xorps %xmm1, %xmm1
movaps 0x20(%rsp), %xmm2
cmpneqss %xmm2, %xmm1
andps %xmm1, %xmm2
andnps %xmm0, %xmm1
orps %xmm2, %xmm1
movaps %xmm1, 0x20(%rsp)
addq $0x1400, 0x10(%rsp)     # imm = 0x1400
xorps %xmm0, %xmm0
movq %r12, %rdi
movss 0x5c7a5(%rip), %xmm1    # 0xfdcf8
callq 0xbd161
movaps 0x20(%rsp), %xmm1
ucomiss %xmm0, %xmm1
ja 0xa15c4
cmpl %r14d, %r13d
je 0xa15c4
cmpb $0x0, 0x1c(%rsp)
je 0xa15d2
movq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xa7a46
movl %r14d, %ecx
movq (%rax), %rax
movq 0x40(%rbp), %rdx
xorps %xmm1, %xmm1
cvtss2sd 0x48(%rdx), %xmm1
movsd (%rax,%rcx,8), %xmm0
xorps %xmm2, %xmm2
cvtss2sd 0x4c(%rdx), %xmm2
movzbl 0x51(%rdx), %esi
callq 0x7742c
movsd %xmm0, 0x40(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
jne 0xa15f9
movq %rbx, %rdi
leaq 0x40(%rsp), %rdx
callq 0x67e5a
jmp 0xa160f
movl %r14d, %edx
shlq $0x3, %rdx
movq 0x38(%rsp), %rax
jmp 0xa15e8
movq 0x10(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xa7a46
movl %r14d, %edx
shlq $0x3, %rdx
addq (%rax), %rdx
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0xa1607
movsd (%rdx), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x8(%rbx)
jmp 0xa160f
movq %rbx, %rdi
callq 0x684d4
incl %r14d
movq %rbp, %rdi
callq 0x22ad0
movq %rax, %rbp
cmpq %r15, %rax
jne 0xa1545
movq %rbx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x75910(%rip), %rdi     # 0x116f4f
leaq 0x7591c(%rip), %rsi     # 0x116f62
leaq 0x7594c(%rip), %rcx     # 0x116f99
movl $0x151, %edx            # imm = 0x151
callq 0x22610
jmp 0xa1659
movq %rax, %r14
movq (%rbx), %rdi
testq %rdi, %rdi
je 0xa1670
movq 0x10(%rbx), %rsi
subq %rdi, %rsi
callq 0x229c0
movq %r14, %rdi
callq 0x23240