Separable ODEs
Topic:
ode.separable
Separable ODEs are the most important and frequently encountered class of first-order differential equations. MathHook provides a robust solver that handles both general and particular solutions with automatic variable separation and symbolic integration.
Mathematical Definition
A first-order ODE is separable if it can be written as:
where is a function of only and is a function of only .
Separable ODEs
Coverage: ~30% of first-order ODE problems Priority: Highest-priority solver in classification chain Complexity: O(n) where n is integration complexity
Separable ODEs are the most important and frequently encountered class of first-order differential equations. MathHook provides a robust solver that handles both general and particular solutions with automatic variable separation and symbolic integration.
Mathematical Background
What is a Separable ODE?
A first-order ODE is separable if it can be written as:
where:
- is a function of only (the independent variable)
- is a function of only (the dependent variable)
Key insight: The right-hand side factors into a product of two single-variable functions.
Solution Method
Algorithm:
- Separate variables: Rewrite as
- Integrate both sides:
- Solve for (if possible): Obtain explicit or implicit solution
- Apply initial condition (if given): Determine constant
Mathematical justification:
Starting with , we multiply both sides by :
This is valid because we're treating and as differentials. Integrating both sides gives the general solution.
Why This Method Works
The separation of variables method exploits the multiplicative structure of the equation. By dividing by , we isolate all -dependence on one side and all -dependence on the other. Since both sides must be equal, their integrals must also be equal (up to a constant).
Implicit vs Explicit Solutions:
- Explicit: (can solve for directly)
- Implicit: (cannot solve for algebraically)
Examples
Simple Linear ODE
Solve dy/dx = x
Rust
#![allow(unused)] fn main() { use mathhook::prelude::*; use mathhook::ode::first_order::separable::SeparableODESolver; let x = symbol!(x); let y = symbol!(y); let solver = SeparableODESolver::new(); let solution = solver.solve(&expr!(x), &y, &x, None)?; // Result: y = x²/2 + C }
Python
from mathhook import symbol
from mathhook.ode.first_order.separable import SeparableODESolver
x = symbol('x')
y = symbol('y')
solver = SeparableODESolver()
solution = solver.solve('x', y, x, None)
# Result: y = x²/2 + C
JavaScript
const { symbol } = require('mathhook');
const { SeparableODESolver } = require('mathhook/ode/firstOrder/separable');
const x = symbol('x');
const y = symbol('y');
const solver = new SeparableODESolver();
const solution = solver.solve('x', y, x, null);
// Result: y = x²/2 + C
Exponential Growth
Solve dy/dx = y (exponential growth/decay model)
Rust
#![allow(unused)] fn main() { use mathhook::prelude::*; use mathhook::ode::first_order::separable::SeparableODESolver; let x = symbol!(x); let y = symbol!(y); let solver = SeparableODESolver::new(); let solution = solver.solve(&expr!(y), &y, &x, None)?; // Result: y = Ce^x }
Python
from mathhook import symbol
from mathhook.ode.first_order.separable import SeparableODESolver
x = symbol('x')
y = symbol('y')
solver = SeparableODESolver()
solution = solver.solve('y', y, x, None)
# Result: y = Ce^x
JavaScript
const { symbol } = require('mathhook');
const { SeparableODESolver } = require('mathhook/ode/firstOrder/separable');
const x = symbol('x');
const y = symbol('y');
const solver = new SeparableODESolver();
const solution = solver.solve('y', y, x, null);
// Result: y = Ce^x
Product Form
Solve dy/dx = xy (nonlinear growth model)
Rust
#![allow(unused)] fn main() { use mathhook::prelude::*; use mathhook::ode::first_order::separable::SeparableODESolver; let x = symbol!(x); let y = symbol!(y); let solver = SeparableODESolver::new(); let solution = solver.solve(&expr!(x * y), &y, &x, None)?; // Result: y = Ce^(x²/2) }
Python
from mathhook import symbol
from mathhook.ode.first_order.separable import SeparableODESolver
x = symbol('x')
y = symbol('y')
solver = SeparableODESolver()
solution = solver.solve('x*y', y, x, None)
# Result: y = Ce^(x²/2)
JavaScript
const { symbol } = require('mathhook');
const { SeparableODESolver } = require('mathhook/ode/firstOrder/separable');
const x = symbol('x');
const y = symbol('y');
const solver = new SeparableODESolver();
const solution = solver.solve('x*y', y, x, null);
// Result: y = Ce^(x²/2)
Initial Value Problem
Solve dy/dx = x with y(0) = 1
Rust
#![allow(unused)] fn main() { use mathhook::prelude::*; use mathhook::ode::first_order::separable::SeparableODESolver; let x = symbol!(x); let y = symbol!(y); let solver = SeparableODESolver::new(); let ic = Some((expr!(0), expr!(1))); // y(0) = 1 let solution = solver.solve(&expr!(x), &y, &x, ic)?; // Result: y = x²/2 + 1 }
Python
from mathhook import symbol, expr
from mathhook.ode.first_order.separable import SeparableODESolver
x = symbol('x')
y = symbol('y')
solver = SeparableODESolver()
ic = (expr('0'), expr('1')) # y(0) = 1
solution = solver.solve('x', y, x, ic)
# Result: y = x²/2 + 1
JavaScript
const { symbol, expr } = require('mathhook');
const { SeparableODESolver } = require('mathhook/ode/firstOrder/separable');
const x = symbol('x');
const y = symbol('y');
const solver = new SeparableODESolver();
const ic = [expr('0'), expr('1')]; // y(0) = 1
const solution = solver.solve('x', y, x, ic);
// Result: y = x²/2 + 1
Rational Function
Solve dy/dx = x/y
Rust
#![allow(unused)] fn main() { use mathhook::prelude::*; use mathhook::ode::first_order::separable::SeparableODESolver; let x = symbol!(x); let y = symbol!(y); let solver = SeparableODESolver::new(); let rhs = expr!(x / y); let solution = solver.solve(&rhs, &y, &x, None)?; // Result: y² - x² = C (implicit) or y = ±√(x² + C) (explicit) }
Python
from mathhook import symbol, expr
from mathhook.ode.first_order.separable import SeparableODESolver
x = symbol('x')
y = symbol('y')
solver = SeparableODESolver()
solution = solver.solve('x/y', y, x, None)
# Result: y² - x² = C
JavaScript
const { symbol } = require('mathhook');
const { SeparableODESolver } = require('mathhook/ode/firstOrder/separable');
const x = symbol('x');
const y = symbol('y');
const solver = new SeparableODESolver();
const solution = solver.solve('x/y', y, x, null);
// Result: y² - x² = C
Performance
Time Complexity: O(n) where n = integration complexity
API Reference
- Rust:
mathhook_core::ode::first_order::separable::SeparableODESolver - Python:
mathhook.ode.first_order.separable.SeparableODESolver - JavaScript:
mathhook.ode.firstOrder.separable.SeparableODESolver