// File: /workspace/github_cpp_makefile_star2_O1/xbai0624[P]dnn/src/Neuron.cpp
// Function: Neuron::UpdateSigmaPrime(int)
void Neuron::UpdateSigmaPrime(int sample_index)
{
    // update sigma^prime
    //if(__sigmaPrime.size() != __z.size()-1) 
    //{
    //std::cout<<"Error: computing sigma^prime needs z computed first."<<std::endl;
    //exit(0);
    //}
    //if(__sigmaPrime.size() != __a.size()-1) 
    //{
    //std::cout<<"Error: computing sigma^prime needs a computed first."<<std::endl;
    //exit(0);
    //}

    //double a = __a.back();
    //double z = __z.back();
    double a = __a[sample_index];
    double z = __z[sample_index];
    double sigma_prime = -100; // theoretically, it must between [0, 1]

    if(__funcType == ActuationFuncType::Sigmoid || __funcType == ActuationFuncType::SoftMax) 
    {
        // the \partial a over \partial z is the same for sigmoid and softmax
        // one can easily prove it
        double diff = 1. - a;
        if( diff < 1e-10) diff = 0.; // to get rid of float number precision issues
        sigma_prime = diff*a;
    }
    else if(__funcType == ActuationFuncType::Tanh) 
    {
        sigma_prime = ( 2. / (exp(z) + exp(-z)) ) * ( 2. / (exp(z) + exp(-z)) );
    }
    else if(__funcType == ActuationFuncType::Relu) 
    {
        if( z > 0) sigma_prime = 1.;
        else sigma_prime = 0;
    }
    else
        std::cout<<"Error: unsupported actuation function type in direvative."<<std::endl;

    if(sigma_prime < 0.)
    {
        std::cout<<"Error: Neuron::UpdateSigmaPrime: sigma_prime<0? something wrong."
            <<endl;
        std::cout<<"    Actuation function type: "<<__funcType<<std::endl;
        std::cout<<"    Z: "<<z<<std::endl;
        std::cout<<"    a: "<<a<<std::endl;
        std::cout<<"    sigma prime: "<<sigma_prime<<std::endl;
        exit(0);
    }

    //__sigmaPrime.push_back(sigma_prime);
    __sigmaPrime[sample_index] = sigma_prime;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x60, %rsp
movq %rdi, %rbx
movslq %esi, %r15
movq 0x18(%rdi), %rax
movq 0x48(%rdi), %rcx
movsd (%rax,%r15,8), %xmm1
movsd (%rcx,%r15,8), %xmm2
movl 0x84(%rdi), %eax
cmpl $0x2, %eax
jb 0x2051f
je 0x20545
cmpl $0x3, %eax
jne 0x205d5
xorpd %xmm0, %xmm0
cmpltsd %xmm2, %xmm0
movsd 0x706a(%rip), %xmm3     # 0x27580
andpd %xmm0, %xmm3
jmp 0x20637
movsd 0x7059(%rip), %xmm0     # 0x27580
subsd %xmm1, %xmm0
movapd %xmm0, %xmm3
cmpltsd 0x7080(%rip), %xmm3     # 0x275b8
andnpd %xmm0, %xmm3
mulsd %xmm1, %xmm3
jmp 0x20637
movapd %xmm2, %xmm0
movsd %xmm1, 0x8(%rsp)
movapd %xmm2, 0x10(%rsp)
callq 0x43f0
movapd %xmm0, 0x20(%rsp)
movaps 0x6b29(%rip), %xmm0     # 0x27090
xorps 0x10(%rsp), %xmm0
movaps %xmm0, 0x40(%rsp)
callq 0x43f0
movaps %xmm0, 0x50(%rsp)
movaps 0x10(%rsp), %xmm0
callq 0x43f0
movaps %xmm0, 0x30(%rsp)
movapd 0x40(%rsp), %xmm0
callq 0x43f0
movapd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
movapd 0x20(%rsp), %xmm3
unpcklpd 0x30(%rsp), %xmm3       # xmm3 = xmm3[0],mem[0]
movapd 0x50(%rsp), %xmm4
unpcklpd %xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0]
addpd %xmm3, %xmm4
movapd 0xa56d(%rip), %xmm0     # 0x2ab30
divpd %xmm4, %xmm0
movapd %xmm0, %xmm3
unpckhpd %xmm0, %xmm3            # xmm3 = xmm3[1],xmm0[1]
mulsd %xmm0, %xmm3
jmp 0x20637
movq 0x169fc(%rip), %r14     # 0x36fd8
leaq 0xa88a(%rip), %rsi      # 0x2ae6d
movl $0x39, %edx
movq %r14, %rdi
movsd %xmm1, 0x8(%rsp)
movapd %xmm2, 0x10(%rsp)
callq 0x4280
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x4250
movsbl %al, %esi
movq %r14, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4190
movapd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
movsd 0xa4e9(%rip), %xmm3     # 0x2ab20
xorpd %xmm0, %xmm0
ucomisd %xmm3, %xmm0
ja 0x20655
movq 0x60(%rbx), %rax
movsd %xmm3, (%rax,%r15,8)
addq $0x60, %rsp
popq %rbx
popq %r14
popq %r15
retq
addq $0x84, %rbx
movq 0x16975(%rip), %r14     # 0x36fd8
leaq 0xa83d(%rip), %rsi      # 0x2aea7
movq %r14, %rdi
movsd %xmm1, 0x8(%rsp)
movapd %xmm2, 0x10(%rsp)
movapd %xmm3, 0x20(%rsp)
callq 0x4260
movq %rax, %rdi
callq 0x4100
leaq 0xa855(%rip), %rsi      # 0x2aee8
movq %r14, %rdi
callq 0x4260
movq %rax, %rdi
movq %rbx, %rsi
callq 0x1a19f
movq %rax, %rdi
callq 0x4100
leaq 0xa851(%rip), %rsi      # 0x2af06
movq %r14, %rdi
callq 0x4260
movq %rax, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x4420
movq %rax, %rdi
callq 0x4100
leaq 0xa835(%rip), %rsi      # 0x2af0e
movq %r14, %rdi
callq 0x4260
movq %rax, %rdi
movsd 0x8(%rsp), %xmm0
callq 0x4420
movq %rax, %rdi
callq 0x4100
leaq 0xa818(%rip), %rsi      # 0x2af16
movq %r14, %rdi
callq 0x4260
movq %rax, %rdi
movaps 0x20(%rsp), %xmm0
callq 0x4420
movq %rax, %rdi
callq 0x4100
xorl %edi, %edi
callq 0x4290