Add inverse Klein-Gordon example (mass parameter recovery)#2065
Add inverse Klein-Gordon example (mass parameter recovery)#2065gpartin wants to merge 5 commits intolululxvi:masterfrom
Conversation
Add examples/pinn_inverse/Klein_Gordon_inverse.py which demonstrates recovering the mass parameter m^2 in the Klein-Gordon equation: u_tt - u_xx + m^2 u = 0 from sparse observations of the solution field. Features: - Learnable parameter via dde.Variable (m^2 initialized at 1.0, true value 4.0) - Manufactured solution: u(x,t) = sin(pi*x) cos(omega*t), omega^2 = pi^2 + m^2 - 50 randomly sampled observation points constrain the parameter - Two-phase training: 30k Adam iterations + L-BFGS refinement - Follows existing inverse example patterns (diffusion_1d_inverse.py) This fills a gap in the inverse examples: the forward Klein-Gordon already exists (pinn_forward/Klein_Gordon.py), but no inverse counterpart existed. The Klein-Gordon equation is fundamental in relativistic quantum mechanics and field theory, making parameter recovery a relevant benchmark.
There was a problem hiding this comment.
Pull request overview
Adds a new DeepXDE PINN inverse-problem example that estimates the Klein–Gordon mass parameter (m^2) from sparse solution observations, complementing the existing forward Klein–Gordon example.
Changes:
- Introduces
examples/pinn_inverse/Klein_Gordon_inverse.pyimplementing mass-parameter recovery viadde.Variable. - Adds sparse observation constraints using
PointSetBCplus standard BC/ICs for a hyperbolic PDE. - Uses a two-phase optimization workflow (Adam then L-BFGS) with
VariableValuetracking.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
Please edit auxillary files as shown in #2056. Please give some idea of runtime and how much it "converges further with full 30k + L-BFGS". |
- Add docs/demos/pinn_inverse/klein.gordon.inverse.rst with problem setup, implementation walkthrough, training results, and complete code reference - Update docs/demos/pinn_inverse.rst to include the new example in the Time-dependent PDEs toctree
|
Thanks for the review! I've addressed both points:
The L-BFGS phase is critical — it reduces the error by nearly 100× and drives the parameter to the exact true value. |
echen5503
left a comment
There was a problem hiding this comment.
Overall an interesting example with good results even with sparse observation. Supported backends are correct. Documentation structure is correct. It addresses an area with comparatively few examples.
However, more comments on the code would be helpful, because inverse examples are harder to understand than forward problems.
|
|
||
| # Sparse observation data at 50 random interior points | ||
| rng = np.random.default_rng(42) | ||
| observe_x = np.column_stack( |
There was a problem hiding this comment.
It's important to mention here (in a comment) that these are (x, t) pairs, even though this is inferrable. Keep in mind that the audience of examples are new to deepXDE, and this clarification justifies the logic in all the indexing.
| [rng.uniform(-1, 1, 50), rng.uniform(0, 1, 50)] | ||
| ) | ||
| observe_y = func(observe_x) | ||
| ptset = dde.icbc.PointSetBC(observe_x, observe_y, component=0) |
There was a problem hiding this comment.
Same logic here: mention that component parameter specifies which output needs to satisfy the BC. (In this case, there is only one).
| metrics=["l2 relative error"], | ||
| external_trainable_variables=m_sq, | ||
| ) | ||
| variable = dde.callbacks.VariableValue(m_sq, period=1000, filename="variables.dat") |
There was a problem hiding this comment.
optionally explain this callback structure more (you already did in the docs)
|
|
||
| This description goes through the implementation of a solver for the above described inverse Klein-Gordon problem step-by-step. | ||
|
|
||
| First, the DeepXDE and NumPy modules are imported: |
There was a problem hiding this comment.
28-33 is not useful information.
…rim redundant import section in docs
|
Thanks for the detailed review @echen5503! I've pushed a commit addressing all four points:
Updated docs section also mirrors clarifications (1) and (2). Let me know if anything else needs attention! |
|
All comments addressed well, no further concerns. Will run final tests. |
|
Results approximately reproduced. Recommend merge @lululxvi if you consider this example useful, to me it seems like a good addition |
- Clarify that observe_x rows are (x, t) coordinate pairs (line 52) - Explain component=0 selects which output is constrained (line 57) - Expand VariableValue callback explanation (line 82) - Remove boilerplate constant definitions from RST tutorial (lines 28-33)
echen5503
left a comment
There was a problem hiding this comment.
IMO all changes here are nice except for the first one.
|
|
||
| This description goes through the implementation of a solver for the above described inverse Klein-Gordon problem step-by-step. | ||
|
|
||
| We define the true mass parameter :math:`m^2 = 4` and the corresponding frequency :math:`\omega`: |
There was a problem hiding this comment.
Don't remove. This is useful.
|
still working on this @gpartin? |
|
Yes, still interested! All review feedback from @echen5503 has been addressed and tests are passing. Is there anything else needed from us before merge, or are we just waiting for maintainer availability? Happy to push any final tweaks if they would help move this forward. |
|
Additionally, please put human effort into this PR; it is easier on our end to just prompt AI in this case. |
|
Thanks for the nudge - I just pushed a focused manual doc fix for your unresolved point. I restored the removed line in the implementation section of docs/demos/pinn_inverse/klein.gordon.inverse.rst:
and re-added the accompanying code snippet:
Commit: 6b16cf0 If you want the wording tightened further, I can revise it again right away. |
|
Ok. It's good now. |

Description
Add an inverse Klein-Gordon example demonstrating parameter recovery using PINNs. The example recovers the unknown mass parameter m² from sparse observations of the wave field.
Problem
The Klein-Gordon equation u_tt - u_xx + m² u = 0 with exact solution u(x,t) = sin(πx) cos(ωt) where ω² = π² + m². The true parameter m² = 4; the PINN starts from m² = 1 and recovers the true value from 50 random interior observation points.
Runtime and Convergence
Total runtime: ~8 minutes on GPU (PyTorch backend).
The L-BFGS refinement is essential — it improves the error by ~100× and recovers the exact parameter value.
Files Changed
Backends
Tested with PyTorch. Compatible with tensorflow.compat.v1, tensorflow, and paddle (as noted in the script header).