Borrow in parallel iterator

In the attached code, I tried to use zip() but it does not fit due to the offset introduced by w.
What is a proper solution?

use ndarray::{Array, array, Array1, Array2, Ix, Ix1, Ix2};
use ndarray::parallel::prelude::*;
use rayon::prelude::*;

fn cant_borrow(w: Ix) -> () {
    let mut a = array![1, 2, 3, 4];
    let b = array![5, 6, 7, 8];
    (1..4).into_par_iter().for_each(|i| {
       a[i - w] = b[i - 1] + a[i - 1] + 44; // ERROR: cannot borrow `a` as mutable, as it is a captured variable in a `Fn` closure
    });
    println!("{:?}", a);
}

EDIT:
The above is a simplified code. Here is the original python (with numba?) which I try to convert to Rust: matrixprofile/matrixprofile/algorithms/cympx.pyx at master · matrix-profile-foundation/matrixprofile · GitHub

and here is my feeble attempt at rust:

    let ra_range = (w..n).into_par_iter();
    ra_range.for_each(|i| {
        df[i - w + 1] = 0.5 * (ts[i] - ts[i - w]);
        dg[i - w + 1] = (ts[i] - mu[i - w + 1]) + (ts[i - w] - mu[i - w]);
    });

The real length of the arrays is 1000..1_000_000 (just to say "a lot")
The real value of w is "w in [4..30]"

Regarding protecting the arrays for MT access: The whole idea is that the operations are independent, so can be done in parallel. protecting by mutex, for example, will kill all the benefit of the threads.

I hope I made it clearer.

You'll need to put the arrays in a thread-safe wrapper.

What are you actually trying to do here? The only values you can use for w without overflowing are 0 and 1. 1 means that the read and write happen to the same element, so you can just += over a parallel iterator of a. 0 would mean the results are dependent on the order, so it's not parallelizable anyway.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.