Runtime
Run systems frame by frame with clocks, live parameter changes, observers, and trajectories.
AsFastAsPossibleClock
Bases: BaseClock
Clock that never waits.
Examples:
>>> from skcomplex.engine.runtime import AsFastAsPossibleClock
>>> clock = AsFastAsPossibleClock().check().prepare().run(10.0)
>>> clock.max_lag_
0.0
BaseClock
Bases: BaseConfig[None, float]
Base class of clocks, which decide how long to wait between frames.
A clock follows the common API of the engine. It is checked and prepared at the start of a run with prepare(),
which marks the wall time, and run(elapsed) waits until a frame that is elapsed simulated time units after the
start is due. Subclasses implement _run.
Attributes:
| Name | Type | Description |
|---|---|---|
started_ |
The wall time at which the run started, in seconds of |
|
max_lag_ |
The largest delay of a frame behind its due time, in seconds. |
prepare(context=None)
Mark the wall time at which the run of the checked clock starts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
None
|
Nothing: a clock prepares on no context. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Self
|
The prepared clock. |
Source code in src/skcomplex/engine/runtime/_base.py
109 110 111 112 113 114 115 116 117 118 119 120 | |
run(elapsed=None, final=False)
Wait until a frame that is elapsed simulated time units after the start is due.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
elapsed
|
float | None
|
The simulated time since the start of the run. |
None
|
final
|
bool
|
Whether this is the last call of the run. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Self
|
The clock. |
Source code in src/skcomplex/engine/runtime/_base.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
BaseObserver
Bases: BaseConfig[BaseProblemSpec, FrameSpec]
Base class of objects that receive the frames of a simulation.
An observer follows the common API of the engine. A simulation checks it, calls prepare(problem) with the
compiled problem before the first frame, run(frame) with every frame, and run(final=True) without a frame once
the run stops, which releases what preparing acquired. Subclasses override any of the hooks _prepare, _run,
and _release.
Examples:
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import BaseObserver, Simulation
>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> class CountingObserver(BaseObserver):
... def _prepare(self, context):
... self.count_ = 0
...
... def _run(self, inputs):
... self.count_ += inputs is not None
>>> observer = CountingObserver().check()
>>> simulation = Simulation(System(elements=[PopulationElement('a')]), dt=1, observers=[observer])
>>> _ = simulation.check().prepare().run(until=3)
>>> observer.count_
4
prepare(problem=None)
Prepare the checked observer for a run of a compiled problem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
problem
|
BaseProblemSpec | None
|
The compiled problem the run advances. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Self
|
The prepared observer. |
Source code in src/skcomplex/engine/runtime/_base.py
47 48 49 50 51 52 53 54 55 56 57 58 | |
run(frame=None, final=False)
React to a frame, and release what preparing acquired at the last call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
FrameSpec | None
|
The frame, or |
None
|
final
|
bool
|
Whether this is the last call of the run. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Self
|
The observer. |
Source code in src/skcomplex/engine/runtime/_base.py
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
ConservationObserver(*, rtol=1e-06, atol=1e-09)
Bases: BaseObserver
Observer that checks at every frame that each quantity changes only by its flows with the environment.
The total of a quantity is the sum of the states that hold it. The monitor compares its change since the first frame with the accumulated net inflow from the environment, which the compiler integrates as a hidden state, and raises an error when they differ by more than the tolerance, such as after a boundary law clips a state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rtol
|
float
|
The relative tolerance, a fraction of the largest absolute total seen. |
1e-06
|
atol
|
float
|
The absolute tolerance. |
1e-09
|
Attributes:
| Name | Type | Description |
|---|---|---|
problem_ |
The compiled problem of the run. |
|
transfer_network_ |
The quantities of the problem, with the states that hold them and their flows with the environment. |
|
totals_ |
The total of every quantity at the latest frame. |
|
initial_ |
The total of every quantity minus its inflow from the environment at the first frame, or |
|
scale_ |
The largest absolute total of every quantity seen so far. |
Examples:
>>> from skcomplex.engine.runtime import ConservationObserver, Simulation
>>> from skcomplex.models import create
>>> monitor = ConservationObserver()
>>> _ = Simulation(create('bathtub'), dt=1, observers=[monitor]).check().prepare().run(10)
>>> round(monitor.totals_['water'], 6)
25.0
Source code in src/skcomplex/engine/runtime/_conservation.py
53 54 55 | |
InvariantObserver(invariants)
Bases: BaseObserver
Observer that checks at every frame that every named observable stays within its tolerance of its first value.
A simulation attaches one when it is given invariants.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invariants
|
Mapping[str, float]
|
The tolerance of every invariant, by the path of its observable. |
required |
Attributes:
| Name | Type | Description |
|---|---|---|
initial_ |
The value of every invariant at the first frame. |
Examples:
>>> from skcomplex.core.elements import GroupElement
>>> from skcomplex.specs import ObservableSpec
>>> from skcomplex.core.system import System
>>> from skcomplex.engine.runtime import InvariantObserver, Simulation
>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> system = System(
... elements=[GroupElement('herd', element=PopulationElement, size=2, values={'n': [2.0, 6.0]})]
... )
>>> total = ObservableSpec('total', group='herd', reduce='sum', variable='n')
>>> monitor = InvariantObserver({'total': 1e-9})
>>> _ = Simulation(system, dt=1, observables=[total], observers=[monitor]).check().prepare().run(3)
>>> monitor.initial_
{'total': 8.0}
Source code in src/skcomplex/engine/runtime/_invariants.py
44 45 | |
RealTimeClock(speed=1.0)
Bases: BaseClock
Clock that advances simulated time at a fixed speed relative to wall time.
The largest delay of a frame behind its due time is recorded in max_lag_.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
speed
|
float
|
The number of simulated time units per second of wall time. |
1.0
|
Examples:
>>> from skcomplex.engine.runtime import RealTimeClock
>>> clock = RealTimeClock(speed=100.0).check().prepare().run(1.0)
>>> clock.max_lag_ < 0.1
True
Source code in src/skcomplex/engine/runtime/_real_time.py
28 29 | |
RecorderObserver
Bases: BaseObserver
Observer that keeps every frame it receives.
Attributes:
| Name | Type | Description |
|---|---|---|
problem_ |
The compiled problem of the run. |
|
frames_ |
The frames received so far. |
Examples:
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import PopulationElement
>>> from skcomplex.engine.runtime import RecorderObserver, Simulation
>>> recorder = RecorderObserver()
>>> simulation = Simulation(System(elements=[PopulationElement('a')]), dt=1, observers=[recorder])
>>> _ = simulation.check().prepare().run(until=2)
>>> len(recorder.trajectory_.times)
3
trajectory_
property
Trajectory of the frames received so far.
Simulation(system, *, compiler=None, solver=None, backend=None, dt=None, clock=None, observers=(), record=True, random_state=None, checked=False, schedule=None, observables=(), invariants=None, initial_state=None)
Bases: BaseConfig[None, float]
Simulation of a system with the solver of its form.
Each frame advances simulated time by dt and is handed to every observer. Parameters can change between
frames through update_parameters, also while a background run started with start is going. Values set
between runs stay in force for the later runs of the simulation, and extend continues a run from its last
frame.
A simulation composes the pipeline of the engine and follows its common API: check() validates the system,
prepare() compiles it and chooses the solver, and run(until) prepares and runs from time 0 until a time. A run
prepares the solver for its end time and every observer on the problem before the first frame, runs every observer
at every frame, and runs it with final=True at the end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
System | BaseProblemSpec
|
The system to simulate, or a problem already compiled from one, which skips compiling for repeated runs that change only parameters or initial values. |
required |
compiler
|
BaseCompiler | None
|
The compiler of the system, whose backend, solver, and observables the simulation sets, or |
None
|
solver
|
BaseSolver | None
|
The solver, or |
None
|
backend
|
BaseBackend | None
|
The backend that compiles the system, or |
None
|
dt
|
float | None
|
The simulated time between frames. It defaults to 1 for discrete maps and agent-based models. Otherwise it defaults to 0.01, raised to the smallest of 0.02, 0.05, 0.1, 0.2, and so on, in steps of 1, 2, and 5 times a power of ten, that keeps a run at most 1000 frames long. |
None
|
clock
|
BaseClock | None
|
The clock that paces frames against wall time. It defaults to running as fast as possible. |
None
|
observers
|
Sequence[BaseObserver]
|
The observers that receive every frame. |
()
|
record
|
bool
|
Whether to record the frames as the trajectory |
True
|
random_state
|
int | Generator | None
|
The seed or generator of stochastic solvers. A seed starts a stream spawned from
|
None
|
checked
|
bool
|
Whether to check after every frame that every state lies in its domain, such as an alphabet of labels, and raise an error naming the state when it does not. |
False
|
schedule
|
Mapping[str, Callable[[float], float | ArrayLike]] | None
|
A mapping from dotted parameter name to a function of time, such as a ramp of a control parameter. At every frame the parameter takes the value of its function at the frame's time and keeps it until the next frame. An adaptive parameter, such as a bounded control input, can be scheduled too, and the trajectory records its scheduled values. |
None
|
observables
|
Sequence[ObservableSpec]
|
The observables to compute and record at every frame, labelled by their path from the root, such as
|
()
|
invariants
|
Mapping[str, float] | None
|
The tolerance of every observable that must stay constant, by the path of the observable. At every frame
the run checks that each stays within its tolerance of its value at the first frame, and raises a
|
None
|
initial_state
|
Mapping[str, object] | None
|
Initial values that replace those of the elements, by dotted state name, such as |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
problem_ |
The compiled problem. |
|
stepper_ |
The stepper that advances the problem. |
|
time_ |
The simulated time of the last frame. |
|
state_ |
The state vector of the last frame. |
|
parameters_ |
The current parameter vector. |
Examples:
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import LogisticGrowthInteraction, PopulationElement
>>> from skcomplex.engine.runtime import Simulation
>>> system = System(
... elements=[PopulationElement('rabbits', n=10)],
... interactions=[LogisticGrowthInteraction('growth', target='rabbits', r=1.0, K=100)],
... )
>>> simulation = Simulation(system, dt=1.0).check().prepare().run(until=20)
>>> round(simulation.trajectory_.values('rabbits.n')[-1])
100
Source code in src/skcomplex/engine/runtime/_simulations.py
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
trajectory_
property
Trajectory of the frames recorded so far.
extend(until)
Continue a finished run from its last frame to until in the calling thread.
The run keeps its state, parameters, stepper, clock, observers, and frame duration, applies pending parameter
changes, and appends its frames to the trajectory. A solver that closes an external process at the end of a
run, such as LammpsSolver, cannot continue it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
until
|
float
|
The simulated time to stop at, later than the time of the last frame. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
simulation |
Self
|
The simulation itself. |
Raises:
| Type | Description |
|---|---|
SimulationError
|
The simulation has not run, is running in the background, ended at a terminal event, or |
Examples:
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import LogisticGrowthInteraction, PopulationElement
>>> from skcomplex.engine.runtime import Simulation
>>> system = System(
... elements=[PopulationElement('rabbits', n=10)],
... interactions=[LogisticGrowthInteraction('growth', target='rabbits', r=1.0, K=100)],
... )
>>> simulation = Simulation(system, dt=1.0).check().prepare().run(until=5)
>>> simulation.update_parameters({'growth.r': 0.0})
>>> trajectory = simulation.extend(until=10).trajectory_
>>> trajectory.times.tolist()
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
>>> bool(trajectory.values('rabbits.n')[5] == trajectory.values('rabbits.n')[10])
True
Source code in src/skcomplex/engine/runtime/_simulations.py
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | |
pause()
Pause a background run before its next frame.
Source code in src/skcomplex/engine/runtime/_simulations.py
573 574 575 576 | |
prepare(context=None)
Compile the system of the checked simulation and choose the solver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
None
|
Nothing: a simulation prepares on its own system. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
self |
Self
|
The prepared simulation, with the compiled problem |
Source code in src/skcomplex/engine/runtime/_simulations.py
445 446 447 448 449 450 451 452 453 454 455 456 | |
resume()
Resume a paused background run.
Source code in src/skcomplex/engine/runtime/_simulations.py
578 579 580 581 | |
run(until=None, final=False)
Run the prepared simulation from time 0 to until in the calling thread.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
until
|
float | None
|
The simulated time to stop at. |
None
|
final
|
bool
|
Whether this is the last call, after which the simulation releases what preparing acquired. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
simulation |
Self
|
The simulation itself. |
Raises:
| Type | Description |
|---|---|
NotPreparedError
|
The simulation was not prepared with |
ValidationError
|
No end time is passed. |
Source code in src/skcomplex/engine/runtime/_simulations.py
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | |
start(until=math.inf)
Start the simulation from time 0 in a background thread.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
until
|
float
|
The simulated time to stop at. The default runs until |
inf
|
Returns:
| Name | Type | Description |
|---|---|---|
simulation |
Self
|
The simulation itself. |
Source code in src/skcomplex/engine/runtime/_simulations.py
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | |
stop()
Stop a background run after its current frame and wait for its thread to end.
Source code in src/skcomplex/engine/runtime/_simulations.py
601 602 603 604 605 606 | |
update_parameters(values)
Set parameter values by dotted name, applied before the next frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
Mapping[str, float | ArrayLike]
|
A mapping from dotted parameter name, such as |
required |
Raises:
| Type | Description |
|---|---|
ParameterError
|
A name is not a parameter or a parameter component of the problem, or a value would make a transition or emission matrix negative or its rows not sum to 1. |
ValidationError
|
A value has the wrong shape or is outside the domain of its parameter. |
Source code in src/skcomplex/engine/runtime/_simulations.py
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | |
wait(timeout=None)
Wait for a background run to finish and raise any error it met.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float | None
|
The longest time in seconds to wait, or |
None
|
Raises:
| Type | Description |
|---|---|
BaseException
|
The error that ended the background run, if any. |
Source code in src/skcomplex/engine/runtime/_simulations.py
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | |
Trajectory(problem, times, states, parameters, *, agents=(), reporters=(), observables=(), events=(), structures=())
Recorded states and parameters of a simulation over time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
problem
|
BaseProblemSpec
|
The compiled problem, which gives the names of the vector components. |
required |
times
|
NDArray[float64]
|
The time of each recorded frame. |
required |
states
|
NDArray[float64]
|
One state vector per row. |
required |
parameters
|
NDArray[float64]
|
One parameter vector per row. |
required |
agents
|
Sequence[Mapping[str, AgentSnapshotSpec]]
|
One mapping from agent group path to agents per frame, empty for problems without agents. |
()
|
reporters
|
Sequence[Mapping[str, float]]
|
One mapping from dotted reporter name to value per frame, empty for problems without reporters. |
()
|
observables
|
Sequence[Mapping[str, object]]
|
One mapping from observable path to value per frame, empty for systems without observables. |
()
|
events
|
Sequence[BaseRecordSpec]
|
The events that fired during the run, in order, each with its time and the states before and after its reset, the cascades of lattices with their sizes, durations, and areas, and the renewals of renewal laws with their members. |
()
|
structures
|
Sequence[Mapping[str, object]]
|
One mapping from rewritten element path to its structure per frame, empty for other systems. |
()
|
Examples:
>>> from skcomplex.core.system import System
>>> from skcomplex.models.biology.common.populations import ExponentialGrowthInteraction, PopulationElement
>>> from skcomplex.engine.runtime import Simulation
>>> system = System(
... elements=[PopulationElement('a', n=1)],
... interactions=[ExponentialGrowthInteraction('g', target='a', r=1)],
... )
>>> trajectory = Simulation(system, dt=0.5).check().prepare().run(until=1).trajectory_
>>> trajectory.times.tolist()
[0.0, 0.5, 1.0]
>>> trajectory.values('a.n').round(3).tolist()
[1.0, 1.649, 2.718]
Source code in src/skcomplex/engine/runtime/_trajectories.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
names
property
Names of the states, parameters, reporters, and observables that values reads.
agent_locations(group)
Return the locations of the agents of a group, one array per frame with one row per agent alive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
str
|
The path of the agent group. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
locations |
list[AnyArray]
|
The locations at every frame, empty arrays for frames without locations. |
Examples:
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.models import create
>>> trajectory = Simulation(create('boids'), random_state=0).check().prepare().run(until=2).trajectory_
>>> [locations.shape[1] for locations in trajectory.agent_locations('flock')]
[2, 2, 2]
Source code in src/skcomplex/engine/runtime/_trajectories.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
agents(group, frame)
Return the agents of a group alive at a frame, with their ids, states, and locations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
str
|
The path of the agent group. |
required |
frame
|
int
|
The index of the frame. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
agents |
AgentSnapshotSpec
|
The agents of the group at that frame. |
Raises:
| Type | Description |
|---|---|
KeyError
|
The trajectory has no agent group of that path. |
Source code in src/skcomplex/engine/runtime/_trajectories.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
lattice(name)
Return the values of a lattice state over time in lattice shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The dotted name of a state of a lattice group, such as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
values |
AnyArray
|
One array of the lattice shape per frame, with the components of a vector or a tensor state on a last axis. |
Raises:
| Type | Description |
|---|---|
KeyError
|
The name is not a state of a lattice group. |
Source code in src/skcomplex/engine/runtime/_trajectories.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | |
member(index, problem)
Return the trajectory of one member of a replicated system, as a trajectory of the original system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
index
|
int
|
The member index, the same in every group of the replicated system. |
required |
problem
|
BaseProblemSpec
|
The compiled original system, whose single elements the replicated groups hold. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
trajectory |
Trajectory
|
The times, states, and parameters of the member, laid out as the original problem lays them out. |
Examples:
>>> import numpy as np
>>> from skcomplex.engine.compile import compile_system
>>> from skcomplex.engine.runtime import Simulation
>>> from skcomplex.experiments import BaseExperiment
>>> from skcomplex.models.mathematics.dynamical_systems import logistic_map
>>> ensemble = BaseExperiment._replicate(logistic_map(), 3, {'map.x': [0.1, 0.2, 0.3]})
>>> trajectory = Simulation(ensemble, dt=1).check().prepare().run(until=2).trajectory_
>>> float(trajectory.member(1, compile_system(logistic_map())).values('map.x')[0])
0.2
Source code in src/skcomplex/engine/runtime/_trajectories.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
network(frame, nodes=None, layer=None)
Return the nodes and edges of a network whose topology changes, as they are at a frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
int
|
The index of the frame. |
required |
nodes
|
str | None
|
The path of a variable group on the nodes of the network, or |
None
|
layer
|
str | None
|
The layer, or |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
snapshot |
NetworkSnapshotSpec
|
The rows of the nodes present and the ends and rows of the edges present. |
Raises:
| Type | Description |
|---|---|
KeyError
|
The system has no network whose topology changes. |
Source code in src/skcomplex/engine/runtime/_trajectories.py
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
structure(path, frame)
Return the word or patch of a rewritten element at a frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
The path of the rewritten element. |
required |
frame
|
int
|
The index of the frame. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
structure |
object
|
The structure recorded at that frame, which later generations do not change. |
Raises:
| Type | Description |
|---|---|
KeyError
|
The path is not a rewritten element of the system. |
Examples:
>>> from skcomplex.models import run
>>> trajectory = run('cantor_set', settings={'until': 4}).trajectory_
>>> trajectory.structure('cantor', 2).parts
4
Source code in src/skcomplex/engine/runtime/_trajectories.py
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | |
values(name)
Return the values of a state or a parameter over time by dotted name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The dotted name, such as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
values |
AnyArray
|
One value per frame for a scalar, or one row per frame for a vector, NaN in the rows of a variable group on a network that hold no member at a frame. |
Raises:
| Type | Description |
|---|---|
KeyError
|
The name is neither a state nor a parameter. |
Source code in src/skcomplex/engine/runtime/_trajectories.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |