# Path: deeppy/expr/base.py
# class UnaryElementWise(Unary):
#     def setup(self):
#         self.shape = self.x.shape
#         self.array = ca.zeros(self.shape)
#         self.grad_array = ca.zeros(self.shape)


import cudarray as ca
from ..base import UnaryElementWise

    def bprop(self):
        self.x.grad_array = ca.less(self.x.array, 0) * self.a
        pos = ca.nnet.relu_d(self.x.array)
        self.x.grad_array += pos
        self.x.grad_array *= self.grad_array


class ReLU(UnaryElementWise):
    def fprop(self):
        ca.nnet.relu(self.x.array, self.array)

    def bprop(self):
        ca.nnet.relu_d(self.x.array, out=self.x.grad_array)
        self.x.grad_array *= self.grad_array


class Sigmoid(UnaryElementWise):
    def fprop(self):
        ca.nnet.sigmoid(self.x.array, self.array)

    def bprop(self):
        ca.nnet.sigmoid_d(self.x.array, out=self.x.grad_array)
        self.x.grad_array *= self.grad_array


class Softmax(UnaryElementWise):
    def fprop(self):
        # e_i = exp(x_i - max(x))
        # y = e_i / sum(e)

# Path: deeppy/expr/base.py
# class UnaryElementWise(Unary):
#     def setup(self):
#         self.shape = self.x.shape
#         self.array = ca.zeros(self.shape)
#         self.grad_array = ca.zeros(self.shape)


# Path: deeppy/expr/nnet/activation.py
import cudarray as ca
from ..base import UnaryElementWise


    def bprop(self):
        self.x.grad_array = ca.less(self.x.array, 0) * self.a
        pos = ca.nnet.relu_d(self.x.array)
        self.x.grad_array += pos
        self.x.grad_array *= self.grad_array


class ReLU(UnaryElementWise):
    def fprop(self):
        ca.nnet.relu(self.x.array, self.array)

    def bprop(self):
        ca.nnet.relu_d(self.x.array, out=self.x.grad_array)
        self.x.grad_array *= self.grad_array


class Sigmoid(UnaryElementWise):
    def fprop(self):
        ca.nnet.sigmoid(self.x.array, self.array)

    def bprop(self):
        ca.nnet.sigmoid_d(self.x.array, out=self.x.grad_array)
        self.x.grad_array *= self.grad_array


class Softmax(UnaryElementWise):
    def fprop(self):
        # e_i = exp(x_i - max(x))
        # y = e_i / sum(e)

        tmp1 = ca.amax(self.x.array, axis=1, keepdims=True)