# 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


def clip(a, a_min, a_max):
    return Clip(a_min, a_max)(a)


def absolute(x):
    return Absolute()(x)


fabs = absolute


def negative(x):
    return Negative()(x)


def exp(x):
    return Exp()(x)


def log(x):
    return Log()(x)


def add(lhs, rhs):
    return Add()(lhs, rhs)


def subtract(lhs, rhs):

# 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



def clip(a, a_min, a_max):
    return Clip(a_min, a_max)(a)


def absolute(x):
    return Absolute()(x)


fabs = absolute


def negative(x):
    return Negative()(x)


def exp(x):
    return Exp()(x)


def log(x):
    return Log()(x)


def add(lhs, rhs):
    return Add()(lhs, rhs)


def subtract(lhs, rhs):

    return Subtract()(lhs, rhs)