Time–Frequency Atoms with a Compact Window — Mathematica Lab






Time–Frequency Atoms with a Compact Window — Mathematica Lab





Harmonic Analysis — Time–Frequency Methods (Mathematica Lab)

Time–Frequency Atoms with a Compact Window (Mathematica)


Purpose, Conventions, and Learning Outcomes

We study atoms $b_{k,j}(t)=e^{-2\pi i k t}\,\mathbf{1}_{[0,1)}(t-j)$ built from a compactly supported window
and use them to analyze and reconstruct signals. The Fourier convention uses $2\pi$:
\[
\overline{e^{-2\pi i k t}} = e^{+2\pi i k t}.
\]

Outcomes. You will (i) define the window and atoms cleanly; (ii) compute
coefficients $c_{k,j}=\langle g,b_{k,j}\rangle$ stably; (iii) build partial reconstructions
$S_n$; (iv) visualize coefficient footprints; (v) measure reconstruction error; and (vi) extend to a Gaussian input.

Preliminaries — Window, Atoms, and Utilities

We implement indicator functions with UnitStep to avoid verbose Piecewise output and define
atoms $b_{k,j}(t)$ with window $f=\mathbf{1}_{[0,1)}$.
(* Indicator of [a,b) *)
Clear[indicator]
indicator[a_, b_][t_] := UnitStep[t - a] - UnitStep[t - b];

(* Window f = 1_[0,1) and translates *)
Clear[f]
f[t_] := indicator[0, 1][t];

(* Atoms b_{k,j}(t) = e^{-2 π i k t} f(t - j) *)
Clear[b]
b[t_, k_, j_] := Exp[-2 Pi I k t] * f[t - j];

(* Overlap of supports: g supported in [gL,gR], window on [j,j+1) *)
Clear[overlapInterval]
overlapInterval[{gL_, gR_}, j_Integer] := {Max[gL, j], Min[gR, j + 1]};

(* Safe numeric integrate on an interval; returns 0 if empty *)
Clear[safeNIntegrate]
safeNIntegrate[expr_, {t_, a_, b_}] := If[a < b, NIntegrate[expr, {t, a, b}], 0.0];

Activity A — Define and Visualize the Target Signal $g$

Task. Define $g(t)=t^2\,\mathbf{1}_{[-1,1)}(t)$ and plot it on $[-3,3]$.

Clear[g, gSupport]
gSupport = {-1, 1};
g[t_] := t^2 * indicator[-1, 1][t];

Plot[g[t], {t, -3, 3}, PlotRange -> All, PlotTheme -> "Detailed",
 AxesLabel -> {"t","g(t)"}, PlotLabel -> "g(t) = t^2 · 1_{[-1,1)}"]
Observation. Only windows with $j\in\{-1,0\}$ overlap with $g$.

Activity B — Coefficients and Partial Reconstructions $S_n$

Task. Implement a support-aware coefficient
$c_{k,j}=\int_{a}^{b} g(t)e^{2\pi i k t}\,dt$ with $[a,b]=[\max(g_L,j),\min(g_R,j+1)]$ and
build $S_n(t)=\sum_{|k|,|j|\le n} c_{k,j}\,b_{k,j}(t)$. Plot $g$, $\mathrm{Re}\,S_n$, and $|S_n|$.

Clear[cg]
cg[k_Integer, j_Integer] := Module[{a,b},
  {a,b} = overlapInterval[gSupport, j];
  safeNIntegrate[g[t] * Exp[+2 Pi I k t], {t, a, b}]
];

Clear[cgTable, Sg]
cgTable[n_Integer] := Table[cg[k,j], {k,-n,n}, {j,-n,n}];

Sg[n_Integer][t_] := Module[{ks=Range[-n,n], js=Range[-n,n]},
  Sum[cg[k,j]*b[t,k,j], {k,ks}, {j,js}]
];

With[{n=8},
 Show[
  Plot[g[t], {t,-2,2}, PlotRange -> All, PlotLegends -> {"g(t)"}],
  Plot[Evaluate[Re[Sg[n][t]]], {t,-2,2}, PlotLegends -> {"Re S_n(t)"}],
  Plot[Evaluate[Abs[Sg[n][t]]], {t,-2,2}, PlotLegends -> {"|S_n(t)|"}],
  PlotLabel -> Row[{"Partial reconstruction for n = ", n}]
 ]
];
Note. Using UnitStep avoids verbose Piecewise artifacts and improves rendering.

Activity C — Coefficient Footprint: Heatmap of $\lvert c_{k,j}\rvert$

Task. Compute and visualize $\lvert c_{k,j}\rvert$ for $|k|,|j|\le n$.

With[{n=8},
 ArrayPlot[Abs[cgTable[n]],
  ColorFunction -> "ThermometerColors",
  PlotLegends -> Automatic,
  FrameTicks -> {
    Table[{i, i-(n+1)}, {i,1,2n+1}],
    Table[{j, j-(n+1)}, {j,1,2n+1}]
  },
  FrameLabel -> {Style["j (time index)",14], Style["k (frequency index)",14]},
  PlotLabel -> Style[Row[{"|c_{k,j}| for n = ", n}],14]
 ]
]

Activity D — Quantifying Error (Grid RMSE)

Task. On a fixed interval, compute an $L^2$-like discrete error between $g$ and $\mathrm{Re}\,S_n$ and tabulate RMSE versus $n$.

Clear[reconstructionError]
reconstructionError[n_Integer, {a_,b_}, m_Integer:2000] := Module[
 {grid = Subdivide[a,b,m], gt, st, err2},
 gt = g /@ grid;
 st = Re[Sg[n][#]] & /@ grid;
 err2 = Mean[(gt - st)^2];
 <|"grid" -> grid, "MSE" -> err2, "RMSE" -> Sqrt[err2]|>
];

Table[{n, reconstructionError[n, {-1.5,1.5}, 2500]["RMSE"]}, {n,{5,8,12}}]

Activity E — Extension: Gaussian Input $h(t)=e^{-t^2}$

Task. For non-compact $h$, compute $c_{k,j}=\int_j^{j+1} h(t)\,e^{2\pi i k t}\,dt$ (window restricts support) and compare $h$ to $S_n$.

Clear[h]
h[t_] := Exp[-t^2];

Clear[coefOnWindow]
coefOnWindow[gfun_?NumericFunction, k_Integer, j_Integer] :=
  NIntegrate[gfun[t] * Exp[+2 Pi I k t], {t, j, j+1}];

Clear[ch, chTable, Sh]
ch[k_Integer, j_Integer] := coefOnWindow[h, k, j];
chTable[n_Integer] := Table[ch[k,j], {k,-n,n}, {j,-n,n}];

Sh[n_Integer][t_] := Module[{ks=Range[-n,n], js=Range[-n,n]},
  Sum[ch[k,j]*b[t,k,j], {k,ks}, {j,js}]
];

With[{n=6},
  Plot[{h[t], Abs[Sh[n][t]]}, {t,-4,4},
   PlotRange -> All, PlotLegends -> {"h","|S_n|"},
   PlotLabel -> "Gaussian vs. truncated expansion (n = 6)"]
]

Activity F — Exact Coefficient (Polynomial on a Window)

Task. For comparison, derive
$c_{k,j}=\displaystyle\int_j^{j+1} t^2 e^{2\pi i k t}\,dt$ symbolically and compare with numerics.

Clear[cPolyExact]
cPolyExact[k_, j_] := Assuming[
  k ∈ Integers && j ∈ Integers,
  Integrate[t^2 Exp[2 Pi I k t], {t, j, j+1}]
];

{cg[1,0], N[cPolyExact[1,0]]}

Appendix — Minimal Reproducer in Your Original Style

Purpose. Keeps your S[n] structure but removes noisy Piecewise printing and integrates only on the true overlap.
Clear[S]
S[n_Integer][t_] := Total @ Flatten @ Table[
  (NIntegrate[g[τ] * Conjugate[b[τ, k, j]], {τ, Sequence @@ overlapInterval[gSupport, j]}]) * b[t, k, j],
  {k, -n, n}, {j, -n, n}
];

Plot[{g[t], Abs[S[8][t]]}, {t, -1.2, 1.2}, PlotRange -> All,
 PlotLegends -> {"g","|S_8|"}, PlotLabel -> "g vs. |S_8|"]

Short Reflection

  1. Explain why the discontinuities of $g$ lead to Gibbs-like ripples in $S_n$ near $t=\pm 1$.
  2. Compare decay in $|c_{k,j}|$ when using the box window versus a smoother window.
  3. When is a larger $n$ beneficial, and when does it become wasteful for fixed accuracy on a compact interval?
© 2025 — V. Oussa. Page styling and interaction adapted from the department’s Mathematica activities template.