// File: theolepage[P]prophecy/src/layer_implem/dense_layer.hh
// Function: DenseLayer<float>::backpropagation(Matrix<float> const*)
virtual void backpropagation(const Matrix<T>* const y)
    {
        if (this->prev_.expired()) // If we reach InputLayer
            return;

        auto next = std::dynamic_pointer_cast<HiddenLayer<T>>(this->next_);

        this->last_z_.map_inplace(this->activation_.fd_); // Avoid creating a new matrix below
        if (y != nullptr)
        {
            this->last_a_ -= *y; // Same
            this->last_a_.multiply_inplace(this->last_z_); // Same
            this->delta_ = this->last_a_;
        }
        else
        {
            this->last_z_.multiply_inplace(
                Matrix<T>::dot(next->get_weights(), next->get_delta(), transpose::LEFT)); // Same
            this->delta_ = this->last_z_;
        }

        this->delta_biases_ += this->delta_;
        this->delta_weights_ += Matrix<T>::dot(
                                    this->delta_, this->prev_.lock()->get_last_a(), transpose::RIGHT);
        this->prev_.lock()->backpropagation(nullptr);
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xb8(%rbp)
addq $0x70, %rdi
callq 0x8950
testb $0x1, %al
jne 0x77ed
jmp 0x77f2
jmp 0x7a7f
movq -0xb8(%rbp), %rsi
subq $-0x80, %rsi
leaq -0x20(%rbp), %rdi
callq 0x8980
movq -0xb8(%rbp), %rsi
movq %rsi, %rax
addq $0x30, %rax
movq %rax, -0xc0(%rbp)
addq $0x130, %rsi            # imm = 0x130
leaq -0x40(%rbp), %rdi
callq 0x7ff0
jmp 0x782d
movq -0xc0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x8a10
jmp 0x783f
leaq -0x40(%rbp), %rdi
callq 0x5070
cmpq $0x0, -0x10(%rbp)
je 0x78c5
movq -0xb8(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x10, %rdi
callq 0x8ad0
jmp 0x7865
movq -0xb8(%rbp), %rsi
movq %rsi, %rdi
addq $0x10, %rdi
addq $0x30, %rsi
callq 0x8be0
jmp 0x787e
movq -0xb8(%rbp), %rdi
movq %rdi, %rsi
addq $0x10, %rsi
addq $0x50, %rdi
callq 0x7220
jmp 0x7974
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x7ad4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x5070
jmp 0x7ad4
movq -0xb8(%rbp), %rax
addq $0x30, %rax
movq %rax, -0xd0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x8cb0
movq %rax, %rdi
callq 0x8cd0
movq %rax, -0xc8(%rbp)
jmp 0x78f1
leaq -0x20(%rbp), %rdi
callq 0x8cb0
movq %rax, %rdi
callq 0x8cf0
movq %rax, -0xd8(%rbp)
jmp 0x790b
movq -0xd8(%rbp), %rdx
movq -0xc8(%rbp), %rsi
leaq -0x70(%rbp), %rdi
xorl %ecx, %ecx
callq 0x8390
jmp 0x7926
movq -0xd0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x8be0
jmp 0x7938
leaq -0x70(%rbp), %rdi
callq 0x34d0
movq -0xb8(%rbp), %rdi
movq %rdi, %rsi
addq $0x30, %rsi
addq $0x50, %rdi
callq 0x7220
jmp 0x7974
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x34d0
jmp 0x7ad4
movq -0xb8(%rbp), %rdi
movq %rdi, %rsi
addq $0x50, %rsi
addq $0xf0, %rdi
callq 0x8130
jmp 0x7990
movq -0xb8(%rbp), %rsi
movq %rsi, %rax
addq $0x50, %rax
movq %rax, -0xf0(%rbp)
addq $0x70, %rsi
leaq -0xa0(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x8d10
movq -0xe8(%rbp), %rdi
callq 0x7270
movq %rax, %rdi
callq 0x8d40
movq %rax, -0xe0(%rbp)
jmp 0x79d9
movq -0xe0(%rbp), %rdx
movq -0xf0(%rbp), %rsi
leaq -0x90(%rbp), %rdi
movl $0x1, %ecx
callq 0x8390
jmp 0x79fa
movq -0xb8(%rbp), %rdi
addq $0xd0, %rdi
leaq -0x90(%rbp), %rsi
callq 0x8130
jmp 0x7a16
leaq -0x90(%rbp), %rdi
callq 0x34d0
leaq -0xa0(%rbp), %rdi
callq 0x5270
movq -0xb8(%rbp), %rsi
addq $0x70, %rsi
leaq -0xb0(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x8d10
movq -0xf8(%rbp), %rdi
callq 0x7270
movq %rax, %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %ecx, %ecx
movl %ecx, %esi
callq *%rax
jmp 0x7a6a
leaq -0xb0(%rbp), %rdi
callq 0x5270
leaq -0x20(%rbp), %rdi
callq 0x8d60
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x7aae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x34d0
leaq -0xa0(%rbp), %rdi
callq 0x5270
jmp 0x7ad4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x5270
leaq -0x20(%rbp), %rdi
callq 0x8d60
movq -0x48(%rbp), %rdi
callq 0x2200
nopw %cs:(%rax,%rax)