How to reduce the same function calls in a repetitive code?


#1
#[allow(dead_code)]
fn interaction_1(
    d_x: &mut [f32],
    d_y: &[f32],
    d_r: &mut [f32],
    d_m: &[f32],
    s_x: &[f32],
    s_y: &[f32],
    s_h: &[f32],
) {
    let mut _sum = 0.;
    for _i in 0..d_x.len() {
        for _j in 0..s_x.len() {
            _sum += 1.;
        }
    }
}

#[allow(dead_code)]
fn interaction_2(
    d_x: &[f32],
    d_y: &mut [f32],
    d_r: &[f32],
    d_m: &[f32],
    s_x: &[f32],
    s_y: &[f32],
    s_h: &mut [f32],
) {
    let mut _sum = 0.;
    for _i in 0..d_x.len() {
        for _j in 0..s_x.len() {
            _sum += 1.;
        }
    }
}

fn update_1(d_x: &mut [f32], d_y: &mut [f32]) {
    for i in 0..d_x.len() {
        d_x[i] += 1.;
        d_y[i] += 1.;
    }
}

fn update_2(d_x: &mut [f32], d_y: &mut [f32]) {
    for i in 0..d_x.len() {
        d_x[i] += 1.;
        d_y[i] += 1.;
    }
}
struct Destination {
    x: Vec<f32>,
    y: Vec<f32>,
    r: Vec<f32>,
    m: Vec<f32>,
}

struct Source {
    x: Vec<f32>,
    y: Vec<f32>,
    h: Vec<f32>,
}

fn main() {
    let mut dest = Destination {
        x: vec![10.; 30],
        y: vec![10.; 30],
        m: vec![10.; 30],
        r: vec![10.; 30],
    };
    let mut src = Source {
        x: vec![10.; 30],
        y: vec![10.; 30],
        h: vec![10.; 30],
    };

    let tf = 3.;
    let mut t = 0.;
    let dt = 1e-4;
    while t < tf {
        // ----------------------------------------
        // ----------------------------------------
        // Here I am repeating the same code twice.
        // ----------------------------------------
        // ----------------------------------------
        
        
        // for stage 1
        // only the equations i.e 2 functions are repeated
        interaction_1(
            &mut dest.x,
            &dest.y,
            &mut dest.r,
            &dest.m,
            &src.x,
            &src.y,
            &src.h,
        );
        interaction_2(
            &dest.x,
            &mut dest.y,
            &dest.r,
            &dest.m,
            &src.x,
            &src.y,
            &mut src.h,
        );
        update_1(&mut dest.x, &mut dest.y);

        // ----------------------------------------
        // ----------------------------------------
        // Same code is repeated twice
        // ----------------------------------------
        // ----------------------------------------
        // for stage 2
        // only the equations i.e 2 functions are repeated
        interaction_1(
            &mut dest.x,
            &dest.y,
            &mut dest.r,
            &dest.m,
            &src.x,
            &src.y,
            &src.h,
        );
        interaction_2(
            &dest.x,
            &mut dest.y,
            &dest.r,
            &dest.m,
            &src.x,
            &src.y,
            &mut src.h,
        );
        update_2(&mut dest.x, &mut dest.y);

        t = t + dt;
    }
}


(Playground)

Hi guys. I have a code base which pretty much looks like above. I am writing a code which is used to simulate particles. I am using a 2nd order integrator (Numerical stuff). Which makes my functions (or equations) run twice for better accuracy.

Is there a way to make this clean and not repetitive?

Thank you.


#2

What’s wrong with a loop?

for _ in 0..2 { /* code that repeats */ }

#4

I just updated it. Actually I have to run few equations (functions) and call stage 1 ( update_1 ) then again run the same equations and call stage 2 ( update_2 ).


#5

You should consider refactoring the repetitive calls into a function… https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=f96d70a82d5ad268ac3a88b3309a2935

It makes a big difference aesthetically in this case, since you have a lot of vertical stacks of function arguments. But those arguments nicely fit on a single line, anyway, so that’s another way to reduce the visual noise, here.