# Path: deeppy/base.py
# class CollectionMixin(ParamMixin, PhaseMixin):
#     collection = []
# 
#     @property
#     def params(self):
#         params = []
#         for obj in self.collection:
#             if isinstance(obj, ParamMixin):
#                 params.extend(obj.params)
#         return params
# 
#     @params.setter
#     def params(self, params):
#         idx = 0
#         for obj in self.collection:
#             if isinstance(obj, ParamMixin):
#                 n_params = len(obj.params)
#                 obj.params = params[idx:idx+n_params]
#                 idx += n_params
# 
#     @property
#     def phase(self):
#         return self._phase
# 
#     @phase.setter
#     def phase(self, phase):
#         if self._phase == phase:
#             return
#         self._phase = phase
#         for obj in self.collection:
#             if isinstance(obj, PhaseMixin):
#                 obj.phase = phase
# 
# Path: deeppy/expr/base.py
# class Op(PickleMixin):
#     _pickle_ignore = ['_tmp_', 'array', 'grad_array']
#     inputs = []
#     bpropable = True
#     shape = None
#     array = None
#     grad_array = None
# 
#     def setup(self):
#         pass
# 
#     def fprop(self):
#         raise NotImplementedError()
# 
#     def bprop(self):
#         raise NotImplementedError()
# 
#     def __add__(self, other):
#         return deeppy.expr.Add()(self, other)
# 
#     def __radd__(self, other):
#         return deeppy.expr.Add()(other, self)
# 
#     def __iadd__(self, other):
#         return self.__add__(other)
# 
#     def __sub__(self, other):
#         return deeppy.expr.Subtract()(self, other)
# 
#     def __rsub__(self, other):
#         return deeppy.expr.Subtract()(other, self)
# 
#     def __isub__(self, other):
#         return self.__sub__(other)
# 
#     def __mul__(self, other):
#         return deeppy.expr.Multiply()(self, other)
# 
#     def __rmul__(self, other):
#         return deeppy.expr.Multiply()(other, self)
# 
#     def __imul__(self, other):
#         return self.__mul__(other)
# 
#     def __div__(self, other):
#         return deeppy.expr.Divide()(self, other)
# 
#     def __rdiv__(self, other):
#         return deeppy.expr.Divide()(other, self)
# 
#     def __idiv__(self, other):
#         return self.__div__(other)
# 
#     def __truediv__(self, other):
#         return deeppy.expr.Divide()(self, other)
# 
#     def __rtruediv__(self, other):
#         return deeppy.expr.Divide()(other, self)
# 
#     def __itruediv__(self, other):
#         return self.__truediv__(other)
# 
#     def __pow__(self, other):
#         return deeppy.expr.Power()(self, other)
# 
#     def __rpow__(self, other):
#         return deeppy.expr.Power()(other, self)
# 
#     def __ipow__(self, other):
#         return self.__pow__(other)
# 
#     def __neg__(self):
#         return deeppy.expr.Negative()(self)
# 
#     @property
#     def T(self):
#         return deeppy.expr.transpose(self)


from ..base import CollectionMixin
from .base import Op


class Sequential(Op, CollectionMixin):
    def __init__(self, ops):
        self.collection = ops


# Path: deeppy/base.py
# class CollectionMixin(ParamMixin, PhaseMixin):
#     collection = []
# 
#     @property
#     def params(self):
#         params = []
#         for obj in self.collection:
#             if isinstance(obj, ParamMixin):
#                 params.extend(obj.params)
#         return params
# 
#     @params.setter
#     def params(self, params):
#         idx = 0
#         for obj in self.collection:
#             if isinstance(obj, ParamMixin):
#                 n_params = len(obj.params)
#                 obj.params = params[idx:idx+n_params]
#                 idx += n_params
# 
#     @property
#     def phase(self):
#         return self._phase
# 
#     @phase.setter
#     def phase(self, phase):
#         if self._phase == phase:
#             return
#         self._phase = phase
#         for obj in self.collection:
#             if isinstance(obj, PhaseMixin):
#                 obj.phase = phase
# 
# Path: deeppy/expr/base.py
# class Op(PickleMixin):
#     _pickle_ignore = ['_tmp_', 'array', 'grad_array']
#     inputs = []
#     bpropable = True
#     shape = None
#     array = None
#     grad_array = None
# 
#     def setup(self):
#         pass
# 
#     def fprop(self):
#         raise NotImplementedError()
# 
#     def bprop(self):
#         raise NotImplementedError()
# 
#     def __add__(self, other):
#         return deeppy.expr.Add()(self, other)
# 
#     def __radd__(self, other):
#         return deeppy.expr.Add()(other, self)
# 
#     def __iadd__(self, other):
#         return self.__add__(other)
# 
#     def __sub__(self, other):
#         return deeppy.expr.Subtract()(self, other)
# 
#     def __rsub__(self, other):
#         return deeppy.expr.Subtract()(other, self)
# 
#     def __isub__(self, other):
#         return self.__sub__(other)
# 
#     def __mul__(self, other):
#         return deeppy.expr.Multiply()(self, other)
# 
#     def __rmul__(self, other):
#         return deeppy.expr.Multiply()(other, self)
# 
#     def __imul__(self, other):
#         return self.__mul__(other)
# 
#     def __div__(self, other):
#         return deeppy.expr.Divide()(self, other)
# 
#     def __rdiv__(self, other):
#         return deeppy.expr.Divide()(other, self)
# 
#     def __idiv__(self, other):
#         return self.__div__(other)
# 
#     def __truediv__(self, other):
#         return deeppy.expr.Divide()(self, other)
# 
#     def __rtruediv__(self, other):
#         return deeppy.expr.Divide()(other, self)
# 
#     def __itruediv__(self, other):
#         return self.__truediv__(other)
# 
#     def __pow__(self, other):
#         return deeppy.expr.Power()(self, other)
# 
#     def __rpow__(self, other):
#         return deeppy.expr.Power()(other, self)
# 
#     def __ipow__(self, other):
#         return self.__pow__(other)
# 
#     def __neg__(self):
#         return deeppy.expr.Negative()(self)
# 
#     @property
#     def T(self):
#         return deeppy.expr.transpose(self)


# Path: deeppy/expr/composition.py
from ..base import CollectionMixin
from .base import Op



class Sequential(Op, CollectionMixin):
    def __init__(self, ops):
        self.collection = ops


    def __call__(self, x):