from __future__ import annotations
def convolve1d(signal: list, kernel: list) -> list:
n = len(signal)
k = len(kernel)
result = [0.0] * (n - k + 1)
for i in range(n - k + 1):
total = 0.0
for j in range(k):
total += signal[i + j] * kernel[j]
result[i] = total
return result
def moving_average(signal: list, window: int) -> list:
n = len(signal)
result = [0.0] * (n - window + 1)
for i in range(n - window + 1):
total = 0.0
for j in range(window):
total += signal[i + j]
result[i] = total / window
return result
def cross_correlate(a: list, b: list) -> list:
n = len(a)
m = len(b)
out_len = m - n + 1
result = [0.0] * out_len
for i in range(out_len):
total = 0.0
for j in range(n):
total += a[j] * b[i + j]
result[i] = total
return result
def diff(signal: list) -> list:
n = len(signal)
result = [0.0] * (n - 1)
for i in range(n - 1):
result[i] = signal[i + 1] - signal[i]
return result
def cumsum(signal: list) -> list:
n = len(signal)
result = [0.0] * n
total = 0.0
for i in range(n):
total += signal[i]
result[i] = total
return result
if __name__ == "__main__":
import time
n = 10_000
signal = [float(i % 100) for i in range(n)]
kernel = [0.25, 0.5, 0.25]
n_iters = 5_000
print(f"Benchmarking signal processing (n={n}, iters={n_iters})...")
start = time.perf_counter()
for _ in range(n_iters):
convolve1d(signal, kernel)
elapsed = time.perf_counter() - start
print(f" convolve1d (k=3): {elapsed:.3f}s ({elapsed/n_iters*1000:.2f}ms/call)")
start = time.perf_counter()
for _ in range(n_iters):
moving_average(signal, 10)
elapsed = time.perf_counter() - start
print(f" moving_average (w=10): {elapsed:.3f}s ({elapsed/n_iters*1000:.2f}ms/call)")
start = time.perf_counter()
for _ in range(n_iters):
cumsum(signal)
elapsed = time.perf_counter() - start
print(f" cumsum: {elapsed:.3f}s ({elapsed/n_iters*1000:.2f}ms/call)")