vip-ivp
Solve ODEs naturally within the script's flow—no need to manually construct a system of equations.
Minimal example
import vip_ivp as vip
# Exponential decay: dN/dt = - λ * N
d_n = vip.loop_node()
n = vip.integrate(d_n, 1)
d_n.loop_into(-0.5 * n)
# Choose which variables to plot
n.to_plot("Quantity")
d_n.to_plot("Derivative")
# Solve the system. The plot will automatically show.
vip.solve(10, time_step=0.001)
Installation
To install vip-ivp, simply run the following command:
pip install vip-ivp
This will install the latest version from PyPI.
Motivation
The traditional way to solve an Initial Value Problem (IVP) is to define the function $y'=f(t,y(t))$ and pass it
into a solver, such as scipy.integrate.solve_ivp().
However, this approach becomes cumbersome and error-prone for complex systems, as both $f$ and $y$ grow in size and complexity. This is why industries rely on tools like Simulink, which provide a more intuitive, graphical approach for handling large IVP systems.
This package brings key abstractions from graphical IVP solvers into a scripting environment, enabling a more natural and modular way to define differential equations:
- Decouples the solver from the system definition.
- Builds the system incrementally, following the script’s natural flow.
- Represents differential equations as loops, improving clarity.
- Encourages a functional programming paradigm for better system architecture.
- Seamlessly integrates with the Python ecosystem, working alongside libraries like NumPy and SciPy.
Demo: Mass-spring-damper model
import vip_ivp as vip
# System parameters
m = 300.0 # Mass (kg)
c = 1500 # Damping coefficient (N.s/m)
k = 25000 # Spring stiffness (N/m)
displacement_x0 = 0.2 # Initial value of displacement (m)
# Create simulation
# System equation is: m * acc + c * vel + k * disp = 0 <=> acc = - 1 / m * (c * vel + k * disp)
# We do not have access to velocity and displacement at this stage, so we create a loop node.
acceleration = vip.loop_node()
velocity = vip.integrate(acceleration, 0)
displacement = vip.integrate(velocity, displacement_x0)
# Now we can set the acceleration
acceleration.loop_into(-(c * velocity + k * displacement) / m)
# Choose results to plot
displacement.to_plot("Displacement (m)")
velocity.to_plot("Velocity (m/s)")
# Solve the system
t_simulation = 10 # s
time_step = 0.001
vip.solve(t_simulation, time_step=time_step)
Features
Integrate
Integrate a temporal variable starting from an initial condition.
integrated_var = vip.integrate(source, x0=0)
Handle integration loops
Create loop nodes to handle feedback loops in the system.
loop = vip.loop_node(input_value=0)
loop.loop_into(integrated_var)
Loop nodes are essential to solve ODEs in a "sequential" way.
To solve an ODE, follow these steps:
- Create a loop node for the highest-order derivative of the equation:
ddy = vip.loop_node()
- Create lower-order derivatives by integration
dy = vip.integrate(ddy, dy0)
y = vip.integrate(dy, y0)
- Loop into the equation (In this example: $4 \frac{d^2y}{dt^2} + 3 \frac{dy}{dt} + 2y = 5$):
ddy.loop_into(5 - 1 / 4 * (3 * dy + 2 * y))
Create sources
Create source signals from temporal functions or scalar values.
source = vip.temporal(lambda t: 2 * t)
Solve the system of equations
Solve the system until a specified end time.
vip.solve(t_end=10,
method="RK45",
time_step=None,
t_eval=None,
plot=True,
**options)
For **options, see
the SciPy documentation.
Plot results
Plot variables with .to_plot(variable_name : str) method.
The plot is automatically created when the system is solved.
def foo():
variable = vip.temporal(5)
variable.to_plot("Variable name")
foo()
vip.solve(10) # 'variable' will be plotted, even if it was declared in a function.
Explore results
Generate an interactive plot from a given function. The plot includes sliders, allowing users to adjust input values dynamically.
This feature requires the sliderplot package:
pip install sliderplot
def mass_spring_damper_system(m=1, c=1, k=1, x0=0.2):
acceleration = vip.loop_node()
velocity = vip.integrate(acceleration, 0)
displacement = vip.integrate(velocity, x0)
acceleration.loop_into(-(c * velocity + k * displacement) / m)
return displacement
t_simulation = 50 # seconds
time_step = 0.001 # seconds
vip.explore(mass_spring_damper_system, t_simulation, time_step=time_step, title="Mass-Spring-Damper mechanism")
Advanced features
Save intermediary results
Save variables for later analysis.
Its only use-case is when the variable may be lost due to context, typically for variables that are created inside functions.
def foo():
variable = vip.temporal(5)
variable.save("bar")
foo()
bar = vip.get_var("bar")
vip.solve(10) # 'variable' will be plotted, even if it was declared in a function.
Create a new system
Initialize a new system.
If you want to simulate multiple systems in the same script, use this function. Otherwise, the previous systems will be solved again with the new one, which will be slower.
vip.new_system()
Limitations
- Temporal variables can only access their values at time $t$.
- Therefore, there is no function to compute derivatives.
Metadata
Release files for vip-ivp 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| vip_ivp-0.2.0.tar.gz | 35.8 kB | With provenance | Details for vip_ivp-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| vip_ivp-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for vip_ivp-0.2.0-py3-none-any.whl |
Total release size: 61.8 kB
Release files / vip_ivp-0.2.0.tar.gz
| Download URL | vip_ivp-0.2.0.tar.gz |
|---|---|
| Size | 35.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b417d4767faa570fe8854e33b869ada11f4dd81f23bcbc512d6eb765e8fe96f
|
|
BLAKE2b-256 checksum How to use checksums |
61612983c2b1aae03a213e76c0d1598a175ded62562b1c891f73d88e8e2df3fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 13, 2025.
Transparency logRelease files / vip_ivp-0.2.0-py3-none-any.whl
| Download URL | vip_ivp-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d245eb391e99ca35c0bfbdac9a0d8a150b5c3c4e6d2a7af33a962cbe0311d7b9
|
|
BLAKE2b-256 checksum How to use checksums |
37dfdbc8bf6a161b1857aa698174b9da4f2e2aa93a83a14bcfeea65bcf771fef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 13, 2025.
Transparency logSecurity for vip-ivp 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for vip_ivp-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 13, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.