import numpy as np

class SoftSign():
    """
    Smooth, y-range [-1, 1], vanishing gradient at polynomial decay, low computationally expensive
    """
    @staticmethod
    def f(x):
        return x / (1 + np.abs(x))
    @staticmethod
    def df(x, order=1):
        abs_x = np.abs(x)
        match order:
            case 1:
                return 1 / (1 + abs_x)**2
            case 2:
                return -2 * np.sign(x) / (1 + abs_x)**3
            case _:
                raise NotImplementedError(f"SoftSign gradient order {order} is not implemented yet")
