// File: /workspace/github_c_makefile_star2_O1/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), %r15
movslq 0x10(%rdi), %rbp
movslq 0xc(%rdi), %rax
movq %rax, (%rsp)
xorl %ebx, %ebx
movq (%r14), %rax
movl (%rax,%rbx,2), %edi
movsd (%r13,%rbx), %xmm0
callq 0x2900
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%rbx,2)
addq $0x8, %rbx
cmpq $0x8, %rbx
je 0x29a9
addq %r15, %rbp
xorl %ebx, %ebx
movq (%r14), %rax
movl 0x20(%rax,%rbx,2), %edi
movsd (%r12,%rbx), %xmm0
callq 0x2900
movq (%r14), %rax
movsd %xmm0, 0x28(%rax,%rbx,2)
addq $0x8, %rbx
cmpq $0x10, %rbx
jne 0x29d3
addq (%rsp), %rbp
movq 0x8(%rsp), %r15
movl (%r15), %eax
movl $0x4, %ebx
testb $0x1, %al
je 0x2a66
xorpd %xmm0, %xmm0
xorl %ecx, %ecx
movsd (%r13,%rcx,8), %xmm1
subsd (%r12,%rcx,8), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm1, %xmm0
incq %rcx
cmpq $0x1, %rcx
je 0x2a13
movq (%r14), %rcx
movl 0x40(%rcx), %r12d
testb $0x2, %al
jne 0x2a51
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2a4c
sqrtsd %xmm0, %xmm0
jmp 0x2a51
callq 0x1180
movl %r12d, %edi
callq 0x2900
movq (%r14), %rax
movsd %xmm0, 0x48(%rax)
movl $0x5, %ebx
testb $0x4, (%r15)
je 0x2a8b
movq (%r14), %rax
shll $0x4, %ebx
movl (%rax,%rbx), %edi
movsd 0x45c3(%rip), %xmm0     # 0x7040
callq 0x2900
movq (%r14), %rax
movsd %xmm0, 0x8(%rax,%rbx)
movslq 0x8(%r14), %rax
cmpl %ebp, %eax
jge 0x2ab7
movq (%r14), %rcx
movq %rax, %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
addq $0x8, %rcx
movq $0x0, (%rcx)
incq %rax
addq $0x10, %rcx
cmpq %rbp, %rax
jl 0x2aa4
xorl %r12d, %r12d
testb $0x8, (%r15)
je 0x2ac4
movl 0x4c(%r15), %r12d
testl %r12d, %r12d
js 0x2ba2
movslq %ebp, %r15
xorl %r13d, %r13d
movq %rbp, (%rsp)
movslq 0x8(%r14), %rbx
xorpd %xmm1, %xmm1
cmpl %ebp, %ebx
jge 0x2b76
movsd %xmm1, 0x8(%rsp)
movslq 0x20(%r14), %rax
xorpd %xmm0, %xmm0
testq %rax, %rax
jle 0x2b2f
movq 0x18(%r14), %rcx
shlq $0x5, %rax
xorl %edx, %edx
cmpl %ebx, 0x8(%rcx,%rdx)
jne 0x2b26
movsd 0x10(%rcx,%rdx), %xmm1
movq (%r14), %rsi
movslq 0x4(%rcx,%rdx), %rdi
shlq $0x4, %rdi
mulsd 0x8(%rsi,%rdi), %xmm1
addsd %xmm1, %xmm0
addq $0x20, %rdx
cmpq %rdx, %rax
jne 0x2b04
movq (%r14), %rax
movq %rbx, %rbp
shlq $0x4, %rbp
movl (%rax,%rbp), %edi
callq 0x2900
movq (%r14), %rax
movapd %xmm0, %xmm1
subsd 0x8(%rax,%rbp), %xmm1
andpd 0x462a(%rip), %xmm1     # 0x7180
movsd 0x8(%rsp), %xmm2
addsd %xmm1, %xmm2
movapd %xmm2, %xmm1
movsd %xmm0, 0x8(%rax,%rbp)
incq %rbx
cmpq %r15, %rbx
jl 0x2ae7
ucomisd 0x45fa(%rip), %xmm1     # 0x7178
jne 0x2b82
jnp 0x2ba6
testl %r12d, %r12d
sete %al
incl %r13d
cmpl %r12d, %r13d
setl %cl
orb %al, %cl
cmpb $0x1, %cl
movq (%rsp), %rbp
je 0x2ad7
jmp 0x2ba6
xorpd %xmm1, %xmm1
movslq 0xc(%r14), %rax
testq %rax, %rax
movq 0x10(%rsp), %rsi
jle 0x2bdf
movq (%r14), %rcx
movslq 0x8(%r14), %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
addq $0x8, %rcx
shlq $0x3, %rax
xorl %edx, %edx
movsd (%rcx,%rdx,2), %xmm0
movsd %xmm0, (%rsi,%rdx)
addq $0x8, %rdx
cmpq %rdx, %rax
jne 0x2bcc
movapd %xmm1, %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq