Skip to content

DOC: clarify CWT normalization details around sampling_period (issue #801) - #842

Merged
rgommers merged 5 commits into
PyWavelets:mainfrom
magnaprog:fix-cwt-normalization-docs
Sep 2, 2026
Merged

DOC: clarify CWT normalization details around sampling_period (issue #801)#842
rgommers merged 5 commits into
PyWavelets:mainfrom
magnaprog:fix-cwt-normalization-docs

Conversation

@magnaprog

@magnaprog magnaprog commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Why this change

Issue #801 raised a good question: when comparing a hand-written CWT with pywt.cwt, why can an extra 1/sqrt(fs) factor seem necessary to match amplitudes?

This PR improves the docs to make that behavior easier to understand.

What changed

  • Updated the pywt.cwt docstring to explicitly state that sampling_period affects the reported frequencies, not coefficient scaling.
  • Added a short normalization section in the CWT reference docs with the continuous-time formula and a sampled (Riemann-sum) form.
  • Clarified how a dt factor can appear in manual continuous-time discretizations, and why that may show up as sqrt(dt) / 1/sqrt(fs) depending on parameterization.

Notes

This is a documentation-only change. No runtime behavior is changed.

magnaprog and others added 3 commits September 2, 2026 07:40
The previous explanation described a physical-time Riemann-sum
implementation, which carries a factor sqrt(dt) *relative to* what cwt
returns. The reported symptom is the opposite: a hand-written convolution
that uses a scale in seconds in the 1/sqrt(a) prefactor while summing over
raw samples is too large by sqrt(fs), and needs 1/sqrt(fs) to match. Both
factors have the same magnitude but apply in opposite directions, so the
text as written would lead readers to correct the wrong way.

State instead what cwt actually computes, in units of samples:

    C[a, b] = 1/sqrt(a) * sum_n x[n] conj(psi((n - b)/a))

and derive the relation to the continuous-time transform from there, so
that the direction of the sqrt(dt) factor is unambiguous. Name the
mixed-convention mistake explicitly, since that is the one users hit.

Also:
- fix ``t_n = n\,dt``, which was inline literal markup and rendered the
  LaTeX escape verbatim
- use distinct symbols for the scale in samples and in seconds; the old
  text switched between the two meanings of `a` within a few lines
- retitle the section, since sampling_period is precisely the thing that
  does not affect the normalization, and drop the duplicate statement
  about it from the cwt docstring (it is already in the parameter docs)
- move the section after the cwt_scaling_demo plot, which the text above
  it refers to as "the example below"
- add a runnable example reproducing cwt with an explicit convolution,
  and document the two discretization effects that keep the agreement
  from being exact
- add a regression test pinning the convention
It is public in `__all__` and referenced from the CWT docs, but was the
only one of the scale/frequency conversion helpers missing an autodoc
entry.
@rgommers
rgommers force-pushed the fix-cwt-normalization-docs branch from bf3b123 to 0c4c0f1 Compare September 2, 2026 05:40

@rgommers rgommers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @magnaprog, this is a quite useful improvement to the documentation. All the main points were correct, the one thing that looked off was that in gh-801 the contributor stumbled over a factor 1/sqrt(a_sec) while your text used the Riemann sum's dt/sqrt(a_sec) (so a factor dt different); the actual is 1/sqrt(a_samples) either way, but the opposite direction could be confusing.

I updated and extended it; the essence of the explanation was kept.

@rgommers rgommers added this to the v1.10.0 milestone Sep 2, 2026
The new subsections used `~` underlines, but this file uses `^` for
third-level headings, so docutils reported an inconsistent title style
skipping from level 2 to 4.
# Conflicts:
#	pywt/tests/test_cwt_wavelets.py
@rgommers
rgommers merged commit d291c3d into PyWavelets:main Sep 2, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants