pyreco package

Submodules

pyreco.cross_validation module

pyreco.cross_validation.cross_val(model, X: ndarray, y: ndarray, n_splits: int, metric: str = 'mse') Tuple[List[float], float, float][source]

Performs k-fold cross-validation on a given model.

Parameters: model : object

The RC model to be validated.

Xnp.ndarray

Feature matrix.

ynp.ndarray

Target vector.

n_splitsint

Number of folds.

metricsstr

Metric to evaluate.

Returns: tuple

A tuple containing: - list of metric’s value for each fold - mean of the metric values - standard deviation of the metric values

pyreco.custom_models module

class pyreco.custom_models.AutoRC[source]

Bases: CustomModel

Autonomous version of the reservoir computer.

predict_ar(X: ndarray, n_steps: int = 10)[source]

Perform auto-regressive prediction (time series forecasting).

Args: X (np.ndarray): Initial input data. n_steps (int): Number of steps to predict into the future.

Returns: np.ndarray: Predicted future states.

class pyreco.custom_models.CustomModel[source]

Bases: ABC

Abstract base class for custom reservoir computing model.

Has a syntax similar to the one of TensorFlow model API, e.g. using the model.add() statement to add layers to the model.

A model hast an input layer, a reservoir layer and a readout layer.

add(layer: Layer)[source]

Add a layer to the model.

Is type-sensitive and will assign the layer to the correct attribute.

Args: layer (Layer): Layer to be added to the model.

compile(optimizer: str = 'ridge', metrics: list | str | None = None, discard_transients: int = 0)[source]

Configure the model for training.

Args: optimizer (str): Name of the optimizer. metrics (list): List of metric names. discard_transients (int): Number of initial transient timesteps to discard.

compute_reservoir_state(x: ndarray) ndarray[source]

Vectorized computation of reservoir states with batch processing.

Parameters:

x (np.ndarray) – Input data of shape [n_batch, n_timesteps, n_states]

Returns:

Reservoir states of shape [(n_batch * n_timesteps), N]

Return type:

np.ndarray

evaluate(x: ndarray, y: ndarray, metrics: str | list | None = None) tuple[source]

Evaluate metrics on predictions made for input data.

Args: x (np.ndarray): Input data of shape [n_batch, n_timesteps, n_states] y (np.ndarray): Target data of shape [n_batch, n_timesteps_out, n_states_out] metrics (Union[str, list, None], optional): List of metric names or a single metric name. If None, use metrics from .compile()

Returns: tuple: Metric values

fit(x: ndarray, y: ndarray, n_init: int = 1, store_states: bool = False) dict[source]

RC training with batch processing.

fit_evolve(X: ndarray, y: ndarray)[source]
get_hp(*args)[source]

Get one or more reservoir hyperparameters. If no args, returns all. Usage: get_hp(‘spec_rad’, ‘activation’) or get_hp()

plot(path: str)[source]

Print the model to some figure file.

Args: path (str): Path to save the figure.

predict(x: ndarray) ndarray[source]

Make predictions for given input.

Args: x (np.ndarray): Input data of shape [n_batch, n_timestep, n_states] one_shot (bool): If True, don’t re-initialize reservoir between samples.

Returns: np.ndarray: Predictions of shape [n_batch, n_timestep, n_states]

remove_reservoir_nodes(nodes: list)[source]
save(path: str)[source]

Store the model to disk.

Args: path (str): Path to save the model.

set_hp(**kwargs)[source]

Set one or more reservoir hyperparameters. Supported kwargs: spec_rad, leakage_rate, activation

class pyreco.custom_models.HybridRC[source]

Bases: CustomModel

Hybrid version of the reservoir computer.

class pyreco.custom_models.RC[source]

Bases: CustomModel

Non-autonomous version of the reservoir computer.

pyreco.datasets module

pyreco.graph_analyzer module

class pyreco.graph_analyzer.GraphAnalyzer(quantities=None)[source]

Bases: object

A class for analyzing graph properties and extracting network properties from a graph.

extract_properties(graph: Graph | DiGraph | ndarray) dict[source]

Extract the specified network properties from the given graph.

Parameters:

graph (nx.Graph, nx.DiGraph, np.ndarray) – The graph to analyze.

Returns:

A dictionary containing the extracted network properties.

Return type:

dict

list_properties()[source]

Return a list of available network properties.

Returns:

A list of available network properties.

Return type:

list

pyreco.graph_analyzer.available_extractors()[source]

Return a dictionary mapping network property names to their corresponding extractor functions. Make changes here if you want to add more network properties.

Returns:

A dictionary mapping network property names to their corresponding extractor functions.

Return type:

dict

pyreco.graph_analyzer.map_extractor_names(prop_names: str)[source]

Return a dictionary mapping network property names to their corresponding extractor functions for the given property names.

Returns:

A dictionary mapping network property names to their corresponding extractor functions.

Return type:

dict

pyreco.initializer module

class pyreco.initializer.NetworkInitializer(method: str = 'random')[source]

Bases: object

network initializers.

gen_initial_states(shape: tuple | list) ndarray[source]

Generate initial states for the reservoir.

Parameters: - shape (tuple, list): The shape of array to generate

Returns: - np.ndarray: The initialized array

pyreco.layers module

We will have an abstract Layer class, from which the following layers inherit:

  • InputLayer

  • ReservoirLayer
    • RandomReservoir

    • RecurrenceReservoir

    • EvolvedReservoir

  • ReadoutLayer

class pyreco.layers.InputLayer(input_shape)[source]

Bases: Layer

remove_nodes(nodes: list)[source]
update_layer_properties()[source]
class pyreco.layers.Layer[source]

Bases: ABC

abstract update_layer_properties()[source]
class pyreco.layers.RandomReservoirLayer(nodes, density: float = 0.1, activation: str = 'tanh', leakage_rate: float = 0.5, fraction_input: float = 0.8, spec_rad: float = 0.9, init_res_sampling='random_normal', seed=None)[source]

Bases: ReservoirLayer

class pyreco.layers.ReadoutLayer(output_shape, fraction_out=1.0)[source]

Bases: Layer

remove_nodes(nodes: list)[source]
update_layer_properties()[source]
class pyreco.layers.ReservoirLayer(nodes, density, activation, leakage_rate, fraction_input, init_res_sampling, seed: int = 42)[source]

Bases: Layer

activation_fun(x: ndarray)[source]
get_activation()[source]
get_leakage_rate()[source]
get_spec_rad()[source]
remove_nodes(nodes: list)[source]

Remove specified nodes from the reservoir network. Parameters: nodes (list): A list of indices representing the nodes to be removed. 1. Removes the specified nodes from the adjacency matrix. 2. Updates the reservoir properties including the number of nodes, density, and spectral radius.

set_activation(value)[source]
set_initial_state(r_init: ndarray)[source]
set_leakage_rate(value)[source]
set_spec_rad(value)[source]

Sets the spectral radius of the reservoir network. Parameters: - value (float): The desired spectral radius. Raises: - ValueError: If the value is not positive or if the weights are not set.

set_weights(network: ndarray)[source]
update_layer_properties()[source]

Updates the reservoir properties including the number of nodes, density, and spectral radius. This method should be called after any changes to the reservoir network.

pyreco.metrics module

pyreco.metrics.assign_metric(metric: str)[source]
pyreco.metrics.available_metrics() list[source]
pyreco.metrics.mae(y_true: ndarray, y_pred: ndarray) float[source]
pyreco.metrics.mse(y_true: ndarray, y_pred: ndarray) float[source]
pyreco.metrics.r2(y_true: ndarray, y_pred: ndarray) float[source]

pyreco.models module

Higher-level model definition for default models (built on custom models):

Wrapper for lower-level implementation of RCs. Instead of the Sequential-API-type syntax, this will provide sklearn-ready models, which under the hood build Sequential-API-type models and ship them.

Currently contains a lot of duplicate code, which needs to be ported to the lower-level implementations.

class pyreco.models.Model(num_nodes: int = 100, activation: str = 'tanh', leakage_rate: float = 0.5)[source]

Bases: ABC

compile(optimizer: str = 'ridge', metrics: None | list = None)[source]
evaluate(X: ndarray, y: ndarray, metrics: str | list = ['mse'])[source]
abstract fit(X: ndarray, y: ndarray)[source]
get_params(deep=True)[source]
abstract predict(X: ndarray) ndarray[source]
abstract remove_reservoir_nodes(nodes: list)[source]
set_params(**get_params)[source]
class pyreco.models.ReservoirComputer(num_nodes: int = 100, density: float = 0.8, activation: str = 'tanh', leakage_rate: float = 0.5, spec_rad: float = 0.9, fraction_input: float = 1.0, fraction_output: float = 1.0, n_time_in=None, n_time_out=None, n_states_in=None, n_states_out=None, metrics: str | list = 'mean_squared_error', optimizer: str | Optimizer = 'ridge', init_res_sampling='random_normal')[source]

Bases: Model

evaluate(x: ndarray, y: ndarray, metrics: list = ['mse'])[source]
fit(x: ndarray, y: ndarray, n_init: int = 1, store_states: bool = False)[source]
get_params(deep=True)[source]
predict(x: ndarray) ndarray[source]
remove_reservoir_nodes(nodes: list)[source]
set_params(**get_params)[source]

pyreco.network_prop_extractor module

pyreco.node_analyzer module

class pyreco.node_analyzer.NodeAnalyzer(quantities=None)[source]

Bases: object

A class for analyzing node properties in a graph.

extract_properties(graph: Graph | DiGraph | ndarray, node: int) dict[source]

Extract the specified network properties from the given graph at the given node(s).

Parameters:
  • graph (nx.Graph, nx.DiGraph, np.ndarray) – The graph to analyze.

  • nodes (int) – The node to analyze.

Returns:

A dictionary containing the extracted network properties.

Return type:

dict

list_properties()[source]

Return a list of available node properties.

Returns:

A list of available node properties.

Return type:

list

pyreco.node_analyzer.available_extractors()[source]

Return a dictionary mapping network property names to their corresponding extractor functions. Make changes here if you want to add more network properties.

Returns:

A dictionary mapping network property names to their corresponding extractor functions.

Return type:

dict

pyreco.node_analyzer.map_extractor_names(prop_names: str)[source]

Return a dictionary mapping network property names to their corresponding extractor functions for the given property names.

Returns:

A dictionary mapping network property names to their corresponding extractor functions.

Return type:

dict

pyreco.node_selector module

class pyreco.node_selector.NodeSelector(strategy: str = 'random_uniform_wo_repl', total_nodes: int | None = None, graph: Graph | ndarray | None = None)[source]

Bases: object

A class to select nodes from a graph based on specific criteria.

This class provides functionality to select a subset of nodes from a total number of nodes using different strategies. Currently, only the “random without replacement” strategy is implemented.

Attributes: - num_total_nodes (int): The total number of nodes in the graph. - num_select_nodes (int): The number of nodes to select. - fraction (float): The fraction of nodes to select. - strategy (str): The strategy used for node selection. - selected_nodes (list): The list of selected nodes.

select_nodes(fraction: float | None = None, num: int | None = None)[source]

Selects a specified number of nodes from the graph either by fraction or by exact number.

Parameters: - fraction (float, optional): The fraction of the total nodes to select. Must be between 0 and 1. - num (int, optional): The exact number of nodes to select. Must be a positive integer.

Raises: - ValueError: If neither or both of fraction and num are provided. - TypeError: If num is not an integer.

Returns: - list: A list of selected node identifiers.

pyreco.optimizers module

class pyreco.optimizers.Optimizer(name: str = '')[source]

Bases: ABC

abstract solve(A: ndarray, b: ndarray) ndarray[source]
class pyreco.optimizers.RidgeSK(name: str = '', alpha=1.0)[source]

Bases: Optimizer

solve(A: ndarray, b: ndarray) ndarray[source]
pyreco.optimizers.assign_optimizer(optimizer: str) Optimizer[source]

Maps names of optimizers to the correct implementation.

Parameters:

optimizer (str or Optimizer) – The name of the optimizer.

Returns:

An instance of the optimizer class corresponding to the given name.

Return type:

Optimizer

Raises:

ValueError – If the given optimizer name is not implemented.

pyreco.plotting module

Some plotting capabilities

pyreco.plotting.r2_scatter(y_true: ndarray, y_pred: ndarray, state_idx: int | tuple | None = None, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None)[source]

pyreco.pruning module

Capabilities to prune an existing RC model, i.e. try to cut reservoir nodes and improve performance while reducing the reservoir size

class pyreco.pruning.NetworkPruner(target_score: float | None = None, stop_at_minimum: bool = True, min_num_nodes: int = 3, patience: int = 0, candidate_fraction: float = 0.1, remove_isolated_nodes: bool = False, criterion: str = 'mse', metrics: list | str = ['mse'], maintain_spectral_radius: bool = False, node_props_extractor=None, graph_props_extractor=None, return_best_model: bool = True, graph_analyzer: GraphAnalyzer | None = None, node_analyzer: NodeAnalyzer | None = None)[source]

Bases: object

add_dict_to_history(keys, value_dict)[source]

Add a dictionary to history dictionary based on a list of keys.

Args: nested_dict (dict): The nested dictionary. keys (list): A list of keys specifying the path in the nested dictionary. value_dict (dict): The dictionary to add.

add_val_to_history(keys, value)[source]

Add a value to history dictionary based on a list of keys.

Parameters:
  • keys (list) – A list of keys specifying the path in the nested dictionary.

  • value – The value to add.

prune(model: RC, data_train: tuple, data_val: tuple)[source]

Prune a given model by removing nodes.

Parameters: - model (RC): The reservoir computer model to prune. - data_train (tuple): Training data. - data_val (tuple): Validation data.

pyreco.pruning.append_to_dict(dict1, dict2)[source]
pyreco.pruning.dictlist_to_dict(dict_list)[source]

Join dictionaries in a list into a common dictionary.

Parameters:

dict_list (list) – A list of dictionaries to join.

Returns:

A common dictionary containing all key-value pairs from the dictionaries in the list.

Return type:

dict

pyreco.remove_transients module

pyreco.remove_transients.RemoveTransient_Inps(X, Transients)[source]
pyreco.remove_transients.RemoveTransient_Outs(Y, Transients)[source]
pyreco.remove_transients.RemoveTransients_Res(ResStates, Transients)[source]
pyreco.remove_transients.TransientRemover(What: str, ResStates, X, Y, Transients: int)[source]

pyreco.utils_data module

Provides testing data sets.

SHAPES will always be: inputs X: [n_batch, n_timesteps, n_states] outputs y: [n_batch, n_timesteps, n_states]

pyreco.utils_data.gen_cos(n=10, omega=3.141592653589793)[source]
pyreco.utils_data.gen_sincos(n=10, omega=3.141592653589793, a_sc=1, b_sc=0.25, P_sc=3)[source]
pyreco.utils_data.gen_sine(n=10, omega=3.141592653589793)[source]
pyreco.utils_data.sequence_to_scalar(name, n_batch: int = 50, n_states=1, n_time_in=2)[source]
pyreco.utils_data.sequence_to_sequence(name, n_batch: int = 50, n_states: int = 2, n_time: int = 3)[source]
pyreco.utils_data.sincos2(n_batch, n_time_in, n_time_out, n_states)[source]
pyreco.utils_data.sine_pred(n_batch, n_time_in, n_time_out, n_states)[source]
pyreco.utils_data.sine_to_cosine(n_batch, n_time_in, n_time_out, n_states)[source]
pyreco.utils_data.split_sequence(signal, n_batch, n_time_in, n_time_out)[source]
pyreco.utils_data.train_test_split(x, y)[source]
pyreco.utils_data.vector_to_vector(name, n_batch: int = 50, n_states=1)[source]
pyreco.utils_data.x_to_x(name, n_batch: int = 50, n_states_in: int = 2, n_states_out: int = 2, n_time_int: int = 1, n_time_out: int = 1)[source]

pyreco.utils_networks module

Helper routines for networks

pyreco.utils_networks.compute_density(network: ndarray) float[source]
pyreco.utils_networks.compute_spec_rad(network: ndarray) float[source]
pyreco.utils_networks.convert_to_nx_graph(graph: ndarray) Graph[source]

Convert a numpy array to a NetworkX graph. :param adjacency_matrix: The adjacency matrix of the graph. :type adjacency_matrix: np.ndarray

Returns:

The NetworkX graph.

Return type:

nx.Graph

pyreco.utils_networks.extract_av_in_degree(graph: ndarray | Graph | DiGraph) float[source]
pyreco.utils_networks.extract_av_out_degree(graph: ndarray | Graph | DiGraph) float[source]
pyreco.utils_networks.extract_clustering_coefficient(graph: ndarray | Graph | DiGraph) float[source]
pyreco.utils_networks.extract_density(graph: ndarray | Graph | DiGraph) float[source]

Extract the density of a graph from its adjacency matrix. :param adjacency_matrix: The adjacency matrix of the graph. :type adjacency_matrix: np.ndarray, nx.Graph, nx.DiGraph

Returns:

The density of the graph.

Return type:

float

pyreco.utils_networks.extract_node_betweenness_centrality(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_node_clustering_coefficient(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_node_degree(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_node_in_degree(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_node_out_degree(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_node_pagerank(graph: ndarray | Graph | DiGraph, node: int) float[source]
pyreco.utils_networks.extract_spectral_radius(graph: ndarray | Graph | DiGraph) float[source]
pyreco.utils_networks.gen_ER_graph(nodes: int, density: float, spec_rad: float = 0.9, directed: bool = True, seed=None)[source]

Generate an Erdős-Rényi random graph with specified properties.

Bug Fix Documentation:

Previous Bug:

The line G.remove_nodes_from(list(nx.isolates(G))) removed isolated nodes from the graph before converting to a numpy array. This caused the final matrix to sometimes be smaller than the specified size (e.g., 29x29 instead of 30x30) when isolated nodes were present. This led to dimension mismatches in reservoir computations where other matrices expected the full size.

Solution:

Instead of removing isolated nodes, we now connect them to maintain the specified network size. This ensures consistency between the reservoir weight matrix and other matrices in the computation.

param nodes:

Number of nodes in the graph

type nodes:

int

param density:

Desired connection density (0 to 1)

type density:

float

param spec_rad:

Desired spectral radius

type spec_rad:

float

param directed:

Whether to create a directed graph

type directed:

bool

param seed:

Random seed for reproducibility

type seed:

int, optional

returns:

Adjacency matrix with shape (nodes, nodes)

rtype:

np.ndarray

pyreco.utils_networks.gen_init_states(num_nodes: int, method: str = 'random')[source]
pyreco.utils_networks.get_num_nodes(network: ndarray) int[source]
pyreco.utils_networks.is_zero_col_and_row(x: ndarray, idx: int) bool[source]
pyreco.utils_networks.remove_nodes_from_graph(graph: ndarray, nodes: list)[source]
pyreco.utils_networks.rename_nodes_after_removal(original_nodes: list, removed_nodes: list)[source]
pyreco.utils_networks.set_spec_rad(network: ndarray, spec_radius: float) ndarray[source]

Module contents