// File: /workspace/github_cpp_makefile_star2_O3/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::calcParticlePosQPSO(unsigned int, std::vector<double, std::allocator<double>>)
vector<double> Swarm::calcParticlePosQPSO(unsigned int particle, vector<double> mBests) {

	vector<double> nextPositions;
	vector<double> neighborhoodBests = getNeighborhoodBestPositions(particle);
	for (unsigned int d = 0; d < mBests.size(); ++d) {
		//cout << particle << " before: " << particleCurrParamSets_[particle][d] << endl;
		//cout << particle << " mbest: " << mBests[d] << endl;
		//cout << particle << " best: " << particleBestParamSets_[particle][d] << endl;
		//cout << particle << " swarmbest: " << getNeighborhoodBestPositions(particle)[d] << endl;
		double fi1 = ((double) rand() / (RAND_MAX));
		//cout << "f1: " << fi1 << endl;
		//double fi2 = ((double) rand() / (RAND_MAX));
		//double p = ((fi1 * particleBestFits_.at(particle)) + (fi2 * swarmBestFits_.begin()->first)) / (fi1 + fi2);
		// TODO: Work out whether or not we should be using abs() for this and below
		double p = fi1 * abs(particleBestParamSets_[particle][d]) + (1 - fi1) * neighborhoodBests[d];
		double u = ((double) rand() / (RAND_MAX));

		// TODO: Linearly decrease beta from 1.0 to 0.5? See Liu et al.

		// Liu et all, 2005, eq 2a
		if (u > 0.5) {
			nextPositions.push_back(p - beta_ * abs(mBests[d] - abs(particleCurrParamSets_.at(particle)[d])) * log(1/u));
			//cout << particle << " p: " << p << endl;
			//cout << "mbest - curr: " << mBests[d] - particleCurrParamSets_.at(particle)[d] << endl;
			//cout << "log: " << log(1/u) << endl;
			//cout << particle << " after: " << p - beta_ * abs(mBests[d] - particleCurrParamSets_.at(particle)[d]) * log(1/u) << endl;
		}
		else {
			nextPositions.push_back(p + beta_ * abs(mBests[d] - abs(particleCurrParamSets_.at(particle)[d])) * log(1/u));
			//cout << particle << " after: " << p + beta_ * abs(mBests[d] - particleCurrParamSets_.at(particle)[d]) * log(1/u) << endl;
		}
	}

	return nextPositions;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movl %edx, 0xc(%rsp)
xorpd %xmm0, %xmm0
movupd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
leaq 0x58(%rsp), %rdi
callq 0x8a700
movq 0x8(%r14), %rax
cmpq (%r14), %rax
je 0x8a695
leaq 0x1cc0(%r15), %rax
movq %rax, 0x50(%rsp)
leaq 0x1400(%r15), %rax
movq %rax, 0x30(%rsp)
movl $0x1, %r13d
xorl %ebp, %ebp
callq 0x22230
movl %eax, %r12d
movq 0x50(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xa7e00
xorps %xmm0, %xmm0
cvtsi2sd %r12d, %xmm0
movsd 0x6de14(%rip), %xmm1    # 0xf82e0
divsd %xmm1, %xmm0
movq (%rax), %rax
movsd (%rax,%rbp,8), %xmm2
andpd 0x6d770(%rip), %xmm2    # 0xf7c50
movsd 0x6de08(%rip), %xmm1    # 0xf82f0
subsd %xmm0, %xmm1
movq 0x58(%rsp), %rax
mulsd (%rax,%rbp,8), %xmm1
mulsd %xmm0, %xmm2
addsd %xmm1, %xmm2
movapd %xmm2, 0x70(%rsp)
callq 0x22230
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x6ddc8(%rip), %xmm0    # 0xf82e0
movsd %xmm0, 0x38(%rsp)
ucomisd 0x6c5d2(%rip), %xmm0    # 0xf6af8
jbe 0x8a5d3
movsd 0x1da0(%r15), %xmm0
movsd %xmm0, 0x40(%rsp)
movq (%r14), %rax
movsd (%rax,%rbp,8), %xmm0
movapd %xmm0, 0x10(%rsp)
movq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xa7a46
movq (%rax), %rax
movsd (%rax,%rbp,8), %xmm0
movapd 0x6d6e8(%rip), %xmm1    # 0xf7c50
andpd %xmm1, %xmm0
movapd 0x10(%rsp), %xmm2
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
movapd %xmm2, 0x10(%rsp)
movsd 0x6dd68(%rip), %xmm0    # 0xf82f0
divsd 0x38(%rsp), %xmm0
callq 0x227a0
movapd 0x10(%rsp), %xmm1
mulsd 0x40(%rsp), %xmm1
mulsd %xmm0, %xmm1
movapd 0x70(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
jne 0x8a660
movq %rbx, %rdi
leaq 0x28(%rsp), %rdx
callq 0x67e5a
jmp 0x8a67b
movsd 0x1da0(%r15), %xmm0
movsd %xmm0, 0x10(%rsp)
movq (%r14), %rax
movsd (%rax,%rbp,8), %xmm0
movapd %xmm0, 0x40(%rsp)
movq 0x30(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xa7a46
movq (%rax), %rax
movsd (%rax,%rbp,8), %xmm0
movapd 0x6d641(%rip), %xmm1    # 0xf7c50
andpd %xmm1, %xmm0
movapd 0x40(%rsp), %xmm2
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
movsd 0x10(%rsp), %xmm0
mulsd %xmm2, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x6dcb7(%rip), %xmm0    # 0xf82f0
divsd 0x38(%rsp), %xmm0
callq 0x227a0
mulsd 0x10(%rsp), %xmm0
addsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x8a66e
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x8(%rbx)
jmp 0x8a67b
movq %rbx, %rdi
leaq 0x28(%rsp), %rdx
callq 0x67e5a
movq 0x8(%r14), %rax
subq (%r14), %rax
movl %r13d, %ebp
sarq $0x3, %rax
incl %r13d
cmpq %rbp, %rax
ja 0x8a4a5
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x8a6ac
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x229c0
movq %rbx, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
jmp 0x8a6e4
jmp 0x8a6ca
jmp 0x8a6ca
movq %rax, %r14
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x8a6e4
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x229c0
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x8a6f8
movq 0x10(%rbx), %rsi
subq %rdi, %rsi
callq 0x229c0
movq %r14, %rdi
callq 0x23240