Name | pathsim JSON |
Version |
0.7.1
JSON |
| download |
home_page | None |
Summary | A differentiable block based hybrid system simulation framework. |
upload_time | 2025-07-28 13:51:14 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | MIT |
keywords |
simulation
differentiable
hybrid systems
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
<p align="center">
<img src="https://raw.githubusercontent.com/milanofthe/pathsim/master/docs/source/logos/pathsim_logo.png" width="300" alt="Pathsim Logo" />
</p>
------------
# PathSim - A System Simulation Framework
[](https://doi.org/10.21105/joss.08158)


[](https://pathsim.readthedocs.io/en/latest/?badge=latest)

[](https://codecov.io/gh/pathsim/pathsim)
## Overview
**PathSim** is a flexible block-based time-domain system simulation framework in Python with automatic differentiation capabilities and an event handling mechanism! It provides a variety of classes that enable modeling and simulating complex interconnected dynamical systems through Python scripting in the block diagram paradigm.
All of that with minimal dependencies, only `numpy`, `scipy` and `matplotlib` (and `dill` if you want to use serialization)!
Key Features:
- **Dynamic system modification** at simulation runtime, i.e. triggered through events
- Automatic block- and system-level **linearization** at runtime
- Wide range of **numerical integrators** (implicit, explicit, high order, adaptive), able to handle [stiff systems](#stiff-systems)
- **Modular and hierarchical** modeling with (nested) subsystems
- [Event handling](#event-detection) system to detect and resolve **discrete events** (zero-crossing detection)
- **Automatic differentiation** for end-to-end [differentiable simulations](#differentiable-simulation)
- **Extensibility** by subclassing the base `Block` class and implementing just a handful of methods
For the full **documentation**, tutorials and API-reference visit [Read the Docs](https://pathsim.readthedocs.io/en/latest/)!
The source code can be found in the [GitHub repository](https://github.com/milanofthe/pathsim) and is fully open source under **MIT license**. Consider starring PathSim to support its development.
## Contributing and Future
If you want to contribute to **PathSim**s development, check out the [community guidelines](https://pathsim.readthedocs.io/en/latest/contributing). If you are curious about what the future holds for **PathSim**, check out the [roadmap](https://pathsim.readthedocs.io/en/latest/roadmap)!
## Installation
The latest release version of PathSim is available on [PyPi](https://pypi.org/project/pathsim/) and installable via pip:
```console
pip install pathsim
```
## Example - Harmonic Oscillator
There are lots of [examples](https://github.com/milanofthe/pathsim/tree/master/examples) of dynamical system simulations in the GitHub repository that showcase PathSim's capabilities.
But first, lets have a look at how we can simulate the harmonic oscillator (a spring mass damper 2nd order system) using PathSim. The system and its corresponding equivalent block diagram are shown in the figure below:

The equation of motion that defines the harmonic oscillator it is give by
$$
\ddot{x} + \frac{c}{m} \dot{x} + \frac{k}{m} x = 0
$$
where $c$ is the damping, $k$ the spring constant and $m$ the mass together with the initial conditions $x_0$ and $v_0$ for position and velocity.
The topology of the block diagram above can be directly defined as blocks and connections in the PathSim framework. First we initialize the blocks needed to represent the dynamical systems with their respective arguments such as initial conditions and gain values, then the blocks are connected using `Connection` objects, forming two feedback loops.
The `Simulation` instance manages the blocks and connections and advances the system in time with the timestep (`dt`). The `log` flag for logging the simulation progress is also set. Finally, we run the simulation for some number of seconds and plot the results using the `plot()` method of the scope block.
```python
from pathsim import Simulation, Connection
#import the blocks we need for the harmonic oscillator
from pathsim.blocks import Integrator, Amplifier, Adder, Scope
#initial position and velocity
x0, v0 = 2, 5
#parameters (mass, damping, spring constant)
m, c, k = 0.8, 0.2, 1.5
#define the blocks
I1 = Integrator(v0) # integrator for velocity
I2 = Integrator(x0) # integrator for position
A1 = Amplifier(-c/m)
A2 = Amplifier(-k/m)
P1 = Adder()
Sc = Scope(labels=["v(t)", "x(t)"])
blocks = [I1, I2, A1, A2, P1, Sc]
#define the connections between the blocks
connections = [
Connection(I1, I2, A1, Sc), # one to many connection
Connection(I2, A2, Sc[1]),
Connection(A1, P1), # default connection to port 0
Connection(A2, P1[1]), # specific connection to port 1
Connection(P1, I1)
]
#create a simulation instance from the blocks and connections
Sim = Simulation(blocks, connections, dt=0.05)
#run the simulation for 30 seconds
Sim.run(duration=30.0)
#plot the results directly from the scope
Sc.plot()
#read the results from the scope for further processing
time, data = Sc.read()
```

## Stiff Systems
PathSim implements a large variety of implicit integrators such as diagonally implicit runge-kutta (`DIRK2`, `ESDIRK43`, etc.) and multistep (`BDF2`, `GEAR52A`, etc.) methods. This enables the simulation of very stiff systems where the timestep is limited by stability and not accuracy of the method.
A common example for a stiff system is the Van der Pol oscillator where the parameter $\mu$ "controls" the severity of the stiffness. It is defined by the following second order ODE:
$$
\ddot{x} + \mu (1 - x^2) \dot{x} + x = 0
$$
The Van der Pol ODE can be translated into a block diagram like the one below, where the two states are handled by two distinct integrators.

Lets translate it to PathSim using two `Integrator` blocks and a `Function` block. The parameter is set to $\mu = 1000$ which means severe stiffness.
```python
from pathsim import Simulation, Connection
from pathsim.blocks import Integrator, Scope, Function
#implicit adaptive timestep solver
from pathsim.solvers import ESDIRK54
#initial conditions
x1, x2 = 2, 0
#van der Pol parameter (1000 is very stiff)
mu = 1000
#blocks that define the system
Sc = Scope(labels=["$x_1(t)$"])
I1 = Integrator(x1)
I2 = Integrator(x2)
Fn = Function(lambda x1, x2: mu*(1 - x1**2)*x2 - x1)
blocks = [I1, I2, Fn, Sc]
#the connections between the blocks
connections = [
Connection(I2, I1, Fn[1]),
Connection(I1, Fn, Sc),
Connection(Fn, I2)
]
#initialize simulation with the blocks, connections, timestep and logging enabled
Sim = Simulation(
blocks,
connections,
dt=0.05,
Solver=ESDIRK54,
tolerance_lte_abs=1e-5,
tolerance_lte_rel=1e-3
)
#run simulation for some number of seconds
Sim.run(3*mu)
#plot the results directly (steps highlighted)
Sc.plot(".-")
```

## Differentiable Simulation
PathSim also includes a fully fledged automatic differentiation framework based on a dual number system with overloaded operators and numpy ufunc integration. This makes the system simulation fully differentiable end-to-end with respect to a predefined set of parameters. Works with all integrators, adaptive, fixed, implicit, explicit.
To demonstrate this lets consider the following linear feedback system and perform a sensitivity analysis on it with respect to some system parameters.

The source term is a scaled unit step function (scaled by $b$). In this example, the parameters for the sensitivity analysis are the feedback term $a$, the initial condition $x_0$ and the amplitude of the source term $b$.
```python
from pathsim import Simulation, Connection
from pathsim.blocks import Source, Integrator, Amplifier, Adder, Scope
#AD module
from pathsim.optim import Value, der
#values for derivative propagation / parameters for sensitivity analysis
a = Value(-1)
b = Value(1)
x0 = Value(2)
#simulation timestep
dt = 0.01
#step function
tau = 3
def s(t):
return b*int(t>tau)
#blocks that define the system
Src = Source(s)
Int = Integrator(x0)
Amp = Amplifier(a)
Add = Adder()
Sco = Scope(labels=["step", "response"])
blocks = [Src, Int, Amp, Add, Sco]
#the connections between the blocks
connections = [
Connection(Src, Add[0], Sco[0]),
Connection(Amp, Add[1]),
Connection(Add, Int),
Connection(Int, Amp, Sco[1])
]
#initialize simulation with the blocks, connections, timestep
Sim = Simulation(blocks, connections, dt=dt)
#run the simulation for some time
Sim.run(4*tau)
Sco.plot()
```

Now the recorded time series data is of type `Value` and we can evaluate the automatically computed partial derivatives at each timestep. For example the response, differentiated with respect to the linear feedback parameter $\partial x(t) / \partial a$ can be extracted from the data like this `der(data, a)`.
```python
import matplotlib.pyplot as plt
#read data from the scope
time, [step, data] = Sco.read()
fig, ax = plt.subplots(nrows=1, tight_layout=True, figsize=(8, 4), dpi=120)
#evaluate and plot partial derivatives
ax.plot(time, der(data, a), label=r"$\partial x / \partial a$")
ax.plot(time, der(data, x0), label=r"$\partial x / \partial x_0$")
ax.plot(time, der(data, b), label=r"$\partial x / \partial b$")
ax.set_xlabel("time [s]")
ax.grid(True)
ax.legend(fancybox=False)
```

## Event Detection
PathSim has an event handling system that monitors the simulation state and can find and locate discrete events by evaluating an event function and trigger callbacks or state transformations. Multiple event types are supported such as `ZeroCrossing` or `Schedule`.
This enables the simulation of hybrid continuous time systems with discrete events.

Probably the most popular example for this is the bouncing ball (see figure above) where discrete events occur whenever the ball touches the floor. The event in this case is a zero-crossing.
The dynamics of this system can be translated into a block diagramm in the following way:

And built and simulated with `PathSim` like this:
```python
from pathsim import Simulation, Connection
from pathsim.blocks import Integrator, Constant, Scope
from pathsim.solvers import RKBS32
#event library
from pathsim.events import ZeroCrossing
#initial values
x0, v0 = 1, 10
#blocks that define the system
Ix = Integrator(x0) # v -> x
Iv = Integrator(v0) # a -> v
Cn = Constant(-9.81) # gravitational acceleration
Sc = Scope(labels=["x", "v"])
blocks = [Ix, Iv, Cn, Sc]
#the connections between the blocks
connections = [
Connection(Cn, Iv),
Connection(Iv, Ix),
Connection(Ix, Sc)
]
#event function for zero crossing detection
def func_evt(t):
i, o, s = Ix() #get block inputs, outputs and states
return s
#action function for state transformation
def func_act(t):
i1, o1, s1 = Ix()
i2, o2, s2 = Iv()
Ix.engine.set(abs(s1))
Iv.engine.set(-0.9*s2)
#event (zero-crossing) -> ball makes contact
E1 = ZeroCrossing(
func_evt=func_evt,
func_act=func_act,
tolerance=1e-4
)
events = [E1]
#initialize simulation with the blocks, connections, timestep
Sim = Simulation(
blocks,
connections,
events,
dt=0.1,
Solver=RKBS32,
dt_max=0.1
)
#run the simulation
Sim.run(20)
#plot the recordings from the scope
Sc.plot()
```

During the event handling, the simulator approaches the event until the specified tolerance is met. You can see this by analyzing the timesteps taken by the adaptive integrator `RKBS32`.
```python
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8,4), tight_layout=True, dpi=120)
time, _ = Sc.read()
#add detected events
for t in E1: ax.axvline(t, ls="--", c="k")
#plot the timesteps
ax.plot(time[:-1], np.diff(time))
ax.set_yscale("log")
ax.set_ylabel("dt [s]")
ax.set_xlabel("time [s]")
ax.grid(True)
```

Raw data
{
"_id": null,
"home_page": null,
"name": "pathsim",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "simulation, differentiable, hybrid systems",
"author": null,
"author_email": "Milan Rother <milan.rother@gmx.de>",
"download_url": "https://files.pythonhosted.org/packages/03/7a/a05313b11aa53f236f3c96e2b5e1bb5d8e54db4af97e07b5021beefe270f/pathsim-0.7.1.tar.gz",
"platform": null,
"description": "\n\n<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/milanofthe/pathsim/master/docs/source/logos/pathsim_logo.png\" width=\"300\" alt=\"Pathsim Logo\" />\n</p>\n\n------------\n\n\n# PathSim - A System Simulation Framework\n[](https://doi.org/10.21105/joss.08158)\n\n\n[](https://pathsim.readthedocs.io/en/latest/?badge=latest)\n\n[](https://codecov.io/gh/pathsim/pathsim)\n\n\n## Overview\n\n**PathSim** is a flexible block-based time-domain system simulation framework in Python with automatic differentiation capabilities and an event handling mechanism! It provides a variety of classes that enable modeling and simulating complex interconnected dynamical systems through Python scripting in the block diagram paradigm.\n\nAll of that with minimal dependencies, only `numpy`, `scipy` and `matplotlib` (and `dill` if you want to use serialization)!\n\nKey Features:\n\n- **Dynamic system modification** at simulation runtime, i.e. triggered through events\n- Automatic block- and system-level **linearization** at runtime\n- Wide range of **numerical integrators** (implicit, explicit, high order, adaptive), able to handle [stiff systems](#stiff-systems)\n- **Modular and hierarchical** modeling with (nested) subsystems\n- [Event handling](#event-detection) system to detect and resolve **discrete events** (zero-crossing detection)\n- **Automatic differentiation** for end-to-end [differentiable simulations](#differentiable-simulation)\n- **Extensibility** by subclassing the base `Block` class and implementing just a handful of methods\n\n\nFor the full **documentation**, tutorials and API-reference visit [Read the Docs](https://pathsim.readthedocs.io/en/latest/)!\n\nThe source code can be found in the [GitHub repository](https://github.com/milanofthe/pathsim) and is fully open source under **MIT license**. Consider starring PathSim to support its development.\n\n\n## Contributing and Future\n\nIf you want to contribute to **PathSim**s development, check out the [community guidelines](https://pathsim.readthedocs.io/en/latest/contributing). If you are curious about what the future holds for **PathSim**, check out the [roadmap](https://pathsim.readthedocs.io/en/latest/roadmap)!\n\n\n## Installation\n\nThe latest release version of PathSim is available on [PyPi](https://pypi.org/project/pathsim/) and installable via pip:\n\n```console\npip install pathsim\n```\n\n## Example - Harmonic Oscillator\n\nThere are lots of [examples](https://github.com/milanofthe/pathsim/tree/master/examples) of dynamical system simulations in the GitHub repository that showcase PathSim's capabilities. \n\nBut first, lets have a look at how we can simulate the harmonic oscillator (a spring mass damper 2nd order system) using PathSim. The system and its corresponding equivalent block diagram are shown in the figure below:\n\n\n\n\n\nThe equation of motion that defines the harmonic oscillator it is give by\n\n$$\n\\ddot{x} + \\frac{c}{m} \\dot{x} + \\frac{k}{m} x = 0\n$$\n\nwhere $c$ is the damping, $k$ the spring constant and $m$ the mass together with the initial conditions $x_0$ and $v_0$ for position and velocity.\n\nThe topology of the block diagram above can be directly defined as blocks and connections in the PathSim framework. First we initialize the blocks needed to represent the dynamical systems with their respective arguments such as initial conditions and gain values, then the blocks are connected using `Connection` objects, forming two feedback loops.\n\nThe `Simulation` instance manages the blocks and connections and advances the system in time with the timestep (`dt`). The `log` flag for logging the simulation progress is also set. Finally, we run the simulation for some number of seconds and plot the results using the `plot()` method of the scope block.\n\n\n```python\nfrom pathsim import Simulation, Connection\n\n#import the blocks we need for the harmonic oscillator\nfrom pathsim.blocks import Integrator, Amplifier, Adder, Scope\n\n#initial position and velocity\nx0, v0 = 2, 5\n\n#parameters (mass, damping, spring constant)\nm, c, k = 0.8, 0.2, 1.5\n\n#define the blocks \nI1 = Integrator(v0) # integrator for velocity\nI2 = Integrator(x0) # integrator for position\nA1 = Amplifier(-c/m)\nA2 = Amplifier(-k/m)\nP1 = Adder()\nSc = Scope(labels=[\"v(t)\", \"x(t)\"])\n\nblocks = [I1, I2, A1, A2, P1, Sc]\n\n#define the connections between the blocks\nconnections = [\n Connection(I1, I2, A1, Sc), # one to many connection\n Connection(I2, A2, Sc[1]),\n Connection(A1, P1), # default connection to port 0\n Connection(A2, P1[1]), # specific connection to port 1\n Connection(P1, I1)\n ]\n\n#create a simulation instance from the blocks and connections\nSim = Simulation(blocks, connections, dt=0.05)\n\n#run the simulation for 30 seconds\nSim.run(duration=30.0)\n\n#plot the results directly from the scope\nSc.plot()\n\n#read the results from the scope for further processing\ntime, data = Sc.read()\n```\n\n\n\n\n## Stiff Systems\n\nPathSim implements a large variety of implicit integrators such as diagonally implicit runge-kutta (`DIRK2`, `ESDIRK43`, etc.) and multistep (`BDF2`, `GEAR52A`, etc.) methods. This enables the simulation of very stiff systems where the timestep is limited by stability and not accuracy of the method.\n\nA common example for a stiff system is the Van der Pol oscillator where the parameter $\\mu$ \"controls\" the severity of the stiffness. It is defined by the following second order ODE:\n\n$$\n\\ddot{x} + \\mu (1 - x^2) \\dot{x} + x = 0\n$$\n\nThe Van der Pol ODE can be translated into a block diagram like the one below, where the two states are handled by two distinct integrators.\n\n\n\n\n\nLets translate it to PathSim using two `Integrator` blocks and a `Function` block. The parameter is set to $\\mu = 1000$ which means severe stiffness. \n\n\n```python\nfrom pathsim import Simulation, Connection\nfrom pathsim.blocks import Integrator, Scope, Function\n\n#implicit adaptive timestep solver \nfrom pathsim.solvers import ESDIRK54\n\n#initial conditions\nx1, x2 = 2, 0\n\n#van der Pol parameter (1000 is very stiff)\nmu = 1000\n\n#blocks that define the system\nSc = Scope(labels=[\"$x_1(t)$\"])\nI1 = Integrator(x1)\nI2 = Integrator(x2)\nFn = Function(lambda x1, x2: mu*(1 - x1**2)*x2 - x1)\n\nblocks = [I1, I2, Fn, Sc]\n\n#the connections between the blocks\nconnections = [\n Connection(I2, I1, Fn[1]), \n Connection(I1, Fn, Sc), \n Connection(Fn, I2)\n ]\n\n#initialize simulation with the blocks, connections, timestep and logging enabled\nSim = Simulation(\n blocks, \n connections, \n dt=0.05, \n Solver=ESDIRK54, \n tolerance_lte_abs=1e-5, \n tolerance_lte_rel=1e-3\n )\n\n#run simulation for some number of seconds\nSim.run(3*mu)\n\n#plot the results directly (steps highlighted)\nSc.plot(\".-\")\n```\n\n\n\n\n\n## Differentiable Simulation\n\nPathSim also includes a fully fledged automatic differentiation framework based on a dual number system with overloaded operators and numpy ufunc integration. This makes the system simulation fully differentiable end-to-end with respect to a predefined set of parameters. Works with all integrators, adaptive, fixed, implicit, explicit. \n\nTo demonstrate this lets consider the following linear feedback system and perform a sensitivity analysis on it with respect to some system parameters. \n\n\n\n\n\nThe source term is a scaled unit step function (scaled by $b$). In this example, the parameters for the sensitivity analysis are the feedback term $a$, the initial condition $x_0$ and the amplitude of the source term $b$.\n\n\n```python\nfrom pathsim import Simulation, Connection\nfrom pathsim.blocks import Source, Integrator, Amplifier, Adder, Scope\n\n#AD module\nfrom pathsim.optim import Value, der\n\n#values for derivative propagation / parameters for sensitivity analysis\na = Value(-1)\nb = Value(1)\nx0 = Value(2)\n\n#simulation timestep\ndt = 0.01\n\n#step function\ntau = 3\ndef s(t):\n return b*int(t>tau)\n\n#blocks that define the system\nSrc = Source(s)\nInt = Integrator(x0)\nAmp = Amplifier(a)\nAdd = Adder()\nSco = Scope(labels=[\"step\", \"response\"])\n\nblocks = [Src, Int, Amp, Add, Sco]\n\n#the connections between the blocks\nconnections = [\n Connection(Src, Add[0], Sco[0]),\n Connection(Amp, Add[1]),\n Connection(Add, Int),\n Connection(Int, Amp, Sco[1])\n ]\n\n#initialize simulation with the blocks, connections, timestep\nSim = Simulation(blocks, connections, dt=dt)\n \n#run the simulation for some time\nSim.run(4*tau)\n\nSco.plot()\n```\n\n\n\n\n\nNow the recorded time series data is of type `Value` and we can evaluate the automatically computed partial derivatives at each timestep. For example the response, differentiated with respect to the linear feedback parameter $\\partial x(t) / \\partial a$ can be extracted from the data like this `der(data, a)`.\n\n\n```python\nimport matplotlib.pyplot as plt\n\n#read data from the scope\ntime, [step, data] = Sco.read()\n\nfig, ax = plt.subplots(nrows=1, tight_layout=True, figsize=(8, 4), dpi=120)\n\n#evaluate and plot partial derivatives\nax.plot(time, der(data, a), label=r\"$\\partial x / \\partial a$\")\nax.plot(time, der(data, x0), label=r\"$\\partial x / \\partial x_0$\")\nax.plot(time, der(data, b), label=r\"$\\partial x / \\partial b$\")\n\nax.set_xlabel(\"time [s]\")\nax.grid(True)\nax.legend(fancybox=False)\n```\n\n\n\n\n## Event Detection\n\nPathSim has an event handling system that monitors the simulation state and can find and locate discrete events by evaluating an event function and trigger callbacks or state transformations. Multiple event types are supported such as `ZeroCrossing` or `Schedule`. \n\nThis enables the simulation of hybrid continuous time systems with discrete events. \n\n\n\n\n\nProbably the most popular example for this is the bouncing ball (see figure above) where discrete events occur whenever the ball touches the floor. The event in this case is a zero-crossing.\n\nThe dynamics of this system can be translated into a block diagramm in the following way:\n\n\n\n\n\nAnd built and simulated with `PathSim` like this:\n\n```python\nfrom pathsim import Simulation, Connection\nfrom pathsim.blocks import Integrator, Constant, Scope\nfrom pathsim.solvers import RKBS32\n\n#event library\nfrom pathsim.events import ZeroCrossing\n\n#initial values\nx0, v0 = 1, 10\n\n#blocks that define the system\nIx = Integrator(x0) # v -> x\nIv = Integrator(v0) # a -> v \nCn = Constant(-9.81) # gravitational acceleration\nSc = Scope(labels=[\"x\", \"v\"])\n\nblocks = [Ix, Iv, Cn, Sc]\n\n#the connections between the blocks\nconnections = [\n Connection(Cn, Iv),\n Connection(Iv, Ix),\n Connection(Ix, Sc)\n ]\n\n#event function for zero crossing detection\ndef func_evt(t):\n i, o, s = Ix() #get block inputs, outputs and states\n return s\n\n#action function for state transformation\ndef func_act(t):\n i1, o1, s1 = Ix() \n i2, o2, s2 = Iv() \n Ix.engine.set(abs(s1))\n Iv.engine.set(-0.9*s2)\n\n#event (zero-crossing) -> ball makes contact\nE1 = ZeroCrossing(\n func_evt=func_evt, \n func_act=func_act, \n tolerance=1e-4\n )\n\nevents = [E1]\n\n#initialize simulation with the blocks, connections, timestep\nSim = Simulation(\n blocks, \n connections, \n events, \n dt=0.1, \n Solver=RKBS32, \n dt_max=0.1\n )\n\n#run the simulation\nSim.run(20)\n\n#plot the recordings from the scope\nSc.plot()\n```\n\n\n\nDuring the event handling, the simulator approaches the event until the specified tolerance is met. You can see this by analyzing the timesteps taken by the adaptive integrator `RKBS32`.\n\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfig, ax = plt.subplots(figsize=(8,4), tight_layout=True, dpi=120)\n\ntime, _ = Sc.read()\n\n#add detected events\nfor t in E1: ax.axvline(t, ls=\"--\", c=\"k\")\n\n#plot the timesteps\nax.plot(time[:-1], np.diff(time))\n\nax.set_yscale(\"log\")\nax.set_ylabel(\"dt [s]\")\nax.set_xlabel(\"time [s]\")\nax.grid(True)\n```\n\n\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A differentiable block based hybrid system simulation framework.",
"version": "0.7.1",
"project_urls": {
"Homepage": "https://github.com/milanofthe/pathsim",
"documentation": "https://pathsim.readthedocs.io/en/latest/"
},
"split_keywords": [
"simulation",
" differentiable",
" hybrid systems"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5e45388672319ce8bcc990fdb16672194acb2f466db60ec10381c06308fe6bea",
"md5": "783141f2a53459f92dc014aa7c9c2013",
"sha256": "5b2dc747886ab080b11716052b09c964cc1de14d3eb6f060db726894a764d349"
},
"downloads": -1,
"filename": "pathsim-0.7.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "783141f2a53459f92dc014aa7c9c2013",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 152454,
"upload_time": "2025-07-28T13:51:12",
"upload_time_iso_8601": "2025-07-28T13:51:12.390133Z",
"url": "https://files.pythonhosted.org/packages/5e/45/388672319ce8bcc990fdb16672194acb2f466db60ec10381c06308fe6bea/pathsim-0.7.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "037aa05313b11aa53f236f3c96e2b5e1bb5d8e54db4af97e07b5021beefe270f",
"md5": "0546677aba4cd68fc74bc05c8608cf7c",
"sha256": "b4c6a903f8543cf5d21bca5a662117ca784758dc0bea8d485f736ec4399699f0"
},
"downloads": -1,
"filename": "pathsim-0.7.1.tar.gz",
"has_sig": false,
"md5_digest": "0546677aba4cd68fc74bc05c8608cf7c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 3651145,
"upload_time": "2025-07-28T13:51:14",
"upload_time_iso_8601": "2025-07-28T13:51:14.155181Z",
"url": "https://files.pythonhosted.org/packages/03/7a/a05313b11aa53f236f3c96e2b5e1bb5d8e54db4af97e07b5021beefe270f/pathsim-0.7.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-28 13:51:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "milanofthe",
"github_project": "pathsim",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pathsim"
}