Sine / Cosine Transform Example — DST and DCT Roundtrip Fidelity¶
This example computes the DST-II and DCT-II of a triangle wave signal using
transforms.dst_forward() and transforms.dct_forward(), then
reconstructs the signal via the inverse transforms and verifies numerical
fidelity.
Example Code¶
"""IMSL Sine/Cosine Transform example: DST and DCT roundtrip fidelity.
Demonstrates forward DST/DCT and reconstruction via the inverse transforms.
Outputs:
- Summary table printed to stdout
- SVG plot saved to test_output/demo_imsl_sine_cosine.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 fft_cosine, fft_sine
def run_demo_imsl_sine_cosine() -> Dict[str, object]:
"""Run IMSL DST/DCT roundtrip demonstration.
Applies the forward DST and DCT to a simple piecewise-linear test signal,
then reconstructs it via the inverse transforms and reports the max
reconstruction error.
Args:
None
Returns:
Dict[str, object]: Result dict with keys ``dst_max_error`` (float),
``dct_max_error`` (float), and ``plot_path`` (str).
"""
N = 32
t = np.linspace(0, 1, N, endpoint=False)
x = np.where(t < 0.5, 2 * t, 2 - 2 * t) # triangle wave
# DST roundtrip
X_dst = fft_sine(x)
x_dst_back = fft_sine(X_dst, inverse=True)
dst_max_error = float(np.max(np.abs(x_dst_back - x)))
# DCT roundtrip
X_dct = fft_cosine(x)
x_dct_back = fft_cosine(X_dct, inverse=True)
dct_max_error = float(np.max(np.abs(x_dct_back - x)))
print("\nIMSL Sine/Cosine Transform Example (N=32, triangle wave)")
print("-" * 50)
print(f"{'DST max reconstruction error':<35} {dst_max_error:.2e}")
print(f"{'DCT max reconstruction error':<35} {dct_max_error:.2e}")
print("-" * 50)
output_dir = Path("test_output")
output_dir.mkdir(parents=True, exist_ok=True)
plot_path = output_dir / "demo_imsl_sine_cosine.svg"
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
n_idx = np.arange(N)
# DST spectrum
axes[0, 0].stem(n_idx, X_dst, linefmt="#7c3aed", markerfmt="o", basefmt="k-")
axes[0, 0].set_title("DST Coefficients")
axes[0, 0].set_xlabel("Index k")
axes[0, 0].set_ylabel("X_DST[k]")
axes[0, 0].grid(True, alpha=0.3)
# DST reconstruction
axes[0, 1].plot(t, x, color="#1f2937", linewidth=2.0, label="Original", zorder=3)
axes[0, 1].plot(t, x_dst_back, color="#7c3aed", linewidth=1.5,
linestyle="--", label=f"DST roundtrip (err={dst_max_error:.1e})")
axes[0, 1].set_title("DST Forward + Inverse Roundtrip")
axes[0, 1].set_xlabel("t")
axes[0, 1].set_ylabel("x")
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)
# DCT spectrum
axes[1, 0].stem(n_idx, X_dct, linefmt="#059669", markerfmt="o", basefmt="k-")
axes[1, 0].set_title("DCT Coefficients")
axes[1, 0].set_xlabel("Index k")
axes[1, 0].set_ylabel("X_DCT[k]")
axes[1, 0].grid(True, alpha=0.3)
# DCT reconstruction
axes[1, 1].plot(t, x, color="#1f2937", linewidth=2.0, label="Original", zorder=3)
axes[1, 1].plot(t, x_dct_back, color="#059669", linewidth=1.5,
linestyle="--", label=f"DCT roundtrip (err={dct_max_error:.1e})")
axes[1, 1].set_title("DCT Forward + Inverse Roundtrip")
axes[1, 1].set_xlabel("t")
axes[1, 1].set_ylabel("x")
axes[1, 1].legend()
axes[1, 1].grid(True, alpha=0.3)
fig.suptitle("IMSL Sine/Cosine Transform: DST-II and DCT-II Roundtrip Fidelity",
fontsize=13, fontweight="bold")
fig.tight_layout()
fig.savefig(plot_path, format="svg")
plt.close(fig)
return {
"dst_max_error": dst_max_error,
"dct_max_error": dct_max_error,
"plot_path": str(plot_path),
}
if __name__ == "__main__":
run_demo_imsl_sine_cosine()
Plot Output¶
2×2 panel plot: original triangle wave (top-left), DST-II spectrum (top-right), DCT-II spectrum (bottom-left), and reconstructed signal overlaid on the original (bottom-right).¶
Console Output¶
IMSL Sine/Cosine Transform Example (N=32, triangle wave)
--------------------------------------------------
DST max reconstruction error 2.22e-16
DCT max reconstruction error 1.11e-16
--------------------------------------------------