// File: /workspace/github_cpp_makefile_star2_O2/gkosae[P]ArduinoNeuralNet/neuralnet.cpp
// Function: NeuralNet::backpropagateErrors()
void NeuralNet::backpropagateErrors() {
    // Calculate delta (backpropagating error) for output layer
    unsigned short output_layer_size = layers.back().size();

    for(auto i = 0; i < output_layer_size; ++i) {

        layers.back().neurons.at(i).delta = (actual_output.at(current_sample).at(i) -
                                             expected_output.at(current_sample).at(i)) *
                                             layers.back().neurons.at(i).sigmoidPrime();
    }

    unsigned short number_of_hidden_layers = layers.size() - 2;

    for(auto i = number_of_hidden_layers; i > 0 ; --i) {

      unsigned short current_layer_size = layers.at(i).size();
      unsigned short next_layer_size = layers.at(i+1).size();

      for(auto j = 0; j < current_layer_size; ++j) {

          double delta = 0;
          for(auto k = 0; k <  next_layer_size; k++) {
              delta += (layers.at(i+1).neurons.at(k).delta *
                        layers.at(i+1).neurons.at(k).weights.at(j) *
                        layers.at(i).neurons.at(j).sigmoidPrime());
          }

          layers.at(i).neurons.at(j).delta = delta;
      }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r14
movq 0x20(%rdi), %rax
movl -0x10(%rax), %ecx
subl -0x18(%rax), %ecx
shrl $0x6, %ecx
movzwl %cx, %r13d
leaq 0x30(%rdi), %rbx
leaq 0x48(%rdi), %r15
xorl %r12d, %r12d
cmpq %r12, %r13
je 0x35b9
movl 0x78(%r14), %esi
movq %rbx, %rdi
callq 0x476a
movq %rax, %rdi
movq %r12, %rsi
callq 0x264c
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x78(%r14), %esi
movq %r15, %rdi
callq 0x476a
movq %rax, %rdi
movq %r12, %rsi
callq 0x264c
movsd 0x8(%rsp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x20(%r14), %rdi
addq $-0x18, %rdi
movq %r12, %rsi
callq 0x479e
movq %rax, %rdi
callq 0x47de
mulsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x20(%r14), %rdi
addq $-0x18, %rdi
movq %r12, %rsi
callq 0x479e
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x38(%rax)
incq %r12
jmp 0x3521
leaq 0x18(%r14), %rbx
movq 0x20(%r14), %rax
subq 0x18(%r14), %rax
pushq $0x30
popq %rcx
cqto
idivq %rcx
addl $-0x2, %eax
movl %eax, %ecx
subw $0x1, %cx
jb 0x370c
movw %cx, 0x16(%rsp)
movzwl %ax, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x47c0
movl 0x20(%rax), %r12d
subl 0x18(%rax), %r12d
shrl $0x6, %r12d
leaq 0x1(%r14), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x47c0
movl 0x20(%rax), %ebp
subl 0x18(%rax), %ebp
shrl $0x6, %ebp
movl $0xffff, %eax           # imm = 0xFFFF
andl %eax, %r12d
movq %r12, 0x20(%rsp)
andl %eax, %ebp
xorl %r12d, %r12d
cmpq 0x20(%rsp), %r12
je 0x3700
xorpd %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
xorl %r13d, %r13d
movq %rbx, %rdi
cmpq %r13, %rbp
je 0x36d9
movq %r15, %rsi
callq 0x47c0
leaq 0x18(%rax), %rdi
movq %r13, %rsi
callq 0x479e
movsd 0x38(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x47c0
leaq 0x18(%rax), %rdi
movq %r13, %rsi
callq 0x479e
leaq 0x20(%rax), %rdi
movq %r12, %rsi
callq 0x264c
movsd 0x8(%rsp), %xmm0
mulsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x47c0
leaq 0x18(%rax), %rdi
movq %r12, %rsi
callq 0x479e
movq %rax, %rdi
callq 0x47de
mulsd 0x8(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
incq %r13
jmp 0x363e
movq %r14, %rsi
callq 0x47c0
leaq 0x18(%rax), %rdi
movq %r12, %rsi
callq 0x479e
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x38(%rax)
incq %r12
jmp 0x3626
movzwl 0x16(%rsp), %ecx
movl %ecx, %eax
jmp 0x35d2
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop