we developed a new method called Sparse Identification of Nonlinear Dynamical Systems from Graph-structured data (SINDyG), which incorporates the network structure into sparse regression to identify model parameters that explain the underlying network dynamics. SINDyG discovers the governing equations of network dynamics while offering improvements in accuracy and model simplicity.
This repository contains Python code for modeling and analyzing coupled oscillator systems using the SINDy (Sparse Identification of Nonlinear Dynamics) and SINDyG (SINDy with Graph) algorithms.
Please cite the following paper if you use this code.
Mohammad Amin Basiri and Sina Khanmohammadi. "SINDyG: sparse identification of nonlinear dynamical systems from graph-structured data, with applications to Stuart–Landau oscillator networks." Journal of Complex Networks 13, no. 5 (2025): cnaf029.
https://academic.oup.com/comnet/article/13/5/cnaf029/8259871
-
Prerequisites: Make sure you have the following installed:
- Python (3.6 or later)
- Required libraries:
numpy,pysindy,matplotlib,scipy,sklearn,networkx,sympy,pandas
-
Install Git:
-
If you don't have Git, install it using:
conda install -c anaconda git
-
Verify the installation and get information about the installed version of git:
git --version
-
-
Install PySINDy:
-
PySINDy is a sparse regression package with several implementations for the Sparse Identification of Nonlinear Dynamical systems (SINDy).
-
You can install the version V1.7.5 of pysindy by the following command:
!pip install git+https://github.com/dynamicslab/pysindy@v1.7.5 -
You can use the following to check if pysindy is installed:
!pip freeze -
make sure the version is the one which is in their GitHub repository "pysindy @ git+https://github.com/dynamicslab"
-
-
Add SINDyG Add-ons to PySINDy:
- Once PySINDy is installed, navigate to its installation directory (you can find it using
!pip show pysindy). - Then, make the following modifications to add the SINDyG Add-ons to the PySINDY package.
- replace
(installation directory)/pysindy/__init__.pywithSINDyG/PySINDy Add-ons/__init__.py - replace
(installation directory)/pysindy/pysindy.pywithSINDyG/PySINDy Add-ons/pysindy.py - replace
(installation directory)/pysindy/optimizers/__init__.pywithSINDyG/PySINDy Add-ons/optimizers/__init__.py - Add
Graph-SINDY/pysindy/optimizers/STLSQG.pyto(installation directory)/pysindy/optimizers/
- Once PySINDy is installed, navigate to its installation directory (you can find it using
The run_experiment function generates synthetic datasets based on the Stuart-Landau oscillator model with graph-structured coupling. Each node evolves according to the Stuart-Landau equation, and interactions between nodes are determined by the specified graph topology (either Erdős–Rényi or Scale-Free). Coupling strengths and oscillator frequencies are randomly initialized within specified ranges.
-
Single Run:
- Execute
SindyGraph_main_singlerun.pyto run a single experiment and visualize results. - Customize parameters within the
run_experimentfunction call.
- Execute
run_experiment(dt=0.01, # time step
Al=0.2, # -0.2 for damping, 0.2 for oscillating
max_edge_value=5, # maximum value for an edge when generating random edge values #5
max_freq=2, # maximum natural frequency
min_freq=0.1, # minimum natural frequency
d=2, #dimension of each oscillator
min_time=0, # starting time of Full signal
max_time=20, # finish time of Full signal
num_oscillators=5,
min_time_train=0, # minimum of train time
max_time_train=15, # maximum of train time
poly_deg=3, # the polynomial degree.
lamda_reg=0.05, # Lambda of Reg
STLSQ_thr=0.14, # the threshold of STLSQ
L=10, # parameter for adjusting the shape of the function
test_length=1.0, length of test set
timeout_seconds=20, # stop the run if it takes a long time
Graph = "ER", #"SF" Type of the graph "Scale-free" or "ER"
plot_train_data = True, # plot the data
print_summary = True # print summary of the model + all the scores and metrics
)Train data:
Test data:
-
Multiple Runs (Sensitivity Analysis):
- Execute
SindyGraph_main_sensitivity.pyto run multiple experiments with varying parameters. - Configure
Variable_nameandVariable_listto control the parameter being varied and its range.
Variable_name= 'num_oscillators' Variable_list = [3, 4, 5, 6] repetition = 5
- Set
repetitionto define the number of runs for each parameter value. - Also when the run_experiment function is going to be called in a loop, set the value of the corresponding variable to be chosen from vector V that iterates in Variable_list.
- Execute
- CSV File: The experiment results will be saved in the specified
csv_file_path. - Sensitivity Plots: The code will generate sensitivity plots for various attributes (e.g., Complexity, Train_r2) to visualize the impact of different parameters on model performance.
one example of sensitivity analysis:
sindy_functions.py: Contains all the core functions for simulating dynamics, training models, plotting, etc.run_experiment.py: Defines therun_experimentfunction that encapsulates the logic for a single experiment run.SindyGraph_main_sensitivity.py: Contains the main experiment loop that iterates over parameter combinations, runs experiments, and saves results to a CSV file. Also includes the code for reading the CSV and generating sensitivity plots.SindyGraph_main_Singlerun.py: Contains One experiment loop with one parameter combination, Plot Train data, Plot test data, providing summery model, and evaluating using different metrics.
- Parameters: Adjust the parameters in the main experiment loop or the
run_experimentfunction to explore different scenarios. - Graph Types: The code currently supports 'ER' (Erdős-Rényi) and 'SF' (Scale-Free) graphs. You can add support for other graph types by modifying the
run_experimentfunction. - Metrics and Visualization: You can customize the
attributes_to_plotlist to generate sensitivity plots for different metrics. You can also modify the plotting code to create different types of visualizations or use other plotting libraries.
[1] Brunton, Steven L., Joshua L. Proctor, and J. Nathan Kutz. "Discovering governing equations from data by sparse identification of nonlinear dynamical systems." Proceedings of the national academy of sciences 113, no. 15 (2016): 3932-3937.
[2] Kaptanoglu, Alan A., Brian M. de Silva, Urban Fasel, Kadierdan Kaheman, Andy J. Goldschmidt, Jared L. Callaham, Charles B. Delahunt et al. "PySINDy: A comprehensive Python package for robust sparse system identification." arXiv preprint arXiv:2111.08481 (2021).
[3] Qin, Yuzhen, Tommaso Menara, Danielle S. Bassett, and Fabio Pasqualetti. "Phase-amplitude coupling in neuronal oscillator networks." Physical Review Research 3, no. 2 (2021): 023218.


