use mathcore::differential::{DifferentialEquations, PDESolver};
use mathcore::parser::Parser;
fn main() {
println!("Scientific Computing Examples\n");
population_dynamics();
heat_diffusion();
wave_propagation();
pendulum_motion();
}
fn population_dynamics() {
println!("=== Population Dynamics (Logistic Growth) ===");
let r = 0.5;
let k = 1000.0;
let expr = Parser::parse(&format!("{}*P*(1 - P/{})", r, k)).unwrap();
let solution = DifferentialEquations::solve_ode_first_order(
&expr,
"t",
"P",
(0.0, 10.0), 20.0, 200, )
.unwrap();
println!("Time\tPopulation");
for i in (0..solution.t.len()).step_by(20) {
println!("{:.1}\t{:.1}", solution.t[i], solution.y[i][0]);
}
println!("\nPopulation stabilizes at carrying capacity K = {}\n", k);
}
fn heat_diffusion() {
println!("=== Heat Diffusion in a Rod ===");
let initial_temp = |x: f64| {
if (x - 0.5).abs() < 0.1 {
100.0 } else {
20.0 }
};
let solution = PDESolver::solve_heat_equation(
0.01, &initial_temp,
20.0, 20.0, (0.0, 1.0), 0.5, 50, 100, )
.unwrap();
println!("Temperature distribution after heat diffusion:");
println!("Position\tInitial\t\tFinal");
for i in (0..50).step_by(5) {
let x = i as f64 / 49.0;
println!(
"{:.2}\t\t{:.1}\t\t{:.1}",
x,
solution[0][i], solution[99][i] );
}
println!();
}
fn wave_propagation() {
println!("=== Wave Propagation ===");
let initial_position = |x: f64| {
let center = 0.5;
let width = 0.05;
(-(((x - center) / width).powi(2) as f64)).exp()
};
let initial_velocity = |_: f64| 0.0;
let solution = PDESolver::solve_wave_equation(
0.5, &initial_position,
&initial_velocity,
(0.0, 1.0), 1.0, 100, 200, )
.unwrap();
println!("Wave amplitude at different times:");
println!("Position\tt=0\t\tt=0.5\t\tt=1.0");
for i in (0..100).step_by(10) {
let x = i as f64 / 99.0;
println!(
"{:.2}\t\t{:.4}\t\t{:.4}\t\t{:.4}",
x,
solution[0][i], solution[100][i], solution[199][i] );
}
println!();
}
fn pendulum_motion() {
println!("=== Nonlinear Pendulum ===");
let g_over_l = 9.81;
let theta_dot = Parser::parse("omega").unwrap();
let omega_dot = Parser::parse(&format!("-{}*sin(theta)", g_over_l)).unwrap();
let solution = DifferentialEquations::solve_ode_system(
&[theta_dot, omega_dot],
"t",
&["theta".to_string(), "omega".to_string()],
(0.0, vec![1.0, 0.0]), 10.0, 1000, )
.unwrap();
println!("Pendulum motion (nonlinear):");
println!("Time\tAngle (rad)\tAngular Velocity");
for i in (0..solution.t.len()).step_by(100) {
println!(
"{:.1}\t{:.4}\t\t{:.4}",
solution.t[i],
solution.y[i][0], solution.y[i][1] );
}
let mut crossings = Vec::new();
for i in 1..solution.y.len() {
if solution.y[i - 1][0] > 0.0 && solution.y[i][0] <= 0.0 {
crossings.push(solution.t[i]);
}
}
if crossings.len() >= 2 {
let period = 2.0 * (crossings[1] - crossings[0]);
println!("\nEstimated period: {:.3} seconds", period);
let linear_period = 2.0 * std::f64::consts::PI / (g_over_l as f64).sqrt();
println!("Linear approximation: {:.3} seconds", linear_period);
println!(
"Difference: {:.1}%",
100.0 * (period - linear_period).abs() / linear_period
);
}
}