// File: wkohlenberg[P]simple_NN/src/main.cpp
// Function: Net::backPropagation(std::vector<double, std::allocator<double>> const&)
void Net::backPropagation(const vector<double> &target)
{
  calcTotalError(target);
  averageError();

  for (unsigned n = 0; n < m_layers.back().size()-1; n++)
  {
    Layer &prevLayer = m_layers[1];
    m_layers.back()[n].calculateOutputGradient(target[n], prevLayer);
  }

  // Calculate the derivative of the hidden neurons
  Layer &hiddenLayer = m_layers[m_layers.size()-2];
  for (unsigned n = 0; n < m_layers[1].size()-1; n++) // Exclude the bias node
  {
    hiddenLayer[n].calculateHiddenGradient(m_layers.back(), m_layers[0]);
  }

  for (unsigned n = 0; n < m_layers.size()-1; n++)  // No output layer opdate...
  {
    for (unsigned i = 0; i < m_layers[n].size()-1; i++) // Exclude bias nodes
    {
      m_layers[n][i].updateWeights();
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x40(%rbp)
movq -0x10(%rbp), %rsi
callq 0x4560
movq -0x40(%rbp), %rdi
callq 0x40f0
movl $0x0, -0x14(%rbp)
movq -0x40(%rbp), %rdi
movl -0x14(%rbp), %eax
movq %rax, -0x48(%rbp)
addq $0x10, %rdi
callq 0x54e0
movq %rax, %rdi
callq 0x51d0
movq %rax, %rcx
movq -0x48(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x43f1
movq -0x40(%rbp), %rdi
addq $0x10, %rdi
movl $0x1, %esi
callq 0x5550
movq -0x40(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x10, %rdi
callq 0x54e0
movq %rax, %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
callq 0x51f0
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %eax
movl %eax, %esi
callq 0x5590
movq -0x50(%rbp), %rdi
movsd (%rax), %xmm0
movq -0x20(%rbp), %rsi
callq 0x3b40
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x4364
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x10, %rax
movq %rax, -0x58(%rbp)
addq $0x10, %rdi
callq 0x55b0
movq -0x58(%rbp), %rdi
movq %rax, %rsi
subq $0x2, %rsi
callq 0x5550
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x40(%rbp), %rdi
movl -0x2c(%rbp), %eax
movq %rax, -0x60(%rbp)
addq $0x10, %rdi
movl $0x1, %esi
callq 0x5550
movq %rax, %rdi
callq 0x51d0
movq %rax, %rcx
movq -0x60(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x44a4
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %esi
callq 0x51f0
movq -0x40(%rbp), %rdi
movq %rax, -0x70(%rbp)
addq $0x10, %rdi
callq 0x54e0
movq -0x40(%rbp), %rdi
movq %rax, -0x68(%rbp)
addq $0x10, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5550
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq %rax, %rdx
callq 0x3c70
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x4424
movl $0x0, -0x30(%rbp)
movq -0x40(%rbp), %rdi
movl -0x30(%rbp), %eax
movq %rax, -0x78(%rbp)
addq $0x10, %rdi
callq 0x55b0
movq %rax, %rcx
movq -0x78(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x4549
movl $0x0, -0x34(%rbp)
movq -0x40(%rbp), %rdi
movl -0x34(%rbp), %eax
movq %rax, -0x80(%rbp)
addq $0x10, %rdi
movl -0x30(%rbp), %eax
movl %eax, %esi
callq 0x5550
movq %rax, %rdi
callq 0x51d0
movq %rax, %rcx
movq -0x80(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x4539
movq -0x40(%rbp), %rdi
addq $0x10, %rdi
movl -0x30(%rbp), %eax
movl %eax, %esi
callq 0x5550
movq %rax, %rdi
movl -0x34(%rbp), %eax
movl %eax, %esi
callq 0x51f0
movq %rax, %rdi
callq 0x39d0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x44d6
jmp 0x453b
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x44ab
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)