Skip to content

utils

Auxiliar functions

check_func_inverse(func, inv_func)

check that func and inv_func are indeed inverse of each other

Source code in echoes/utils.py
def check_func_inverse(func: Callable, inv_func: Callable) -> None:
    """check that func and inv_func are indeed inverse of each other"""
    x = np.linspace(-2, 2, 10)
    y = func(x)
    mismatch = np.where(inv_func(y) != x)[0]
    assert np.isclose(
        inv_func(y), x
    ).all(), f"function {inv_func.__name__} is not the inverse of {func.__name__}"

check_matrices_shapes(W_in, W, W_fb, n_inputs, n_reservoir, n_outputs, feedback)

Check shapes of W, W_in, W_fb

Source code in echoes/utils.py
def check_matrices_shapes(W_in, W, W_fb, n_inputs, n_reservoir, n_outputs, feedback):
    """Check shapes of W, W_in, W_fb"""
    assert W.shape[0] == W.shape[1], "W must be square"
    assert len(W) == n_reservoir, "W does not match n_reservoir"
    assert W_in.shape[0] == n_reservoir, "W_in first dimension must equal n_reservoir"
    assert W_in.shape[1] == n_inputs, "W_in second dimension must equal n_inputs"
    if feedback:
        assert W_fb is not None, "W_fb must be specified if feedback=True"
    if W_fb is not None:
        assert (
            W_fb.shape[0] == n_reservoir
        ), "W_fb first dimension must equal n_reservoir"
        assert W_fb.shape[1] == n_outputs, "W_fb second dimension must equal n_outputs"

check_model_params(params)

check consistency of parameters, shapes, sensible warnings

Source code in echoes/utils.py
def check_model_params(params: Mapping,) -> None:
    """check consistency of parameters, shapes, sensible warnings"""
    W_in = params["W_in_"]
    W = params["W_"]
    W_fb = params["W_fb_"]
    n_reservoir = params["n_reservoir_"]
    n_inputs = params["n_inputs_"]
    n_outputs = params["n_outputs_"]
    feedback = params["feedback"]
    input_scaling = params["input_scaling"]
    input_shift = params["input_shift"]

    check_matrices_shapes(W_in, W, W_fb, n_inputs, n_reservoir, n_outputs, feedback)
    check_sparsity(params["sparsity"])
    check_input_scaling(input_scaling, n_inputs)
    check_input_shift(input_scaling, n_inputs)

    # Warnings
    if params["leak_rate"] == 0:
        warnings.warn(
            "leak_rate == 0 is total leakeage, you probably meant 1. See documentation."
        )
    if (
        params["regression_method"] != "ridge"
        and params["ridge_sample_weight"] is not None
    ):
        warnings.warn(
            "ridge_sample_weight will be ignored since regression_method is not ridge"
        )

relu(x)

Numba jitted ReLu (rectified linear unit) function. Return ReLu(x)

Source code in echoes/utils.py
@njit
def relu(x: Union[float, int, np.ndarray]) -> Union[float, np.ndarray]:
    """Numba jitted ReLu (rectified linear unit) function. Return ReLu(x)"""
    return np.maximum(0, x)

set_spectral_radius(matrix, target_radius)

Return a copy of matrix with rescaled weights to match target spectral radius

Source code in echoes/utils.py
def set_spectral_radius(matrix: np.ndarray, target_radius: float) -> np.ndarray:
    """Return a copy of matrix with rescaled weights to match target spectral radius"""
    matrix = matrix.copy()
    current_radius = np.max(np.abs(np.linalg.eigvals(matrix)))
    matrix *= target_radius / current_radius
    return matrix

sigmoid(x, a=1)

Return f(x) = 1 / (1 + np.exp(-x * a)). Numba jitted sigmoid function.

Source code in echoes/utils.py
@njit
def sigmoid(x: Union[float, int, np.ndarray], a: float = 1) -> Union[float, np.ndarray]:
    """
    Return  f(x) = 1 / (1 + np.exp(-x * a)). Numba jitted sigmoid function.
    """
    return 1 / (1 + np.exp(-x * a))

tanh(x)

Numba jitted tanh function. Return tanh(x)

Source code in echoes/utils.py
@njit
def tanh(x: Union[float, int, np.ndarray]) -> Union[float, np.ndarray]:
    """Numba jitted tanh function. Return tanh(x)"""
    return np.tanh(x)