Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help



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:

  1. Separate variables: Rewrite as
  2. Integrate both sides:
  3. Solve for (if possible): Obtain explicit or implicit solution
  4. 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

See Also