Convolution Example — Pulse Smoothing and Cross-Correlation¶
This example convolves a rectangular pulse with a Gaussian smoothing kernel
using transforms.convolve(), then detects a time delay between two
delayed signals via cross-correlation.
Example Code¶
"""IMSL Convolution example: rectangular pulse convolved with Gaussian kernel.
Also demonstrates cross-correlation of two delayed signals.
Outputs:
- Summary table printed to stdout
- SVG plot saved to test_output/demo_imsl_convolution.svg
"""
from __future__ import annotations
from pathlib import Path
from typing import Dict
import matplotlib.pyplot as plt
import numpy as np
from transforms import convolve_real, correlate_real
def run_demo_imsl_convolution() -> Dict[str, object]:
"""Run IMSL convolution/correlation example.
Convolves a rectangular pulse with a Gaussian smoothing kernel, then
computes the cross-correlation of two time-shifted pulses to detect delay.
Args:
None
Returns:
Dict[str, object]: Result dict with keys ``conv_peak`` (float),
``detected_lag`` (int), and ``plot_path`` (str).
"""
N = 128
# Rectangular pulse signal
x = np.zeros(N)
x[40:60] = 1.0
# Gaussian kernel
sigma = 5.0
k_range = np.arange(-15, 16)
h = np.exp(-0.5 * (k_range / sigma) ** 2)
h /= h.sum()
# Convolution
conv_result = convolve_real(x, h)
conv_peak = float(conv_result.max())
# Cross-correlation: detect delay between two pulses
x1 = np.zeros(N)
x1[30] = 1.0
x2 = np.zeros(N)
delay = 8
x2[30 + delay] = 1.0
corr_result = correlate_real(x1, x2)
center = N - 1
detected_lag = int(np.argmax(corr_result) - center)
print("\nIMSL Convolution Example")
print("-" * 45)
print(f"{'Convolution peak amplitude':<30} {conv_peak:>10.4f}")
print(f"{'True delay (samples)':<30} {delay:>10}")
print(f"{'Detected lag from correlation':<30} {detected_lag:>10}")
print("-" * 45)
output_dir = Path("test_output")
output_dir.mkdir(parents=True, exist_ok=True)
plot_path = output_dir / "demo_imsl_convolution.svg"
fig, axes = plt.subplots(3, 1, figsize=(10, 9))
# Signal and kernel
t = np.arange(N)
axes[0].plot(t, x, color="#6d28d9", linewidth=1.5, label="Rect pulse x")
ax0b = axes[0].twinx()
k_plot = np.arange(len(h)) - 15
ax0b.fill_between(k_plot + 50, h, alpha=0.4, color="#f59e0b", label="Gaussian h")
axes[0].set_xlabel("Sample")
axes[0].set_ylabel("x[n]")
axes[0].set_title("Input Signal (rect pulse) and Gaussian Kernel")
axes[0].legend(loc="upper left")
axes[0].grid(True, alpha=0.3)
# Convolution output
t_conv = np.arange(len(conv_result))
axes[1].plot(t_conv, conv_result, color="#7c3aed", linewidth=1.5)
axes[1].set_xlabel("Sample")
axes[1].set_ylabel("(x * h)[n]")
axes[1].set_title("Convolution Output (rect pulse ∗ Gaussian)")
axes[1].grid(True, alpha=0.3)
# Correlation
lags = np.arange(len(corr_result)) - center
axes[2].plot(lags, corr_result, color="#059669", linewidth=1.5)
axes[2].axvline(-delay, color="#dc2626", linestyle="--", linewidth=1.2,
label=f"True lag = {-delay}")
axes[2].set_xlabel("Lag (samples)")
axes[2].set_ylabel("R_{x1,x2}[lag]")
axes[2].set_title("Cross-Correlation (delay detection)")
axes[2].legend()
axes[2].grid(True, alpha=0.3)
axes[2].set_xlim(-30, 30)
fig.tight_layout()
fig.savefig(plot_path, format="svg")
plt.close(fig)
return {
"conv_peak": conv_peak,
"detected_lag": detected_lag,
"plot_path": str(plot_path),
}
if __name__ == "__main__":
run_demo_imsl_convolution()
Plot Output¶
Three-panel plot: original rectangular pulse (top), Gaussian-smoothed output (middle), and cross-correlation lag plot detecting the time delay (bottom).¶
Console Output¶
IMSL Convolution Example
---------------------------------------------
Convolution peak amplitude 0.9556
True delay (samples) 8
Detected lag from correlation -8
---------------------------------------------