a

 
 
fn main() {
    // Define the derivative function: dx/dt = t
    /* let f = |x: &[f64], t: f64| -> Vec<f64> {
        vec![t] // Ignores x
    }; */
 
    let f = |x: &[f64], t: f64| -> Vec<f64> {
        let m = 1000.0;
        let k = 50.0;
        let kp = 3.3;
        let r = 0.0;
        let der_x = x[1];
        let der_v = -k / m * x[1] + kp * (r - x[0]) / m;
        vec![der_x, der_v]
    };
 
    let t0 = 0.0;
    let x0 = vec![100.0, 0.0]; // Initial condition x(0) = 0
    let h = 0.5;
    let n = 1000;
 
    let (t, result) = runge_kutta_4(f, &x0, t0, h, n);
 
    // Print the solution at each step
    for (time, state) in t.iter().zip(result.iter()) {
        println!("t = {:.1}, x = {:.6}", time, state[0]);
    }
}
 
pub fn runge_kutta_4<F>(f: F, x0: &[f64], t0: f64, h: f64, n: usize) -> (Vec<f64>, Vec<Vec<f64>>)
where
    F: Fn(&[f64], f64) -> Vec<f64>,
{
    let mut t = vec![t0];
    let mut result = vec![x0.to_vec()];
 
    for _ in 0..n {
        let xi = &result[result.len() - 1];
        let ti = t[t.len() - 1];
 
        let k1 = f(xi, ti);
        let k2 = f(&extend(xi, h / 2.0, &k1), ti + h / 2.0);
        let k3 = f(&extend(xi, h / 2.0, &k2), ti + h / 2.0);
        let k4 = f(&extend(xi, h, &k3), ti + h / 2.0);
 
        let mut next_x = Vec::with_capacity(xi.len());
        for j in 0..xi.len() {
            let step = xi[j] + (h / 6.0) * (k1[j] + 2.0 * k2[j] + 2.0 * k3[j] + k4[j]);
            next_x.push(step);
        }
 
        result.push(next_x);
        t.push(ti + h);
    }
 
    (t, result)
}
 
fn extend(x: &[f64], h: f64, der: &[f64]) -> Vec<f64> {
    assert_eq!(x.len(), der.len());
    x.iter()
        .zip(der.iter())
        .map(|(&xj, &derj)| xj + h * derj)
        .collect()
}

 
 
fn main() {
    // Define the derivative function: dx/dt = t
    /* let f = |x: &[f64], t: f64| -> Vec<f64> {
        vec![t] // Ignores x
    }; */
 
let f = |x: &[f64], t: f64| -> Vec<f64> {
        let m = 1000.0;
        let k = 50.0;
        let kp = 20.0;
        let kd = 200.0;
        let r = 0.0;
        let f = kp * (r - x[0]) - kd * x[1];
        let der_x = x[1];
        let der_v = -k / m * x[1] + f / m;
        vec![der_x, der_v]
    };
    let t0 = 0.0;
    let x0 = vec![100.0, 0.0]; // Initial condition x(0) = 0
    let h = 0.5;
    let n = 1000;
 
    let (t, result) = runge_kutta_4(f, &x0, t0, h, n);
 
    // Print the solution at each step
    for (time, state) in t.iter().zip(result.iter()) {
        println!("t = {:.1}, x = {:.6}", time, state[0]);
    }
}
 
pub fn runge_kutta_4<F>(f: F, x0: &[f64], t0: f64, h: f64, n: usize) -> (Vec<f64>, Vec<Vec<f64>>)
where
    F: Fn(&[f64], f64) -> Vec<f64>,
{
    let mut t = vec![t0];
    let mut result = vec![x0.to_vec()];
 
    for _ in 0..n {
        let xi = &result[result.len() - 1];
        let ti = t[t.len() - 1];
 
        let k1 = f(xi, ti);
        let k2 = f(&extend(xi, h / 2.0, &k1), ti + h / 2.0);
        let k3 = f(&extend(xi, h / 2.0, &k2), ti + h / 2.0);
        let k4 = f(&extend(xi, h, &k3), ti + h / 2.0);
 
        let mut next_x = Vec::with_capacity(xi.len());
        for j in 0..xi.len() {
            let step = xi[j] + (h / 6.0) * (k1[j] + 2.0 * k2[j] + 2.0 * k3[j] + k4[j]);
            next_x.push(step);
        }
 
        result.push(next_x);
        t.push(ti + h);
    }
 
    (t, result)
}
 
fn extend(x: &[f64], h: f64, der: &[f64]) -> Vec<f64> {
    assert_eq!(x.len(), der.len());
    x.iter()
        .zip(der.iter())
        .map(|(&xj, &derj)| xj + h * derj)
        .collect()
}