# Translating a 1d convolution from Python to Julia

**URL:** <https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080>\
**Category:** General Usage\
**Tags:** question, python, dsp\
**Created:** [July 31, 2022, 10:20pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080 "2022-07-31T22:20:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 31, 2022, 10:20pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/1 "2022-07-31T22:20:24Z")

</div>

Hi all,

I am trying to port some code written in Python. It performs a 1d convolution on a 3d array. The Python and Julia code output arrays with different dimensions and values. Does anyone know the equivalent code on Julia?

**Julia**

```julia
using DSP
x = [0 0 1 2 3 5 0 0; 0 0 4 5 6 5 0 0 ;;; 0 0 2 3 4 5 0 0 ; 0 0 5 6 7 5 0 0]
z = [5,6,7,10]
    conv(x, z)

```

output:

```julia
5×8×2 Array{Int64, 3}:
[:, :, 1] =
 0 0 5 10 15 25 0 0
 0 0 26 37 48 55 0 0
 0 0 31 44 57 65 0 0
 0 0 38 55 72 85 0 0
 0 0 40 50 60 50 0 0

[:, :, 2] =
 0 0 10 15 20 25 0 0
 0 0 37 48 59 55 0 0
 0 0 44 57 70 65 0 0
 0 0 55 72 89 85 0 0
 0 0 50 60 70 50 0 0

```

**Python**

```julia
import scipy
x1 = np.array([[0,0,1,2,3,5,0,0],[0,0,4,5,6,5,0,0]])
x2 = np.array([[0,0,2,3,4,5,0,0],[0,0,5,6,7,5,0,0]])
x = np.dstack((x1, x2))
z = [5,6,7,10]
scipy.ndimage.convolve1d(x, z, axis=1, mode='constant', cval=0)

```

output:

```julia
array([[[5, 10],
        [16, 27],
        [34, 52],
        [67, 90],
        [71, 88],
        [65, 75],
        [50, 50],
        [0, 0]],

       [[20, 25],
        [49, 60],
        [88, 106],
        [136, 159],
        [122, 139],
        [95, 105],
        [50, 50],
        [0, 0]]])

```

---

<div class="post-metadata">

**Author:** ![devel-chm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/devel-chm/32/3572_2.png) [@devel-chm](https://discourse.julialang.org/u/devel-chm)\
**Post date:** [July 31, 2022, 10:46pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/2 "2022-07-31T22:46:20Z")

</div>

I suggest determining how the `convolve1d` is defined in numpy.  
Do the same for the `conv` operation in `DSP`.  
Then generate the correct calls in Julia.

In practice, I’ve found the simplest is to apply the operations to simple  
arrays and see what happens by inspection. You can do that in both  
scipy and julia REPLs.

Things to look for

- Expanding dimensions versus circular correlation or implicit padding
- Dimension order and index offsets
- Differences in print or display representations
- Applying a 1-D operation along a specific dimension of a multi-dimensional data array
- You julia and numpy versions (I think repeated `;;;` inside `[]` changed in recent versions of julia

N.B. I haven’t used scipy/numpy and not used the DSP package in Julia.

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [July 31, 2022, 11:25pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/3 "2022-07-31T23:25:56Z")

</div>

Thank you. This is good advice. I read through the documentation and code to the best of my ability and tried to discern patterns with simpler examples. The problem is that the behavior of the functions become more divergent as the number of dimensions increases.

The scipy documentation provides the following example:

```julia
convolve1d([2, 8, 0, 4, 1, 9, 9, 0], [1, 3], cval=0)
array([14, 24, 4, 13, 12, 36, 27, 0])

```

In Julia, the code produces:

```julia
conv([2, 8, 0, 4, 1, 9, 9, 0], [1, 3])
9-element Vector{Int64}:
  2
 14
 24
  4
 13
 12
 36
 27
  0

```

The results are similar except for an additional 2 in the Julia output. In my first example involving a 3d array, the arrays differ in ways that I have yet to understand.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 31, 2022, 11:31pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/4 "2022-07-31T23:31:33Z")

</div>

The following produces the same result:

```julia
using DSP
x = [0 0 1 2 3 5 0 0; 0 0 4 5 6 5 0 0 ;;; 0 0 2 3 4 5 0 0 ; 0 0 5 6 7 5 0 0]
z = [5,6,7,10]

n, m = length(z)÷2, size(x,2)
r0 = conv.(eachslice(x,dims=1), (z,))
r = [view(u,n+1:n+m,:) for u in r0]

julia> r[1]
8×2 Matrix{Int64}:
  5 10
 16 27
 34 52
 67 90
 71 88
 65 75
 50 50
  0 0

julia> r[2]
8×2 Matrix{Int64}:
  20 25
  49 60
  88 106
 136 159
 122 139
  95 105
  50 50
   0 0

```

The result of the DSP convolution must be cut off at the beginning and end, so that its output has the same length as the input.

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [August 1, 2022, 12:11am UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/5 "2022-08-01T00:11:21Z")

</div>

> [@rafael.guerra](#):
>
> ```julia
> n, m = length(z)÷2, size(x,2)
> r0 = conv.(eachslice(x,dims=1), (z,))
> r = [u[n+1:n+m,:] for u in r0]
> 
> ```

Thank you for your help! I will study this in more detail tomorrow.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 1, 2022, 6:29pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/6 "2022-08-01T18:29:40Z")

</div>

Adding `view()` inside the comprehension above provides better performance _(NB: edited the post)_, but another way to trim the convolution output is:

```julia
r = selectdim.(r0, 1, (n+1:n+m,))

```

---

<div class="post-metadata">

**Author:** ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)\
**Post date:** [August 1, 2022, 6:35pm UTC](https://discourse.julialang.org/t/translating-a-1d-convolution-from-python-to-julia/85080/7 "2022-08-01T18:35:25Z")

</div>

Thanks for your help! I will mark your answer as a solution. I will provide an update if I am clever enough to find a more efficient solution (I suspect that `convolve1d` in `scipy` is more efficient because it is not manipulating intermediate arrays). But in either case, having a correct solution is very helpful!
