# -*- coding: utf-8 -*- 
from .module import Module
from ...functions import *
[docs]class Identity(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
    
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return identity(x)  
    
[docs]class ReLU(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return relu(x)  
    
[docs]class LeakyReLU(Module):
    def __init__(self, negative_slope=0.01):
        super().__init__() 
        self.negative_slope = negative_slope
        
    def __repr__(self):
        return '{}(negative_slope={}) at 0x{:0{}X}'.format(self.__class__.__name__, self.negative_slope, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return leakyrelu(x, self.negative_slope)  
[docs]class ELU(Module):
    def __init__(self, alpha=1.0):
        super().__init__()
        self.alpha = alpha
    
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return elu(x, self.alpha)  
[docs]class Sigmoid(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return sigmoid(x)  
[docs]class Tanh(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return tanh(x)  
[docs]class SoftPuls(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return softplus(x)  
[docs]class SoftSign(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return softsign(x)  
[docs]class SoftMax(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
[docs]    def forward(self, x):
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = x.shape
        return softmax(x)  
[docs]class Flatten(Module):
    def __repr__(self):
        return '{}() at 0x{:0{}X}'.format(self.__class__.__name__, id(self), 16)
        
[docs]    def forward(self, x):
        result = x.reshape(x.shape[0],-1)
        if self.input_shape is None:
            self.input_shape = x.shape
        if self.output_shape is None:
            self.output_shape = result.shape
        return result