Skip to content

feat(QuantumMechanics): number Hamiltonian of the harmonic oscillator, adjointness of the ladder operators - #1645

Merged
jstoobysmith merged 10 commits into
leanprover-community:masterfrom
KevorkianPhilippe:oscillator-ladder-2
Sep 21, 2026
Merged

jstoobysmith merged 10 commits into
leanprover-community:masterfrom
KevorkianPhilippe:oscillator-ladder-2

Conversation

@KevorkianPhilippe

@KevorkianPhilippe KevorkianPhilippe commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

AI disclosure

AI disclosure. This PR was generated with Claude Fable 5.1 (Claude Code) under my
supervision, following AI-POLICY.md and AGENTS.md. I have read every definition and lemma
statement and vouch that they state what the docstrings say. The statements were fixed before
the proofs were written and the operator identities were checked symbolically (sympy, in the
Schrodinger representation) beforehand.

Was stacked on #1644 (oscillator-ladder-1, now merged); master is merged in.

Fills the remaining TODO items of LadderOperators.lean except the last one (same quantum system,
which needs essential self-adjointness; left as a TODO together with the essential self-adjointness of
the number operators). No new Hamiltonian is defined: the lemmas are about the Hamiltonian
kineticOperator + potentialOperator of Basic.lean.

LadderOperators.lean, in namespace QuantumMechanics.HarmonicOscillator:

  • A.4: loweringOperator, raisingOperator (unbounded operators with the Schwartz submodule as
    domain, modelled on momentumOperator), loweringCLM_inner, raisingCLM_inner,
    loweringOperator_isFormalAdjoint_raisingOperator: aᵢ† is the formal adjoint of aᵢ.
  • B.3: numberCLM_inner: ⟪Nᵢ f, g⟫ = ⟪f, Nᵢ g⟫ for Schwartz maps.
  • C.1: sum_number_commutation_lowering, _raising, _number: with H_N = ∑ᵢ ℏ ωᵢ (Nᵢ + ½)
    written out, [H_N, aᵢ] = -ℏ ωᵢ aᵢ, [H_N, aᵢ†] = ℏ ωᵢ aᵢ†, [H_N, Nᵢ] = 0.
  • C.2: sum_number_apply: H_N ψ = (1/2m) ∑ᵢ pᵢ (pᵢ ψ) + V ψ pointwise on Schwartz maps (the
    canonical commutation relation and ξᵢ² m ωᵢ = ℏ do the work); schwartzSubmodule_le_hamiltonian_domain
    (by temperate growth of the potential); hamiltonian_apply_schwartz: on a Schwartz map the Hamiltonian
    of Basic.lean acts as H_N (almost-everywhere identification of the potential operator);
    hamiltonian_inner_schwartz: the Hamiltonian is symmetric on the Schwartz submodule.

HarmonicOscillator/NumberOperator.lean (new file): numberOperator (unbounded operator with the
Schwartz submodule as domain), numberOperator_apply, numberOperator_isSymmetric.

Small lemmas placed next to the objects they are about:

  • HarmonicOscillator/Basic.lean: ξ_sq_mul_ofReal, potentialFunction_apply
    (V(x) = ∑ᵢ ½ m ωᵢ² xᵢ²), potentialFunction_hasTemperateGrowth; kineticOperator_apply_schwartz
    and potentialOperator_apply_schwartz, right after the definitions of the two operators.
  • Operators/Commutation.lean: id_commutation, position_commutation_momentum_apply (the
    canonical commutation relation pointwise).
  • Operators/Position.lean, Operators/Momentum.lean: positionCLM_inner, momentumCLM_inner
    (symmetry of xᵢ and pᵢ on Schwartz maps, in terms of the continuous linear maps).

Reviewer map: loweringCLM_inner (the adjointness computation), sum_number_apply (the identity
H_N = K + V), then hamiltonian_apply_schwartz (domain inclusion and the almost-everywhere
identification of the potential operator).

Update (Sept 16). Review of Sept 15 applied: the two _apply_schwartz lemmas moved next to their
definitions, the number operators as unbounded operators moved to their own file, and the separate
definitions numberHamiltonianCLM / numberHamiltonian replaced by lemmas about the existing
Hamiltonian.

🤖 Generated with Claude Code

Philippe Kevorkian and others added 2 commits September 11, 2026 12:14
…scillator, commutation relations

Defines the lowering, raising and number operators of the d-dimensional quantum harmonic
oscillator on Schwartz maps and proves their commutation relations from the canonical
commutation relations: [a_i, a_j^dag] = delta_ij, [a_i, a_j] = 0, [N_i, N_j] = 0,
[N_i, a_j] = -delta_ij a_j, [N_i, a_j^dag] = delta_ij a_j^dag, a_i a_i^dag = N_i + 1, and the
position and momentum operators in terms of the ladder operators. Fills the first six TODO items
of LadderOperators.lean; the adjointness, symmetry and Hamiltonian items remain.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…, adjointness of the ladder operators

Lifts the ladder and number operators to unbounded operators with the Schwartz submodule as
domain, proves that the raising operator is the formal adjoint of the lowering operator and that
the number operators are symmetric. Defines the Hamiltonian H_N = sum_i hbar omega_i (N_i + 1/2),
proves its commutation relations with the ladder and number operators, shows that on Schwartz maps
it is the kinetic-plus-potential Hamiltonian of Basic.lean, and that as unbounded operators
numberHamiltonian <= hamiltonian; H_N is symmetric. Small lemmas placed next to their objects:
potentialFunction_apply and its temperate growth (Basic.lean), the pointwise canonical commutation
relation and id_commutation (Commutation.lean), positionCLM_inner and momentumCLM_inner.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added the large label Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for this pull-request (PR). If this is your first PR, welcome to the community!

Below is what will happen next. Please read carefully if you are not familiar with the process. You may open other PRs while this one is being reviewed, and can stack PRs on top of each other, so don't let these steps slow you down.

  1. Some automated checks will be run on your PR. You can see the results of these checks at the buttom of your PR page. If any of these checks fail, you will need to fix the issues before your PR can be merged. You can learn more about these here, including how to run them locally, which is sometimes quicker than relying on the GitHub Actions. If you have never had a PR merged before, you may have to wait for a reviewer to manually start these checks (this is for security).

  2. A reviewer will look at your PR and may ask you to make changes. This may happen a couple of days after you submit your PR, so you may need to be patient. But it should not be longer than that - if it is please bring it to the attention of the community on the Zulip. The level of review will depend on where your PR is submitted. If it is submitted to ./Physlib or ./QuantumInfo, the review will be more thorough than if it is submitted to ./PhyslibAlpha. You can find out more about what the review process is looking for in our review guidelines. If a reviewer adds an awaiting-author label to your PR, address the review comments, then please remove that label by adding a comment with -awaiting-author. This helps us keep track of reviews.

  3. The reviewer will either approve your PR, or request more changes (in which case we return to step 2). Once your PR is approved, it will be merged by a maintainer, this should happen shortly after approval, though you may get more comments at this stage.

Tip: The easiest way to get have a fast review is to submit a PR that is small and self-contained, and has clear documentation explaining why things are the way they are in your chages.

If you have any problems or questions, please reach out to the community on the Zulip.

Philippe Kevorkian and others added 2 commits September 13, 2026 10:25
- one `namespace QuantumMechanics.HarmonicOscillator`;
- `lowering`, `raising`, `number` renamed `loweringCLM`, `raisingCLM`, `numberCLM`
  (operators on Schwartz maps, like `positionCLM` and `momentumCLM`);
- `ξ_ofReal_ne_zero` moved to `HarmonicOscillator/Basic.lean`, `ℏ_ofReal_ne_zero` to
  `PlanckConstant.lean`;
- the `I ^ 2 = -1` and `√2 ^ 2 = 2` rewrites precede `field_simp` (after `ring_nf`).

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…y morrison-daniel: CLM names, moved lemmas, rewrites before field_simp)
@github-actions github-actions Bot added medium and removed large labels Sep 14, 2026
-/

/-- The Hamiltonian in terms of the number operators, `H_N = ∑ᵢ ℏ ωᵢ (Nᵢ + ½)`, on Schwartz maps. -/
def numberHamiltonianCLM : 𝓢(Space d, ℂ) →L[ℂ] 𝓢(Space d, ℂ) :=

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.

I would make this a lemma rather then a separate definition if possible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in the last two commits: numberHamiltonianCLM and numberHamiltonian are gone. The Hamiltonian of Basic.lean is used directly: hamiltonian_apply_schwartz says that on a Schwartz map it acts as ∑ᵢ ℏ ωᵢ (Nᵢ + ½) (with schwartzSubmodule_le_hamiltonian_domain for the domain), and hamiltonian_inner_schwartz gives its symmetry on the Schwartz submodule. The commutation relations are stated for the sum ∑ᵢ ℏ ωᵢ (Nᵢ + ½) written out (sum_number_commutation_lowering, _raising, _number), and sum_number_apply is the pointwise identity = (1/2m) ∑ᵢ pᵢ (pᵢ ψ) + V ψ. This is my reading of "if possible"; if you would rather keep a named abbreviation for the sum, say so and I will adjust. #1646 is updated accordingly (sum_number_eigenfunction, and hamiltonian_eigenstate now goes through hamiltonian_apply_schwartz).

-/

/-- The number operator as an unbounded operator with domain the Schwartz submodule. -/
def numberOperator : Q.HS →ₗ.[ℂ] Q.HS where

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.

Would maybe give this its own file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done: numberOperator, numberOperator_apply, numberOperator_isSymmetric and the TODO now live in HarmonicOscillator/NumberOperator.lean (registered in Physlib.lean). numberCLM_inner stays in LadderOperators.lean, next to loweringCLM_inner and raisingCLM_inner which it is built from.

- 2 * ((Q.ω i : ℝ) : ℂ) * ((Q.ξ i : ℝ) : ℂ) ^ 4 * 𝐩 i (𝐩 i ψ) x * ((Q.m : ℝ) : ℂ)) * I_sq

/-- The kinetic operator on a Schwartz map, `(1/2m) ∑ᵢ pᵢ (pᵢ f)`. -/
lemma kineticOperator_apply_schwartz (f : 𝓢(Space d, ℂ))

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.

Move next to the definition of kineticOperator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done: moved to Basic.lean, right after the definition of kineticOperator.

exact key _

/-- The potential operator on a Schwartz map, almost everywhere `V f`. -/
lemma potentialOperator_apply_schwartz (f : 𝓢(Space d, ℂ))

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.

move next to the definition of potentialOperator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done: moved to Basic.lean, right after the definition of potentialOperator.

@jstoobysmith

Copy link
Copy Markdown
Member

awaiting-author

@github-actions github-actions Bot added the awaiting-author A reviewer has asked the author a question or requested changes label Sep 15, 2026
Philippe Kevorkian added 2 commits September 15, 2026 09:24
… number Hamiltonian

- move kineticOperator_apply_schwartz and potentialOperator_apply_schwartz next to the
  definitions of kineticOperator and potentialOperator in Basic.lean;
- move the number operators as unbounded operators to NumberOperator.lean;
- replace the definitions numberHamiltonianCLM and numberHamiltonian by lemmas about the
  Hamiltonian of Basic.lean: hamiltonian_apply_schwartz (it acts on Schwartz maps as
  sum_i hbar omega_i (N_i + 1/2)), schwartzSubmodule_le_hamiltonian_domain and
  hamiltonian_inner_schwartz; the commutation relations are stated for this sum.
@jstoobysmith jstoobysmith removed the blocked-by-PR This PR depends on another PR label Sep 15, 2026
KevorkianPhilippe pushed a commit to KevorkianPhilippe/physlib that referenced this pull request Sep 16, 2026
…_schwartz

Follows the review of leanprover-community#1645: the Hamiltonian of Basic.lean is used directly, sum_number_eigenfunction
replaces numberHamiltonianCLM_eigenfunction.
@KevorkianPhilippe

Copy link
Copy Markdown
Contributor Author

Thanks for the review. The four points are applied (inline replies give the details):

  • kineticOperator_apply_schwartz and potentialOperator_apply_schwartz moved to Basic.lean, next to the definitions they are about;
  • the number operators as unbounded operators moved to a new file HarmonicOscillator/NumberOperator.lean;
  • the separate definitions numberHamiltonianCLM / numberHamiltonian are replaced by lemmas about the Hamiltonian of Basic.lean: hamiltonian_apply_schwartz (it acts on Schwartz maps as ∑ᵢ ℏ ωᵢ (Nᵢ + ½)), schwartzSubmodule_le_hamiltonian_domain, hamiltonian_inner_schwartz; the commutation relations and the pointwise identity are stated for the sum written out.

#1646 is updated on top (sum_number_eigenfunction, hamiltonian_eigenstate through hamiltonian_apply_schwartz). PR description updated.

-awaiting-author

@github-actions github-actions Bot removed the awaiting-author A reviewer has asked the author a question or requested changes label Sep 16, 2026
@@ -201,8 +268,6 @@ def numberCLM : 𝓢(Space d, ℂ) →L[ℂ] 𝓢(Space d, ℂ) := Q.raisingCLM

lemma numberCLM_eq : Q.numberCLM i = Q.raisingCLM i ∘L Q.loweringCLM i := rfl

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.

Would likewise move numberCLM to the NumberOperator file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 87f03321: the number operators and the Hamiltonian written through them now live in
NumberOperator.lean, so LadderOperators.lean is exactly the ladder operators.

Moved, in order: numberCLM, numberCLM_eq, number_commutation_lowering,
number_commutation_raising, number_commutation_number, lowering_comp_raising,
numberCLM_inner, then sum_number_commutation_lowering, sum_number_commutation_raising,
sum_number_commutation_number, sum_number_apply, schwartzSubmodule_le_hamiltonian_domain,
hamiltonian_apply_schwartz and hamiltonian_inner_schwartz. LadderOperators.lean
goes from 455 to 237 lines and NumberOperator.lean from 76 to 302; the sections of both files
are renumbered and the ## i. Overview, ## ii. Key results and ## iii. Table of contents
blocks rewritten on both sides.

No statement and no proof changed. The one thing the move needed is that

attribute [local instance 100] LieRing.ofAssociativeRing
attribute [local instance 100] LieAlgebra.ofAssociativeAlgebra

are file-local and do not cross the module boundary, so they are repeated in
NumberOperator.lean (without them the commutator proofs fail with "simp made no progress").
lake build Physlib is clean.

One consequence for the stack: Eigenstates.lean in #1646 uses eight of the moved names, so its
public import ... HarmonicOscillator.LadderOperators becomes
public import ... HarmonicOscillator.NumberOperator (which imports LadderOperators). I will
do that when rebasing #1646 on this branch.

@jstoobysmith

Copy link
Copy Markdown
Member

One more comment above; otherwise looks good.

awaiting-author

@github-actions github-actions Bot added the awaiting-author A reviewer has asked the author a question or requested changes label Sep 16, 2026
…nian to NumberOperator.lean

Review by jstoobysmith on leanprover-community#1645: move numberCLM to the NumberOperator file. Sections B
(number operators) and C (Hamiltonian on Schwartz maps) of LadderOperators.lean move to
NumberOperator.lean, which already imported it; the local Lie-ring instances are repeated
there. Module docstrings updated on both sides. No statement or proof changed.
@github-actions github-actions Bot added large and removed medium labels Sep 20, 2026
@KevorkianPhilippe

Copy link
Copy Markdown
Contributor Author

-awaiting-author

@github-actions github-actions Bot removed the awaiting-author A reviewer has asked the author a question or requested changes label Sep 20, 2026
One line of the module docstring rewritten in the move reached 101 characters (lint-style
ERR_LIN). Paragraph rewrapped, no content change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@jstoobysmith jstoobysmith 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.

Many thanks for iterating on the reviews. This looks good to me. I will merge shortly.

@jstoobysmith jstoobysmith added the ready-to-merge This PR is approved and will be merged shortly label Sep 21, 2026
@jstoobysmith
jstoobysmith merged commit a61f431 into leanprover-community:master Sep 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

large ready-to-merge This PR is approved and will be merged shortly t-quantum-mechanics Quantum mechanics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants