// File: /workspace/github_c_makefile_star2_O2/kernfel[P]fNEAT/cppn.c
// Function: read_CPPN
double read_CPPN( CPPN *net, const struct NEAT_Params *params, double *source, double *target, double *output ) {
	int i,j;
	int num_nodes = net->num_inputs+net->num_hidden+net->num_outputs;
	
	// Set input values
	for ( i=0; i<DIMENSIONS; i++ ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, source[i]);
	}
	for ( ; i<2*DIMENSIONS; i++ ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, target[i-DIMENSIONS]);
	}
	if ( params->flags & CFL_USE_DIST ) {
		double d=0.0;
		for ( j=0; j<DIMENSIONS; j++ )
			d += pow(source[j]-target[j], 2);
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, (params->flags & CFL_SQUARE_DIST) ? d : sqrt(d));
		i++;
	}
	if ( params->flags & CFL_USE_BIAS ) {
		net->nodes[i].activation = CPPN_func(net->nodes[i].func, 1.0);
	}
	
	// Flush
	for ( i=net->num_inputs; i<num_nodes; i++ ) {
		net->nodes[i].activation = 0.0;
	}
	
	// Cycle through the net until nothing changes or num_activations is reached
	int k, k_incr, k_max;
	if ( params->flags & CFL_ALLOW_RECURRENCE ) {
		k_incr = 1;
		k_max = params->num_activations;
	} else {
		k_incr = 1;
		k_max = 0;
	}
	
	double diff=0;
	for ( k=0; !k_max || k<k_max; k+=k_incr ) {
		diff = 0.0;
		
		// Go through each node
		for ( i=net->num_inputs; i<num_nodes; i++ ) {
			double a=0.0;
			
			// Find each of its input links
			for ( j=0; j<net->num_links; j++ ) {
				if ( net->links[j].to == i ) {
					a += net->links[j].weight * net->nodes[net->links[j].from].activation;
				}
			}
			a = CPPN_func( net->nodes[i].func, a );
			diff += fabs( a - net->nodes[i].activation );
			net->nodes[i].activation = a;
		}

		if ( diff == 0.0 )
			break;
	}
	
	for ( i=0; i<net->num_outputs; i++ ) {
		output[i] = net->nodes[i+net->num_inputs].activation;
	}

	return diff;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, 0x10(%rsp)
movq %rcx, %r12
movq %rdx, %r13
movq %rsi, 0x8(%rsp)
movq %rdi, %r14
movslq 0x8(%rdi), %rbx
movslq 0x10(%rdi), %r15
movslq 0xc(%rdi), %rax
movq %rax, (%rsp)
xorl %ebp, %ebp
cmpq $0x10, %rbp
je 0x2774
movq (%r14), %rax
movl (%rax,%rbp,2), %edi
movsd (%r13,%rbp), %xmm0
callq 0x26a4
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%rbp,2)
addq $0x8, %rbp
jmp 0x274d
addq %rbx, %r15
xorl %ebx, %ebx
movq 0x8(%rsp), %rbp
cmpq $0x10, %rbx
je 0x27a5
movq (%r14), %rax
movl 0x20(%rax,%rbx,2), %edi
movsd (%r12,%rbx), %xmm0
callq 0x26a4
movq (%r14), %rax
movsd %xmm0, 0x28(%rax,%rbx,2)
addq $0x8, %rbx
jmp 0x277e
movl (%rbp), %eax
testb $0x1, %al
jne 0x27b5
pushq $0x4
popq %rbx
movq (%rsp), %r12
jmp 0x281e
xorpd %xmm0, %xmm0
xorl %ecx, %ecx
cmpq $0x2, %rcx
je 0x27db
movsd (%r13,%rcx,8), %xmm1
subsd (%r12,%rcx,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rcx
jmp 0x27bb
movq (%r14), %rcx
movl 0x40(%rcx), %ebp
testb $0x2, %al
jne 0x27f9
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movq (%rsp), %r12
jb 0x27ff
sqrtsd %xmm0, %xmm0
jmp 0x2804
movq (%rsp), %r12
jmp 0x2804
callq 0x1180
movl %ebp, %edi
callq 0x26a4
movq (%r14), %rax
movsd %xmm0, 0x48(%rax)
movq 0x8(%rsp), %rbp
movl (%rbp), %eax
pushq $0x5
popq %rbx
testb $0x4, %al
je 0x2841
movq (%r14), %rax
shll $0x4, %ebx
movl (%rax,%rbx), %edi
movsd 0x38dd(%rip), %xmm0     # 0x6110
callq 0x26a4
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%rbx)
addq %r12, %r15
movslq 0x8(%r14), %rax
movq %rax, %rcx
shlq $0x4, %rcx
orq $0x8, %rcx
cmpq %r15, %rax
jge 0x2869
movq (%r14), %rdx
andq $0x0, (%rdx,%rcx)
incq %rax
addq $0x10, %rcx
jmp 0x2853
xorl %r12d, %r12d
testb $0x8, (%rbp)
movl $0x0, (%rsp)
je 0x287f
movl 0x4c(%rbp), %eax
movl %eax, (%rsp)
xorl %r13d, %r13d
xorpd %xmm2, %xmm2
movl (%rsp), %ecx
testl %ecx, %ecx
sete %al
cmpl %ecx, %r13d
setl %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x2951
movslq 0x8(%r14), %rbx
xorpd %xmm2, %xmm2
cmpq %r15, %rbx
jge 0x293a
movl 0x20(%r14), %eax
testl %eax, %eax
cmovlel %r12d, %eax
shlq $0x5, %rax
xorpd %xmm0, %xmm0
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x28f5
movq 0x18(%r14), %rdx
cmpl %ebx, 0x8(%rdx,%rcx)
jne 0x28ef
movsd 0x10(%rdx,%rcx), %xmm1
movq (%r14), %rsi
movslq 0x4(%rdx,%rcx), %rdx
shlq $0x4, %rdx
mulsd 0x8(%rsi,%rdx), %xmm1
addsd %xmm1, %xmm0
addq $0x20, %rcx
jmp 0x28c4
movq (%r14), %rax
movq %rbx, %rbp
shlq $0x4, %rbp
movl (%rax,%rbp), %edi
movsd %xmm2, 0x8(%rsp)
callq 0x26a4
movsd 0x8(%rsp), %xmm2
movq (%r14), %rax
movapd %xmm0, %xmm1
subsd 0x8(%rax,%rbp), %xmm1
andpd 0x3918(%rip), %xmm1     # 0x6240
addsd %xmm1, %xmm2
movsd %xmm0, 0x8(%rax,%rbp)
incq %rbx
jmp 0x28a7
incl %r13d
ucomisd 0x38f3(%rip), %xmm2     # 0x6238
jne 0x2886
jp 0x2886
movl 0xc(%r14), %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
movq 0x10(%rsp), %rdi
cmpq %rcx, %rax
je 0x2984
movq (%r14), %rdx
movslq 0x8(%r14), %rsi
addq %rcx, %rsi
shlq $0x4, %rsi
movsd 0x8(%rdx,%rsi), %xmm0
movsd %xmm0, (%rdi,%rcx,8)
incq %rcx
jmp 0x2961
movapd %xmm2, %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq