Reputation: 1858
I want the behavior of the following pytorch code:
def random_w(L,A):
w = torch.rand((L,L,A,A))
# We want (i,i,a,b) = 0
diag = w.diagonal()[...] = 0
# And (i,j,a,b) = (j,i,b,a)
i,j = torch.triu_indices(L,L)
w[i,j] = w[j,i].transpose(1,2)
return w
I have the following Rust code (random replaced with ones
for now)
use ndarray::prelude::*;
fn random<F : NdFloat>(L : usize, A: usize) -> Array4<F> {
let mut w = Array::<F, Ix4>::ones((L,L,A,A));
for i in 0..L {
w.slice_mut(s![i,i,..,..]).fill(F::from(0.0).unwrap());
}
for i in 0..L {
for j in (i+1)..L {
let transpose = w.slice(s![j,i,..,..]).t().into_owned();
w.slice_mut(s![i,j,..,..]).assign(&transpose);
}
}
w
}
Is there a way to avoid the copy here? I see that I cannot safely assign from a View into the array in general, but in my case both regions are non overlapping.
Upvotes: 0
Views: 63
Reputation: 1858
I settled with
use ndarray::prelude::*;
fn random<F : NdFloat>(L : usize, A: usize) -> Array4<F> {
let mut w = Array::<F, Ix4>::ones((L,L,A,A));
for i in 0..L {
w.slice_mut(s![i,i,..,..]).fill(F::from(0.0).unwrap());
}
for i in 0..L {
for j in (i+1)..L {
for a in 0..A {
for b in 0..A {
w[(j,i,b,a)] = w[(i,j,a,b)];
}
}
}
}
w
}
Not ideal, but since Rust is compiled, I guess the performance will be fine
Upvotes: 0