# 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)
# 
# class BinaryElementWise(Binary):
#     def __call__(self, lhs, rhs):
#         super(BinaryElementWise, self).__call__(lhs, rhs)
#         self.lhs_orig = self.lhs
#         self.rhs_orig = self.rhs
#         return self
# 
#     def setup(self):
#         self.shape = np.add(np.zeros(self.lhs.shape),
#                             np.zeros(self.rhs.shape)).shape
#         size = np.prod(self.shape)
#         if self.lhs_orig.bpropable and size > self.lhs_orig.array.size:
#             self.lhs = Broadcast(self.lhs_orig.shape,
#                                  self.shape)(self.lhs_orig)
#             self.inputs[0] = self.lhs
#             self.lhs.setup()
#         if self.rhs_orig.bpropable and size > self.rhs_orig.array.size:
#             self.rhs = Broadcast(self.rhs_orig.shape,
#                                  self.shape)(self.rhs_orig)
#             self.inputs[1] = self.rhs
#             self.rhs.setup()
#         self.array = ca.zeros(self.shape)
#         self.grad_array = ca.zeros(self.shape)


import numpy as np
import cudarray as ca
from .base import UnaryElementWise, BinaryElementWise
        self.x.grad_array -= 1.0
        ca.multiply(self.x.grad_array, self.grad_array, out=self.x.grad_array)


class Clip(UnaryElementWise):
    def __init__(self, a_min, a_max, keepgrads=True):
        self.a_min = a_min
        self.a_max = a_max
        self.keepgrads = keepgrads

    def fprop(self):
        ca.clip(self.x.array, self.a_min, self.a_max, out=self.array)

    def bprop(self):
        if self.keepgrads:
            self.x.grad_array = self.grad_array
        else:
            ca.multiply(self.grad_array, self.x.array > self.a_min,
                        self.x.grad_array)
            self.x.grad_array *= self.x.array < self.a_max


class Negative(UnaryElementWise):
    def fprop(self):
        ca.negative(self.x.array, out=self.array)

    def bprop(self):
        ca.negative(self.grad_array, out=self.x.grad_array)



# 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)
# 
# class BinaryElementWise(Binary):
#     def __call__(self, lhs, rhs):
#         super(BinaryElementWise, self).__call__(lhs, rhs)
#         self.lhs_orig = self.lhs
#         self.rhs_orig = self.rhs
#         return self
# 
#     def setup(self):
#         self.shape = np.add(np.zeros(self.lhs.shape),
#                             np.zeros(self.rhs.shape)).shape
#         size = np.prod(self.shape)
#         if self.lhs_orig.bpropable and size > self.lhs_orig.array.size:
#             self.lhs = Broadcast(self.lhs_orig.shape,
#                                  self.shape)(self.lhs_orig)
#             self.inputs[0] = self.lhs
#             self.lhs.setup()
#         if self.rhs_orig.bpropable and size > self.rhs_orig.array.size:
#             self.rhs = Broadcast(self.rhs_orig.shape,
#                                  self.shape)(self.rhs_orig)
#             self.inputs[1] = self.rhs
#             self.rhs.setup()
#         self.array = ca.zeros(self.shape)
#         self.grad_array = ca.zeros(self.shape)


# Path: deeppy/expr/elementwise.py
import numpy as np
import cudarray as ca
from .base import UnaryElementWise, BinaryElementWise

        self.x.grad_array -= 1.0
        ca.multiply(self.x.grad_array, self.grad_array, out=self.x.grad_array)


class Clip(UnaryElementWise):
    def __init__(self, a_min, a_max, keepgrads=True):
        self.a_min = a_min
        self.a_max = a_max
        self.keepgrads = keepgrads

    def fprop(self):
        ca.clip(self.x.array, self.a_min, self.a_max, out=self.array)

    def bprop(self):
        if self.keepgrads:
            self.x.grad_array = self.grad_array
        else:
            ca.multiply(self.grad_array, self.x.array > self.a_min,
                        self.x.grad_array)
            self.x.grad_array *= self.x.array < self.a_max


class Negative(UnaryElementWise):
    def fprop(self):
        ca.negative(self.x.array, out=self.array)

    def bprop(self):
        ca.negative(self.grad_array, out=self.x.grad_array)



class Log(UnaryElementWise):