// File: /workspace/github_cpp_makefile_star2_O1/xbai0624[P]dnn/src/Neuron.cpp
// Function: Neuron::UpdateDeltaOutputLayer(int)
void Neuron::UpdateDeltaOutputLayer(int sample_index)
{
    // back propagation delta for output layer
    if(__sigmaPrime.size() <= 0) 
    {
        std::cout<<"Error: Neuron::UpdateDeltaOutputLayer() computing delta needs sigma^prime computed first."<<std::endl;
        std::cout<<"        "<<__delta.size()<<" deltas, "<<__sigmaPrime.size()<<" sigma^primes"<<endl;
        exit(0);
    }
    assert(__a.size() == __sigmaPrime.size()); // make sure all have been updated
    auto & labels = __layer->GetDataInterface()->GetCurrentBatchLabel();
    assert(labels.size() == __a.size()); // make sure all samples have been processed

    //size_t batch_size = __a.size();

    // check
    auto dim = labels[0].Dimension(); // dim.first is neuron row number, dim.second is neuron collum number
    assert(__coord.i < dim.first);
    assert(dim.second == 1);
    //cout<<"neuron coord: "<<__coord<<endl;
    //assert(__coord.j == 0);

    //cout<<"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<<endl;
    //cout<<"sample index: "<<sample_index<<endl;
    //cout<<"neuron id: "<<__neuron_id<<endl;
    //Print();

    auto cost_func_type = __layer->GetCostFuncType(); // for $\partial C over \partial a$

    // label for current sample
    Matrix & label_for_current_sample = labels[sample_index]; 
    //cout<<label_for_current_sample<<endl;
    // expected value for current sample current neuron
    float y_i = label_for_current_sample[__coord.i][0];
    //cout<<"---"<<y_i<<endl;

    // a value for current sample
    float a_i = __a[sample_index];
    //cout<<a_i<<endl;

    // sigma^\prime for current sample
    //float sigma_prime_i = __sigmaPrime[sample_index]; // obsolete
    //cout<<"---"<<sigma_prime_i<<endl;

    // solve for dC/da, which is dependent on the type of cost function
    float delta = 0;
    if(cost_func_type == CostFuncType::cross_entropy)
    {
        delta = a_i  - y_i;
    }
    else 
    {
        // other types of cost function: to be implemented
        delta = a_i - y_i; 
    }

    // save delta for this batch this neuron
    __delta[sample_index] = delta;
    //cout<<"here..."<<endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x68(%rdi), %rax
subq 0x60(%rdi), %rax
je 0x21084
movq 0x20(%rbx), %rcx
subq 0x18(%rbx), %rcx
cmpq %rax, %rcx
jne 0x21106
movl %esi, %ebp
movq 0x78(%rbx), %rdi
movq (%rdi), %rax
callq *0x2b8(%rax)
movq %rax, %r14
movq 0x28(%rax), %rdi
movq 0x30(%rax), %rax
subq %rdi, %rax
sarq $0x3, %rax
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rcx
movq 0x20(%rbx), %rax
subq 0x18(%rbx), %rax
sarq $0x3, %rax
cmpq %rax, %rcx
jne 0x21125
callq 0x1ac7c
cmpq %rax, 0x88(%rbx)
jae 0x21144
cmpq $0x1, %rdx
jne 0x21163
movq 0x78(%rbx), %rdi
movq (%rdi), %rax
callq *0x2a8(%rax)
movslq %ebp, %r15
leaq (%r15,%r15,2), %rdi
shlq $0x3, %rdi
addq 0x28(%r14), %rdi
movq 0x88(%rbx), %rsi
callq 0x1ae76
movq (%rax), %rax
cvtsd2ss (%rax), %xmm0
movq 0x18(%rbx), %rax
cvtsd2ss (%rax,%r15,8), %xmm1
movq 0x30(%rbx), %rax
subss %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtss2sd %xmm1, %xmm0
movsd %xmm0, (%rax,%r15,8)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x15f4d(%rip), %r14     # 0x36fd8
leaq 0x9e96(%rip), %rsi      # 0x2af28
movq %r14, %rdi
callq 0x4260
movq %rax, %rdi
callq 0x4100
leaq 0x9ed9(%rip), %rsi      # 0x2af82
movq %r14, %rdi
callq 0x4260
movq 0x38(%rbx), %rsi
subq 0x30(%rbx), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x4090
leaq 0x9ebf(%rip), %rsi      # 0x2af8b
movq %rax, %rdi
callq 0x4260
movq 0x68(%rbx), %rsi
subq 0x60(%rbx), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x4090
leaq 0x9ea6(%rip), %rsi      # 0x2af95
movq %rax, %rdi
callq 0x4260
movq %rax, %rdi
callq 0x4100
xorl %edi, %edi
callq 0x4290
leaq 0x9e96(%rip), %rdi      # 0x2afa3
leaq 0x9a82(%rip), %rsi      # 0x2ab96
leaq 0x9eaa(%rip), %rcx      # 0x2afc5
movl $0x1df, %edx            # imm = 0x1DF
callq 0x4160
leaq 0x9ec2(%rip), %rdi      # 0x2afee
leaq 0x9a63(%rip), %rsi      # 0x2ab96
leaq 0x9e8b(%rip), %rcx      # 0x2afc5
movl $0x1e1, %edx            # imm = 0x1E1
callq 0x4160
leaq 0x9ebf(%rip), %rdi      # 0x2b00a
leaq 0x9a44(%rip), %rsi      # 0x2ab96
leaq 0x9e6c(%rip), %rcx      # 0x2afc5
movl $0x1e7, %edx            # imm = 0x1E7
callq 0x4160
leaq 0x6f50(%rip), %rdi      # 0x280ba
leaq 0x9a25(%rip), %rsi      # 0x2ab96
leaq 0x9e4d(%rip), %rcx      # 0x2afc5
movl $0x1e8, %edx            # imm = 0x1E8
callq 0x4160