Skip to main content

Solve ODEs without having to build the system of equations.

Project description

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:

  1. Create a loop node for the highest-order derivative of the equation:
ddy = vip.loop_node()
  1. Create lower-order derivatives by integration
dy = vip.integrate(ddy, dy0)
y = vip.integrate(dy, y0)
  1. 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vip_ivp-0.2.0.tar.gz (35.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vip_ivp-0.2.0-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file vip_ivp-0.2.0.tar.gz.

File metadata

  • Download URL: vip_ivp-0.2.0.tar.gz
  • Upload date:
  • Size: 35.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for vip_ivp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3b417d4767faa570fe8854e33b869ada11f4dd81f23bcbc512d6eb765e8fe96f
MD5 763320c478b5feeac4263f6284fc03f9
BLAKE2b-256 61612983c2b1aae03a213e76c0d1598a175ded62562b1c891f73d88e8e2df3fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for vip_ivp-0.2.0.tar.gz:

Publisher: python-publish.yml on ngripon/vip-ivp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vip_ivp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: vip_ivp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 26.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for vip_ivp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d245eb391e99ca35c0bfbdac9a0d8a150b5c3c4e6d2a7af33a962cbe0311d7b9
MD5 e9826e39c9a6ebf8470ac9591cad48e7
BLAKE2b-256 37dfdbc8bf6a161b1857aa698174b9da4f2e2aa93a83a14bcfeea65bcf771fef

See more details on using hashes here.

Provenance

The following attestation bundles were made for vip_ivp-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on ngripon/vip-ivp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page