# Convolution entirely with iterators?

#1

Is there a way to get rid of this for loop and do the entire operation with one line? [Playground link.](https://play.rust-lang.org/?code=fn%20main()%20{ %20%20%20%20%20let%20iny1%3A[i32%3B5]%20%3D%20%20[1%2C2%2C3%2C4%2C5]%3B %20%20%20%20%20let%20iny2%3A[i32%3B15]%20%3D%20[1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15]%3B %20%20%20%20%20let%20mut%20outy2%3AVec<i32>%20%3D%20Vec%3A%3A<i32>%3A%3Anew()%3B %20%20%20%20%20for%20i%20in%200..10%20{ %20%20%20%20%20%20%20%20%20outy2.push(iny2.iter().skip(i).zip(iny1.iter()).map(%7C(x%2Cy)%7Cx*y).sum())%3B%0D%0A%20%20%20%20%20%7D%0D%0A%0D%0A%0D%0A%20%20%20%20%20for%20k%20in%20outy2.iter()%20%7B%0D%0A%0D%0A%20%20%20%20%20%20%20%20%20println!(%22%7B%3A9%7D%22%2Ck)%3B%0D%0A%0D%0A%20%20%20%20%20%7D%0D%0A%0D%0A%7D%0D%0A&version=stable&backtrace=0)

#2

FYI, I think you wanted `0..11` (0 through 10).

The direct approach would be as follows:

``````fn main() {

let iny1:[i32;5] =  [1,2,3,4,5];
let iny2:[i32;15] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

let outy2: Vec<i32> = (0..11).map(|i| {
iny2.iter().skip(i).zip(&iny1).map(|(x,y)|x*y).sum()
}).collect();

for k in outy2.iter() {
println!("{:9}",k);
}
}
``````

However, I recommend using `windows`. This is actually how I caught that bug (never mess with indices directly unless you absolutely have to).

``````fn main() {

let iny1:[i32;5] =  [1,2,3,4,5];
let iny2:[i32;15] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

let outy2: Vec<i32> = iny2.windows(iny1.len()).map(|window| {
window.iter().zip(&iny1).map(|(x,y)|x*y).sum()
}).collect();

for k in outy2.iter() {
println!("{:9}",k);
}
}
``````

#3

Thank you! I was sure the right answer would have indicies but I didnâ€™t see windows in the doc. I lobe the rust community.

#4

For others interested, here it is in the docs: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.windows

#5

If I scale this up to signal processing sizes (1024 and 1024^2 instead of 5 and 15) I get a trait bounds error. Looks like std::iter::Iterator is limited to 32 elements. Is there a way around this?

#6

Thatâ€™s a problem with arrays â€“ we donâ€™t have integer generics yet, so most of its traits are manually unrolled up to 32 elements. In this case youâ€™re actually missing `IntoIterator`. You can get around this by manually slicing it, `zip(&iny1[..])`.

But as you get to larger sizes, youâ€™re going to run into trouble holding such large data on the stack, and a `Vec` will probably serve you better.

#7

Thank you, the vector worked and also somehow nudged the autovectorizer into using SSE.