1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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
//! # differential-equations
//!
//! A Rust library for solving ODE, DAE, DDE, and SDE initial value problems.
//!
//! [](https://github.com/Ryan-D-Gast/differential-equations)
//! [](https://docs.rs/differential-equations)
//!
//! ## Overview
//!
//! This library provides numerical solvers for:
//!
//! - **[Ordinary Differential Equations (ODE)](crate::ode)**: initial value problems, fixed/adaptive step, event detection, flexible output
//! - **[Boundary Value Problems (BVP)](crate::bvp)**: problems with boundary conditions at both ends of the interval
//! - **[Differential Algebraic Equations (DAE)](crate::dae)**: equations in the form M f' = f(t,y) where M can be singular
//! - **[Delay Differential Equations (DDE)](crate::dde)**: constant/state-dependent delays, same features as ODE
//! - **[Stochastic Differential Equations (SDE)](crate::sde)**: drift-diffusion, user RNG, same features as ODE
//!
//! ## Feature Flags
//!
//! - `nalgebra`: Enable nalgebra matrix and vector states
//! - `num-complex`: Enable complex number states
//! - `ndarray`: Enable ndarray array states
//! - `faer`: Enable faer matrix states
//! - `polars`: Enable converting `Solution` to a Polars DataFrame with `Solution::to_polars()`
//! - `serde`: Enable solution serialization and deserialization
//!
//! ## Example (ODE)
//!
//! ```rust
//! use differential_equations::prelude::*;
//!
//! pub struct LinearEquation {
//! pub a: f64,
//! pub b: f64,
//! }
//!
//! impl ODE for LinearEquation {
//! fn diff(&self, _t: f64, y: &f64, dydt: &mut f64) {
//! *dydt = self.a + self.b * *y;
//! }
//! }
//!
//! fn main() {
//! let system = LinearEquation { a: 1.0, b: 2.0 };
//! let t0 = 0.0;
//! let tf = 1.0;
//! let y0 = 1.0;
//! let solver = ExplicitRungeKutta::dop853().rtol(1e-8).atol(1e-6);
//! let solution = match IVP::ode(&system, t0, tf, y0).method(solver).solve() {
//! Ok(sol) => sol,
//! Err(e) => panic!("Error: {:?}", e),
//! };
//!
//! for (t, y) in solution.iter() {
//! println!("t: {:.4}, y: {:.4}", t, *y);
//! }
//! }
//! ```
//!
//! Alternatively, for simple problems you can use a closure:
//!
//! ```rust
//! use differential_equations::prelude::*;
//!
//! fn main() {
//! let t0 = 0.0;
//! let tf = 1.0;
//! let y0 = 1.0;
//!
//! let solution = IVP::ode_from_fn(|t, y, dydt| *dydt = t * y, t0, tf, y0)
//! .method(ExplicitRungeKutta::dop853().rtol(1e-8).atol(1e-6))
//! .solve()
//! .unwrap();
//! }
//! ```
//!
//! ## License
//!
//! ```text
//! Copyright 2025 Ryan D. Gast
//!
//! Licensed under the Apache License, Version 2.0 (the "License");
//! you may not use this file except in compliance with the License.
//! You may obtain a copy of the License at
//!
//! http://www.apache.org/licenses/LICENSE-2.0
//!
//! Unless required by applicable law or agreed to in writing, software
//! distributed under the License is distributed on an "AS IS" BASIS,
//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KINeither express or implied.
//! See the License for the specific language governing permissions and
//! limitations under the License.
//! ```
// Prelude & User-Facing API
// Numerical Methods
// Differential Equations
// Output Control
// Core Structures
// Shared Traits & Utilities
// Derive Macros