// File: /workspace/github_cpp_makefile_star2_O2/samuel500[P]NEAT/population.cpp
// Function: Population::xor_epoch()
void Population::xor_epoch(){

	all_nodes.clear();
	all_connections.clear();

	speciate();

	vector<vector<double>> xs {{1., 0.,0.}, {1., 0.,1.}, {1., 1.,0.}, {1., 1.,1.}};
	vector<double> ys {0., 1., 1., 0.};

	vector<Individual*>::iterator indPtr;


	double pop_avg_fitness = 0.;

	for(indPtr=individuals.begin(); indPtr!=individuals.end(); ++indPtr){
		double fitness=4.;
		for(int i=0; i<xs.size(); i++){
			(*indPtr)->activate(xs[i]);
			vector<double> out = (*indPtr)->get_outputs();
			(*indPtr)->reset_activations();
			fitness -= abs(out[0]-ys[i]);
		}
		fitness = pow(fitness, 2);
		(*indPtr)->fitness = fitness;
	}
	// cout << "x1" << endl;

	vector<Species*>::iterator spePtr;

	sort(individuals.begin(), individuals.end(), indPtr_compare2);

	elite = individuals[individuals.size()-1];
	// cout << "x2" << endl;
	if(elite->fitness>max_fitness) max_fitness = elite->fitness;


	for(spePtr=species.begin(); spePtr!=species.end(); ++spePtr){
		(*spePtr)->adjust_fitness();

	}

	sort(species.begin(), species.end(), spePtr_compare);



	for(indPtr=individuals.begin(); indPtr!=individuals.end(); ++indPtr){
		pop_avg_fitness += (*indPtr)->adjusted_fitness;
	}

	pop_avg_fitness /= individuals.size();


	for(indPtr=individuals.begin(); indPtr!=individuals.end(); ++indPtr){
		(*indPtr)->est_n_offspring = (*indPtr)->adjusted_fitness / pop_avg_fitness;
	}

	int temp_n_offspring = 0;
	for(spePtr=species.begin(); spePtr!=species.end(); ++spePtr){
		temp_n_offspring += (*spePtr)->calc_n_offspring();
	}
	// cout << "x3" << endl;

	// give missing offspring (bc double->int) to best species
	species[species.size()-1]->n_offspring += (pop_size - temp_n_offspring);


	for(spePtr=species.begin(); spePtr!=species.end(); ++spePtr){
		if((*spePtr)->n_offspring==0) species.erase(spePtr);
	}


	vector<Individual*> new_individuals;
	vector<Individual*> descendants;

	for(spePtr=species.begin(); spePtr!=species.end(); ++spePtr){
	// cout << "x4" << endl;

		descendants = (*spePtr)->evolve(&all_nodes, &all_connections);
	// cout << "x5" << endl;

		new_individuals.insert(end(new_individuals), begin(descendants), end(descendants));
	}

	for(indPtr=individuals.begin(); indPtr!=prev(individuals.end()); ++indPtr){
		delete *indPtr;
	}
	individuals.clear();
	individuals = new_individuals;


	for(spePtr=species.begin(); spePtr!=prev(species.end()); ++spePtr){
		delete *spePtr;
	}
	species.clear();


}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq %rdi, %r13
movq 0x18(%rdi), %rax
cmpq %rax, 0x20(%rdi)
je 0x1bc9
movq %rax, 0x20(%r13)
movq 0x30(%r13), %rax
cmpq %rax, 0x38(%r13)
je 0x1bd7
movq %rax, 0x38(%r13)
movq %r13, %rdi
callq 0x2126
movupd 0x5571(%rip), %xmm0     # 0x7158
leaq -0x80(%rbp), %rsi
movapd %xmm0, (%rsi)
andq $0x0, 0x10(%rsi)
leaq -0x100(%rbp), %r14
pushq $0x3
popq %rdx
leaq -0x2d(%rbp), %rcx
movq %r14, %rdi
callq 0x2290
leaq -0xe8(%rbp), %r15
movupd 0x5557(%rip), %xmm0     # 0x7170
leaq -0x50(%rbp), %rsi
movapd %xmm0, (%rsi)
movabsq $0x3ff0000000000000, %rbx # imm = 0x3FF0000000000000
movq %rbx, 0x10(%rsi)
pushq $0x3
popq %rdx
leaq -0x2c(%rbp), %rcx
movq %r15, %rdi
callq 0x2290
leaq -0xd0(%rbp), %r15
movupd 0x553b(%rip), %xmm0     # 0x7188
leaq -0x120(%rbp), %rsi
movapd %xmm0, (%rsi)
andq $0x0, 0x10(%rsi)
pushq $0x3
popq %rdx
leaq -0x2b(%rbp), %rcx
movq %r15, %rdi
callq 0x2290
leaq -0xb8(%rbp), %r15
movupd 0x5525(%rip), %xmm0     # 0x71a0
leaq -0x150(%rbp), %rsi
movapd %xmm0, (%rsi)
movq %rbx, 0x10(%rsi)
pushq $0x3
popq %rdx
leaq -0x2a(%rbp), %rcx
movq %r15, %rdi
callq 0x2290
leaq -0x98(%rbp), %rdi
leaq -0x100(%rbp), %rsi
pushq $0x4
popq %rdx
leaq -0x29(%rbp), %rcx
callq 0x2342
leaq 0x18(%r13), %rax
movq %rax, -0x60(%rbp)
leaq 0x30(%r13), %rax
movq %rax, -0x58(%rbp)
pushq $0x48
popq %rbx
leaq (%rbx,%rbp), %rdi
addq $-0x100, %rdi
callq 0x2914
addq $-0x18, %rbx
cmpq $-0x18, %rbx
jne 0x1cc6
movups 0x54e1(%rip), %xmm0     # 0x71c8
leaq -0x100(%rbp), %rsi
movaps %xmm0, 0x10(%rsi)
movupd 0x54be(%rip), %xmm0     # 0x71b8
movapd %xmm0, (%rsi)
leaq -0x80(%rbp), %rdi
pushq $0x4
popq %rdx
leaq -0x50(%rbp), %rcx
callq 0x2290
movq (%r13), %r15
leaq -0x138(%rbp), %r12
movq %r13, -0x68(%rbp)
movq 0x8(%r13), %rsi
cmpq %rsi, %r15
je 0x1df2
xorl %ebx, %ebx
xorl %r13d, %r13d
movsd 0x5319(%rip), %xmm0     # 0x7050
movsd %xmm0, -0x38(%rbp)
movq -0x98(%rbp), %rsi
movq -0x90(%rbp), %rax
subq %rsi, %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
cmpq %r13, %rax
jbe 0x1dd5
movq (%r15), %r14
addq %rbx, %rsi
movq %r12, %rdi
callq 0x22c6
movq %r14, %rdi
movq %r12, %rsi
callq 0x5788
movq %r12, %rdi
callq 0x2914
movq (%r15), %rsi
leaq -0x100(%rbp), %rdi
callq 0x5864
movq (%r15), %rdi
callq 0x58c0
movq -0x100(%rbp), %rax
movsd (%rax), %xmm0
movq -0x80(%rbp), %rax
subsd (%rax,%r13,8), %xmm0
andpd 0x52c1(%rip), %xmm0     # 0x7070
movsd -0x38(%rbp), %xmm1
subsd %xmm0, %xmm1
movsd %xmm1, -0x38(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x2914
incq %r13
addq $0x18, %rbx
jmp 0x1d3c
movsd -0x38(%rbp), %xmm0
mulsd %xmm0, %xmm0
movq (%r15), %rax
movsd %xmm0, (%rax)
addq $0x8, %r15
movq -0x68(%rbp), %r13
jmp 0x1d1d
movq (%r13), %rdi
leaq -0x83f(%rip), %rdx      # 0x15be
callq 0x2ced
movq 0x8(%r13), %rax
movq -0x8(%rax), %rax
movq %rax, 0x48(%r13)
movsd (%rax), %xmm0
ucomisd 0x80(%r13), %xmm0
jbe 0x1e26
movsd %xmm0, 0x80(%r13)
leaq 0x50(%r13), %r12
movq 0x50(%r13), %rbx
movq 0x58(%r13), %rsi
cmpq %rsi, %rbx
je 0x1e45
movq (%rbx), %rdi
callq 0x42da
addq $0x8, %rbx
jmp 0x1e2e
movq (%r12), %rdi
leaq -0x89c(%rip), %rdx      # 0x15b4
callq 0x330b
movq (%r13), %rax
movq 0x8(%r13), %rcx
xorpd %xmm0, %xmm0
movq %rax, %rdx
cmpq %rcx, %rdx
je 0x1e77
movq (%rdx), %rsi
addsd 0x8(%rsi), %xmm0
addq $0x8, %rdx
jmp 0x1e64
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
movq %rdx, %xmm1
punpckldq 0x51f2(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x51fa(%rip), %xmm1     # 0x7090
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
cmpq %rcx, %rax
je 0x1ec2
movq (%rax), %rdx
movsd 0x8(%rdx), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rdx)
addq $0x8, %rax
jmp 0x1ea6
movq (%r12), %rbx
leaq -0x8(%rbx), %r15
xorl %r14d, %r14d
cmpq 0x58(%r13), %rbx
je 0x1ee8
movq (%rbx), %rdi
callq 0x4388
addl %eax, %r14d
addq $0x8, %rbx
addq $0x8, %r15
jmp 0x1ecd
movl 0x68(%r13), %eax
subl %r14d, %eax
movq 0x50(%r13), %r14
movq (%r15), %rcx
addl %eax, 0x40(%rcx)
cmpq %rbx, %r14
je 0x1f1c
movq (%r14), %rax
cmpl $0x0, 0x40(%rax)
jne 0x1f16
movq %r12, %rdi
movq %r14, %rsi
callq 0x23a8
movq 0x58(%r13), %rbx
addq $0x8, %r14
jmp 0x1ef9
xorpd %xmm0, %xmm0
leaq -0x100(%rbp), %rcx
andq $0x0, 0x10(%rcx)
movq %r12, %rax
leaq -0x50(%rbp), %r12
andq $0x0, 0x10(%r12)
movapd %xmm0, (%rcx)
movapd %xmm0, (%r12)
movq %rax, -0x38(%rbp)
movq (%rax), %r15
leaq -0x120(%rbp), %r14
cmpq %rbx, %r15
je 0x1fa1
movq (%r15), %rsi
movq %r14, %rdi
movq -0x60(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq 0x43c2
movq %r12, %rdi
movq %r14, %rsi
callq 0x392a
movq %r14, %rdi
callq 0x2508
movq -0xf8(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq -0x48(%rbp), %rcx
leaq -0x100(%rbp), %rdi
callq 0x23e2
addq $0x8, %r15
movq 0x58(%r13), %rbx
jmp 0x1f51
movq (%r13), %rbx
movq 0x8(%r13), %rax
leaq -0x8(%rax), %rcx
cmpq %rcx, %rbx
je 0x1fd5
movq (%rbx), %r14
testq %r14, %r14
je 0x1fc2
movq %r14, %rdi
callq 0x5dda
movl $0x98, %esi
movq %r14, %rdi
callq 0x1100
addq $0x8, %rbx
jmp 0x1fa5
movq (%r13), %rcx
cmpq %rcx, %rax
je 0x1fe2
movq %rcx, 0x8(%r13)
leaq -0x100(%rbp), %rsi
movq %r13, %rdi
callq 0x2402
movq -0x38(%rbp), %rax
movq (%rax), %rbx
pushq $0x48
popq %r14
movq 0x58(%r13), %rax
leaq -0x8(%rax), %rcx
cmpq %rcx, %rbx
je 0x202a
movq (%rbx), %r15
testq %r15, %r15
je 0x2019
movq %r15, %rdi
callq 0x45ec
movq %r15, %rdi
movq %r14, %rsi
callq 0x1100
addq $0x8, %rbx
jmp 0x1ffc
movq -0x38(%rbp), %rcx
movq (%rcx), %rcx
cmpq %rcx, %rax
je 0x203a
movq %rcx, 0x58(%r13)
leaq -0x50(%rbp), %rdi
callq 0x2508
leaq -0x100(%rbp), %rdi
callq 0x2508
leaq -0x80(%rbp), %rdi
callq 0x2914
leaq -0x98(%rbp), %rdi
callq 0x237c
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x20c8
movq %rax, %rbx
jmp 0x2111
movq %rax, %rbx
pushq $0x48
popq %r14
leaq (%r14,%rbp), %rdi
addq $-0x100, %rdi
callq 0x2914
addq $-0x18, %r14
cmpq $-0x18, %r14
jne 0x2087
jmp 0x211d
jmp 0x20a7
jmp 0x20a7
movq %rax, %rbx
addq $-0x18, %r15
movq %r15, %rdi
callq 0x2914
cmpq %r14, %r15
jne 0x20aa
jmp 0x211d
movq %rax, %rbx
jmp 0x211d
jmp 0x20f4
jmp 0x20f4
jmp 0x20c8
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x2508
leaq -0x100(%rbp), %rdi
callq 0x2508
jmp 0x2108
jmp 0x20f4
jmp 0x20f4
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x2103
jmp 0x20f4
movq %rax, %rbx
jmp 0x2108
movq %rax, %rbx
leaq -0x138(%rbp), %rdi
callq 0x2914
leaq -0x80(%rbp), %rdi
callq 0x2914
leaq -0x98(%rbp), %rdi
callq 0x237c
movq %rbx, %rdi
callq 0x1180
nop