Select a ready-made system
Pick a system from the catalog by its name, read what it is, and simulate it with the settings it was tuned for.
The catalog
Pick a ready-made system by name, read what it is, and simulate it with the settings it was tuned for.
create_simulation returns a simulation that is ready to prepare and run.
from skcomplex.systems import create_simulation, describe
entry = describe('sir')
entry.description, entry.parameters, entry.formalism
trajectory = create_simulation('sir').prepare().run().trajectory_
trajectory.values('I.n').max().round()
('An epidemic that moves individuals from susceptible to infected to recovered.',
{'susceptible': 990.0, 'infected': 10.0, 'recovered': 0.0, 'beta': 0.0003, 'gamma': 0.1, 'stochastic': False},
'ordinary differential equations')
304.0
describe tells you what a system is: its field, description, tags, references, the parameters of its factory with
their defaults, its default run settings, and the formalism the compiler infers for it. create_simulation builds the
system and wraps it in a simulation that holds the system as system, the default end time as until, and the tuned
time step, solver, observables, initial state, and seed random_state=0. Every object has the same two verbs, so you
call prepare and then run.
You import four functions from skcomplex.systems and nothing else.
cataloglists the systems, filtered by a field, a field path, or a tag.describegives one system by name.create_systembuilds the system by name and returns it.create_simulationreturns a simulation of it with its default run settings.
The system catalog
Every ready-made system is a factory registered with its field path, description, tags, references, and default run
settings. catalog filters by a field, such as biology, by a field path, such as biology/ecology, or by a tag.
from skcomplex.systems import catalog, create_system, describe
[entry.name for entry in catalog(field='biology/ecology')]
sorted({entry.field for entry in catalog(field='chemistry')})
[entry.name for entry in catalog(tag='oscillation')]
describe('lotka_volterra').formalism
predation = create_system('lotka_volterra', a=0.2)
predation
['agent_based_lotka_volterra', 'comets', 'community_fba', 'competition', 'consumer_resource', 'droop_cell_quota',
'dynamic_multispecies_fba', 'exponential_growth', 'fibonacci_rabbits', 'fisher_kpp', 'food_webs',
'forest_size_structure', 'generalized_lotka_volterra', 'higher_order_random_lotka_volterra', 'hutchinson',
'intrinsic_instability', 'logistic_growth', 'lotka_volterra', 'lotka_volterra_with_harvesting',
'mangrove_succession', 'meadow_capacity', 'mutualism', 'neutral_biodiversity', 'neutral_clustering',
'neutral_macroecology', 'nicholson_bailey', 'penaeid_shrimp', 'ricker', 'rosenzweig_macarthur',
'sequentially_linear_ecosystem', 'stigmergic_predator_prey', 'stochastic_predator_prey', 'varying_capacity_logistic',
'wolf_sheep']
['chemistry/kinetics', 'chemistry/pattern_formation']
['agent_based_lotka_volterra', 'hutchinson', 'lotka_volterra', 'lotka_volterra_with_harvesting', 'nicholson_bailey',
'brusselator_ode', 'oregonator', 'brusselator', 'tunnel_diode_oscillator', 'grain_storage', 'ikeda', 'enso',
'coupled_pendulums', 'driven_damped_oscillator', 'harmonic_oscillator', 'pendulum', 'two_mass_spring_damper',
'adler_equation', 'stuart_landau', 'van_der_pol']
ordinary differential equations
The catalog belongs to the catalog alone. The engine and the experiments take a system or a factory, never a system
name. So you create a system of the library with create_system, or you pass its factory.
Each system has a field path <field>/<subfield>, which catalog takes as a filter.
| Field | Subfields |
|---|---|
physics |
mechanics, celestial_mechanics, nonlinear_oscillators, synchronization, statistical_mechanics, criticality, soft_matter, active_matter, fluids, waves, pattern_formation, heat, cosmology, climate, oceanography, seismology |
chemistry |
kinetics, pattern_formation |
biology |
ecology, epidemiology, evolution, neuroscience, systems_biology, physiology, collective_behaviour, oncology |
economics |
macroeconomics, markets, finance, econophysics, resources, innovation |
social |
opinion_dynamics, segregation, cooperation, spreading, crowds, organizations, language |
engineering |
traffic, circuits, control, power_systems, robotics, processes, mechatronics |
mathematics |
dynamical_systems, stochastic_processes, networks, fractals, fractional_dynamics |
computer_science |
automata, evolutionary_computation, neural_networks |
A system lives where the science that poses it lives, and its tags carry its reach into other fields. The library keeps the catalog apart from the core by three rules, which the checks of the package layout enforce.
- The core never imports the systems.
- Every system is built only from the public names of the core.
- Every subfield package is self-contained, so no system package imports another. Code that several subfields of one
field share lives in the
commonpackage of that field, and no field uses thecommonpackage of another.
Optional extras
Most systems run on the default install. A few take a library from an optional extra. Without the extra they stay in
the catalog, and building one raises MissingExtraError with the name of the system, the extra, and the install
command.
| Extra | Library | Systems | Install notes |
|---|---|---|---|
structures |
Biopython | fuzzy_oil_drop, early_stage_folding_intermediate |
Biopython 1.88 publishes no wheel for macOS on Intel, so the extra builds it from source there with a C compiler. |
rna |
ViennaRNA | rna_neutral_networks |
The licence of ViennaRNA allows research and commercial use, forbids redistribution for a fee, and is not OSI approved, so the default install never brings it. |
trajectories |
MDTraj | none, it reads molecular dynamics trajectories for the systems biology systems | MDTraj is under the LGPL. |
Systems as patterns
The ready-made systems are examples of the core interface, not a separate one. So each is also the pattern for a system of your own. The page of every field, under Systems in the documentation, shows for each system:
- its factory,
- its element and interaction types, with their states, parameters, and laws as written,
- for differential equations and maps, its equations as
SymbolicAnalysis('equations')returns them.
A system of your own follows the same steps. Declare the element and interaction types, and write a function that returns the system. The section Choosing compatible components shows how to find which parts fit together, and the contributing guide covers adding a system to the catalog.
Inventory
The system inventory, docs/overview/inventory.toml, records every system surveyed from the reference books and
articles, with its sources and its status: implemented, pending a planned change, or blocked by a missing feature of the
core. A system the core cannot express is recorded as blocked on the OpenSpec change that specifies the missing general
feature. It is never worked around inside the system package. A test checks the inventory against the catalog and the
changes. Every registered system has its own page under Systems in the documentation, by field and subfield.
Systems exist first to exercise the core, and ready-made systems are a by-product. Every entry lists the core primitives
it exercises, such as rates, jumps, groups, reductions, member-offsets, lattices, fields, agents, or
stocks-and-flows, from a vocabulary the inventory defines. A primitive that the core does not have yet names the
change that adds it. An entry's priority is core when it exercises a primitive, or a combination of primitives, that
no earlier implemented entry exercises, or when it needs a missing one. It is example when it repeats a covered
pattern. So new systems go first where the core is least exercised.