// File: /workspace/github_cpp_makefile_star2_O2/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 %r14
pushq %rbx
subq $0x68, %rsp
movq %rdi, %rbx
movslq %esi, %r14
movq 0x18(%rdi), %rax
movq 0x48(%rdi), %rcx
movsd (%rax,%r14,8), %xmm1
movsd (%rcx,%r14,8), %xmm2
movl 0x84(%rdi), %eax
cmpl $0x2, %eax
jb 0x1be57
je 0x1be7d
cmpl $0x3, %eax
jne 0x1bf27
xorpd %xmm0, %xmm0
cmpltsd %xmm2, %xmm0
movsd 0x56c2(%rip), %xmm3     # 0x21510
andpd %xmm0, %xmm3
jmp 0x1bf15
movsd 0x56b1(%rip), %xmm0     # 0x21510
subsd %xmm1, %xmm0
movapd %xmm0, %xmm3
cmpltsd 0x56d8(%rip), %xmm3     # 0x21548
andnpd %xmm0, %xmm3
mulsd %xmm1, %xmm3
jmp 0x1bf0b
movapd %xmm2, %xmm0
movsd %xmm1, 0x8(%rsp)
movapd %xmm2, 0x10(%rsp)
callq 0x43c0
movapd %xmm0, 0x20(%rsp)
movaps 0x51d1(%rip), %xmm0     # 0x21070
xorps 0x10(%rsp), %xmm0
movaps %xmm0, 0x40(%rsp)
callq 0x43c0
movaps %xmm0, 0x50(%rsp)
movaps 0x10(%rsp), %xmm0
callq 0x43c0
movaps %xmm0, 0x30(%rsp)
movapd 0x40(%rsp), %xmm0
callq 0x43c0
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 0x8bb5(%rip), %xmm0     # 0x24ab0
divpd %xmm4, %xmm0
movapd %xmm0, %xmm3
unpckhpd %xmm0, %xmm3            # xmm3 = xmm3[1],xmm0[1]
mulsd %xmm0, %xmm3
xorpd %xmm0, %xmm0
ucomisd %xmm3, %xmm0
ja 0x1bf62
movq 0x60(%rbx), %rax
movsd %xmm3, (%rax,%r14,8)
addq $0x68, %rsp
popq %rbx
popq %r14
retq
movq 0x170aa(%rip), %rdi     # 0x32fd8
leaq 0x8ea8(%rip), %rsi      # 0x24ddd
movsd %xmm1, 0x8(%rsp)
movapd %xmm2, 0x10(%rsp)
callq 0x4240
movq %rax, %rdi
callq 0x4130
movapd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
movsd 0x8b26(%rip), %xmm3     # 0x24a88
movapd %xmm2, 0x10(%rsp)
movsd %xmm1, 0x8(%rsp)
movapd %xmm3, 0x20(%rsp)
addq $0x84, %rbx
movq 0x17056(%rip), %r14     # 0x32fd8
leaq 0x8e8e(%rip), %rsi      # 0x24e17
movq %r14, %rdi
callq 0x4240
movq %rax, %rdi
callq 0x4130
leaq 0x8eb8(%rip), %rsi      # 0x24e58
movq %r14, %rdi
callq 0x4240
movq %rax, %rdi
movq %rbx, %rsi
callq 0x17307
movq %rax, %rdi
callq 0x4130
leaq 0x8eb4(%rip), %rsi      # 0x24e76
movq %r14, %rdi
callq 0x4240
movq %rax, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x43d0
movq %rax, %rdi
callq 0x4130
leaq 0x8e98(%rip), %rsi      # 0x24e7e
movq %r14, %rdi
callq 0x4240
movq %rax, %rdi
movsd 0x8(%rsp), %xmm0
callq 0x43d0
movq %rax, %rdi
callq 0x4130
leaq 0x8e7b(%rip), %rsi      # 0x24e86
movq %r14, %rdi
callq 0x4240
movq %rax, %rdi
movaps 0x20(%rsp), %xmm0
callq 0x43d0
movq %rax, %rdi
callq 0x4130
xorl %edi, %edi
callq 0x4260
nop