// File: richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::sendMigrationSetDE(unsigned int, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>>, std::map<unsigned int, std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>>>>&)
void Swarm::sendMigrationSetDE(unsigned int island, vector<vector<unsigned int> > islandTopology, map<unsigned int, vector<vector<double> > > &migrationSets) {
	if (options.verbosity >= 3) {
		cout << "Sending migration set from island " << island << endl;
	}

	// Generate a random number between 1 and the number of neighbors
	// in the island topology
	boost::random::uniform_int_distribution<int> unif(0, islandTopology[island].size() - 1);
	int parID = 0;
	// Fill a vector with particles from this island, starting with best fits and ending with worst
	vector<unsigned int> particlesToSend;
	//Raquel: if the user provided constraints, then use the ranks calculated from the fit values and constraints combined in order to select the best particle
	if(options.constraints_.size()>0){

		//the ranks are sorted from the best particle to the worst, so the for loop will stop in the first time it finds a particle that belongs to the current iland
		for (auto fitIt = subParRankFinal.begin(); fitIt != subParRankFinal.end(); ++fitIt) {
			parID = fcalcParID(fitIt->first, options.models.size());

			if (particleToIsland_[parID] == island) {
				particlesToSend.push_back(parID);
				if (particlesToSend.size() == options.numToMigrate) {
					break;
				}
			}
		}

	}else{

		for (auto fitIt = particleBestFitsByFit_.begin(); fitIt != particleBestFitsByFit_.end(); ++fitIt) {
			if (particleToIsland_[fitIt->second] == island) {
				particlesToSend.push_back(fitIt->second);
				if (particlesToSend.size() == options.numToMigrate) {
					break;
				}
			}
		}

	}

	// Choose the index of our receiver
	unsigned int receivingIslandIndex = unif(generalRand);

	// Loop through particles to send
	vector<double> migrationSet;
	//for (auto particle = particlesToSend.begin(); particle != particlesToSend.end(); ++particle) {
	for (unsigned int i = 0; i < options.numToMigrate; ++i) {
		if (options.verbosity >= 3) {
			cout << "sending set " << i + 1 << " from particle " << particlesToSend[i] << endl;
		}
		// Fill migrationSet with this particles current parameters
		for (auto param = particleCurrParamSets_[particlesToSend[i]].begin(); param != particleCurrParamSets_[particlesToSend[i]].end(); ++param) {
			migrationSet.push_back(*param);
		}
		// Add that migration set to the list of the receiving island's
		// migration sets
		migrationSets[islandTopology[island][receivingIslandIndex]].push_back(migrationSet);
		migrationSet.clear();
		if (options.verbosity >= 3) {
			cout << island << " sending migration set to island " << islandTopology[island][receivingIslandIndex] << endl;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdx, -0xc0(%rbp)
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xb8(%rbp)
cmpl $0x3, 0x1614(%rax)
jb 0x10f662
movq 0x1c5914(%rip), %rdi    # 0x2d4f50
leaq 0xd3c02(%rip), %rsi     # 0x1e3245
callq 0x2ff50
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x30640
movq %rax, %rdi
movq 0x1c596b(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
movq -0xc0(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0x1228d0
movq %rax, %rdi
callq 0xb46f0
subq $0x1, %rax
movl %eax, %edx
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x123cd0
movl $0x0, -0x2c(%rbp)
leaq -0x48(%rbp), %rdi
callq 0xb2010
movq -0xb8(%rbp), %rdi
addq $0x14c0, %rdi           # imm = 0x14C0
addq $0x120, %rdi            # imm = 0x120
callq 0x123030
cmpq $0x0, %rax
jbe 0x10f7be
movq -0xb8(%rbp), %rdi
addq $0x18f0, %rdi           # imm = 0x18F0
callq 0x123d20
movq %rax, -0x50(%rbp)
movq -0xb8(%rbp), %rdi
addq $0x18f0, %rdi           # imm = 0x18F0
callq 0x123d90
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x123d50
testb $0x1, %al
jne 0x10f704
jmp 0x10f7b9
leaq -0x50(%rbp), %rdi
callq 0x123dc0
movq -0xb8(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0xc8(%rbp)
addq $0x15c0, %rdi           # imm = 0x15C0
callq 0x45170
movl -0xc8(%rbp), %edi
movl %eax, %esi
callq 0x17d3f0
movl %eax, -0xc4(%rbp)
jmp 0x10f73d
movq -0xb8(%rbp), %rdi
movl -0xc4(%rbp), %eax
movl %eax, -0x2c(%rbp)
addq $0x1d20, %rdi           # imm = 0x1D20
movslq -0x2c(%rbp), %rsi
callq 0xccc10
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x10f7a9
movl -0x2c(%rbp), %eax
movl %eax, -0x68(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x122310
jmp 0x10f779
leaq -0x48(%rbp), %rdi
callq 0xb46f0
movq -0xb8(%rbp), %rcx
movl 0x170c(%rcx), %ecx
cmpq %rcx, %rax
jne 0x10f7a7
jmp 0x10f7b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x10fbac
jmp 0x10f7a9
jmp 0x10f7ab
leaq -0x50(%rbp), %rdi
callq 0x123de0
jmp 0x10f6d7
jmp 0x10f880
movq -0xb8(%rbp), %rdi
addq $0x1ab0, %rdi           # imm = 0x1AB0
callq 0x122630
movq %rax, -0x70(%rbp)
movq -0xb8(%rbp), %rdi
addq $0x1ab0, %rdi           # imm = 0x1AB0
callq 0x1231a0
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x1231d0
testb $0x1, %al
jne 0x10f7ff
jmp 0x10f87e
movq -0xb8(%rbp), %rax
addq $0x1d20, %rax           # imm = 0x1D20
movq %rax, -0xd0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x122660
movq -0xd0(%rbp), %rdi
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xccc10
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x10f86e
leaq -0x70(%rbp), %rdi
callq 0x122660
movq %rax, %rsi
addq $0x8, %rsi
leaq -0x48(%rbp), %rdi
callq 0xb4640
jmp 0x10f84f
leaq -0x48(%rbp), %rdi
callq 0xb46f0
movq -0xb8(%rbp), %rcx
movl 0x170c(%rcx), %ecx
cmpq %rcx, %rax
jne 0x10f86c
jmp 0x10f87e
jmp 0x10f86e
jmp 0x10f870
leaq -0x70(%rbp), %rdi
callq 0xcbd20
jmp 0x10f7d5
jmp 0x10f880
movq -0xb8(%rbp), %rsi
addq $0x58, %rsi
leaq -0x28(%rbp), %rdi
callq 0x123e00
movl %eax, -0xd4(%rbp)
jmp 0x10f89c
movl -0xd4(%rbp), %eax
movl %eax, -0x7c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xb2580
movl $0x0, -0x9c(%rbp)
movq -0xb8(%rbp), %rcx
movl -0x9c(%rbp), %eax
cmpl 0x170c(%rcx), %eax
jae 0x10fb8e
movq -0xb8(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x10f999
movq 0x1c5661(%rip), %rdi    # 0x2d4f50
leaq 0xd3972(%rip), %rsi     # 0x1e3268
callq 0x2ff50
movq %rax, -0xe0(%rbp)
jmp 0x10f904
movq -0xe0(%rbp), %rdi
movl -0x9c(%rbp), %esi
incl %esi
callq 0x30640
movq %rax, -0xe8(%rbp)
jmp 0x10f921
movq -0xe8(%rbp), %rdi
leaq 0xd3946(%rip), %rsi     # 0x1e3275
callq 0x2ff50
movq %rax, -0xf0(%rbp)
jmp 0x10f93d
movl -0x9c(%rbp), %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
callq 0xccc10
movq -0xf0(%rbp), %rdi
movl (%rax), %esi
callq 0x30640
movq %rax, -0xf8(%rbp)
jmp 0x10f965
movq -0xf8(%rbp), %rdi
movq 0x1c5655(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x10f97a
jmp 0x10f999
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xb2660
jmp 0x10fbac
movq -0xb8(%rbp), %rax
addq $0x1400, %rax           # imm = 0x1400
movq %rax, -0x108(%rbp)
movl -0x9c(%rbp), %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
callq 0xccc10
movq -0x108(%rbp), %rdi
movq %rax, %rsi
callq 0x122da0
movq %rax, -0x100(%rbp)
jmp 0x10f9d6
movq -0x100(%rbp), %rdi
callq 0xb2ea0
movq %rax, -0xa8(%rbp)
movq -0xb8(%rbp), %rax
addq $0x1400, %rax           # imm = 0x1400
movq %rax, -0x118(%rbp)
movl -0x9c(%rbp), %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
callq 0xccc10
movq -0x118(%rbp), %rdi
movq %rax, %rsi
callq 0x122da0
movq %rax, -0x110(%rbp)
jmp 0x10fa26
movq -0x110(%rbp), %rdi
callq 0xbdfd0
movq %rax, -0xb0(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x122510
testb $0x1, %al
jne 0x10fa52
jmp 0x10fa82
leaq -0xa8(%rbp), %rdi
callq 0xb2ed0
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
callq 0xb2e30
jmp 0x10fa6f
jmp 0x10fa71
leaq -0xa8(%rbp), %rdi
callq 0xb2ef0
jmp 0x10f9e9
movq -0xc0(%rbp), %rdi
movq -0x20(%rbp), %rax
movq %rax, -0x128(%rbp)
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0x1228d0
movq %rax, %rdi
movl -0x7c(%rbp), %eax
movl %eax, %esi
callq 0xccc10
movq -0x128(%rbp), %rdi
movq %rax, %rsi
callq 0x123e30
movq %rax, -0x120(%rbp)
jmp 0x10fac3
movq -0x120(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x123f10
jmp 0x10fad8
leaq -0x98(%rbp), %rdi
callq 0x123f80
movq -0xb8(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x10fb78
movl -0xc(%rbp), %esi
movq 0x1c544e(%rip), %rdi    # 0x2d4f50
callq 0x30640
movq %rax, -0x130(%rbp)
jmp 0x10fb10
movq -0x130(%rbp), %rdi
leaq 0xd3767(%rip), %rsi     # 0x1e3285
callq 0x2ff50
movq %rax, -0x138(%rbp)
jmp 0x10fb2c
movq -0xc0(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %esi
callq 0x1228d0
movq %rax, %rdi
movl -0x7c(%rbp), %eax
movl %eax, %esi
callq 0xccc10
movq -0x138(%rbp), %rdi
movl (%rax), %esi
callq 0x30640
movq %rax, -0x140(%rbp)
jmp 0x10fb61
movq -0x140(%rbp), %rdi
movq 0x1c5459(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x10fb76
jmp 0x10fb78
jmp 0x10fb7a
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x10f8bb
leaq -0x98(%rbp), %rdi
callq 0xb2660
leaq -0x48(%rbp), %rdi
callq 0xb2400
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0xb2400
movq -0x60(%rbp), %rdi
callq 0x30170
nop