Skip to content

Commit 0fb0325

Browse files
jasmaajiegillet
authored andcommitted
Implement conv in python (#408)
* Implement conv in python * Fix conv func * fix range * remove numpy usage * Fix discrete convolution * Revert julia file * Add padding for fft * Make requested changes
1 parent a8a60fe commit 0fb0325

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import math
2+
from scipy.fftpack import fft, ifft
3+
4+
def conv(signal1, signal2):
5+
"""Discrete convolution by definition"""
6+
7+
n = len(signal1) + len(signal2) - 1
8+
out = []
9+
10+
for i in range(n):
11+
s = 0
12+
13+
for j in range(i + 1):
14+
if j < len(signal1) and i - j < len(signal2):
15+
s += signal1[j] * signal2[i - j]
16+
17+
out.append(s)
18+
19+
return out
20+
21+
22+
def conv_fft(signal1, signal2):
23+
"""Convolution using fft and convolutional theorem"""
24+
25+
signal1 = signal1.copy()
26+
signal2 = signal2.copy()
27+
28+
# pad signals to same len
29+
max_len = max(len(signal1), len(signal2))
30+
31+
for i in range(max_len - len(signal1)):
32+
signal1.append(0)
33+
for i in range(max_len - len(signal2)):
34+
signal2.append(0)
35+
36+
fft_s1 = fft(signal1)
37+
fft_s2 = fft(signal2)
38+
out = []
39+
40+
for i in range(len(signal1)):
41+
out.append(fft_s1[i] * fft_s2[i])
42+
43+
return list(ifft(out))
44+
45+
46+
def main():
47+
# Example convolution with sin and cos
48+
s1 = [math.sin(x) for x in range(5)]
49+
s2 = [math.cos(x) for x in range(5)]
50+
51+
print("Discrete Convolution")
52+
print(conv(s1, s2))
53+
54+
print("FFT Convolution")
55+
print(conv_fft(s1, s2))
56+
57+
58+
if __name__ == "__main__":
59+
main()
60+

contents/convolutions/convolutions.md

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ In code, this looks something like:
4444
[import:5-18, lang:"c_cpp"](code/c/convolutions.c)
4545
{% sample lang="cpp"%}
4646
[import:68-88, lang:"c_cpp"](code/c++/convolutions.cpp)
47+
{% sample lang="python"%}
48+
[import:4-19, lang:"python"](code/python/conv.py)
4749
{% endmethod %}
4850

4951
Note that in this case, the output array will be the size of `f[n]` and `g[n]` put together.
@@ -93,6 +95,8 @@ Where the `.*` operator is an element-wise multiplication.
9395
[import:20-30, lang:"c_cpp"](code/c/convolutions.c)
9496
{% sample lang="cpp"%}
9597
[import:90-105, lang:"c_cpp"](code/c++/convolutions.cpp)
98+
{% sample lang="python"%}
99+
[import:22-43, lang:"python"](code/python/conv.py)
96100
{% endmethod %}
97101

98102
This method also has the added advantage that it will *always output an array of the size of your signal*; however, if your signals are not of equal size, we need to pad the smaller signal with zeros.

0 commit comments

Comments
 (0)