FastLSQ 0.6.0__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastlsq-0.6.0 → fastlsq-0.6.1}/CHANGELOG.md +158 -5
- {fastlsq-0.6.0 → fastlsq-0.6.1}/FastLSQ.egg-info/PKG-INFO +60 -13
- {fastlsq-0.6.0 → fastlsq-0.6.1}/FastLSQ.egg-info/SOURCES.txt +2 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/FastLSQ.egg-info/requires.txt +1 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/MANIFEST.in +1 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/PKG-INFO +60 -13
- {fastlsq-0.6.0 → fastlsq-0.6.1}/README.md +58 -12
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/__init__.py +1 -1
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/api.py +5 -1
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/augment.py +101 -6
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/basis.py +10 -1
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/kernels.py +52 -5
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/learnable.py +6 -2
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/linalg.py +63 -23
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/newton.py +29 -6
- fastlsq-0.6.1/fastlsq/py.typed +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/solvers.py +7 -5
- {fastlsq-0.6.0 → fastlsq-0.6.1}/pyproject.toml +5 -2
- {fastlsq-0.6.0 → fastlsq-0.6.1}/requirements.txt +1 -0
- fastlsq-0.6.1/tests/test_closed_forms_property.py +323 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_diagnostics_timing.py +4 -1
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_symbol.py +7 -2
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_vector_basis.py +15 -1
- {fastlsq-0.6.0 → fastlsq-0.6.1}/FastLSQ.egg-info/dependency_links.txt +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/FastLSQ.egg-info/top_level.txt +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/LICENSE +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/add_your_own_pde.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/benchmark_comparison.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/custom_features.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/fred_sde.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/fred_sde_fastlsq.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/gaia_potential.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/gaia_potential_fastlsq.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/horizons_ephemeris.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/numerai_alpha.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/numerai_alpha_fastlsq.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/run_all_fastlsq.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/__init__.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/_alsu_lattice.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/_common.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/run_all.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_beamloss_ode.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_betatron_tune.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_green_fff.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_hill_ivp.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_observe_fit_act_simulator.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_orbit_inverse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_passive_loco.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_perturbed_hill.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_sofb_observe_fit_act.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_streaming_archive_growth.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_synchrotron_ode.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_tides_3months.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_topoff_impulse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s01_visualize.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s02_plasma_wakefield.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s03_synchrobetatron.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s04_sunspots.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s05_helioseismology.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s06_tides.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s07_iers_earth_rotation.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s08_mauna_loa_co2.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s09_enso_qbo.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s10_pulsar_timing.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s11_modal_analysis.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s12_mems_resonator.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s13_variable_stars_kepler.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s14_eeg.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/scenarios/s15_circadian.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/extras/spectral_expansion.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/grad_shafranov.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/grid_inverse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/grid_rl_control.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/grid_swing.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/gs_inverse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/gs_rl_control.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/integral_equations.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/integro_differential_demo.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/inverse_heat_source.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/inverse_magnetostatics.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/inverse_source_position.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/learnable_helmholtz.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/memory_diffusion.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/orbit_hill.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/orbit_inverse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/orbit_rl.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/pde_discovery.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/rlc_integro_differential.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/run_all_extensions.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/run_linear.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/run_nonlinear.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/sdf_domains.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/tutorial_basic.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/tutorial_nonlinear.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/examples/vector_basis_stream_vorticity.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/benchmark.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/block.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/device.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/diagnostics.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/export.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/geometry.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/lightning.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/plotting.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/problems/__init__.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/problems/integral.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/problems/linear.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/problems/nonlinear.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/problems/regression.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/tuning.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/utils.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/vector.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/fastlsq/viz.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/setup.cfg +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_augment.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_basic.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_benchmarks_inverse.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_block.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_derivatives.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_device.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_geometry_sdf.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_grad_shafranov.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_grid_swing.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_integral.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_kernels.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_learnable.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_multi_integral.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_orbit_hill.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_problems_integral.py +0 -0
- {fastlsq-0.6.0 → fastlsq-0.6.1}/tests/test_projection.py +0 -0
|
@@ -2,6 +2,155 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to FastLSQ will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## Release tags
|
|
6
|
+
|
|
7
|
+
Every released version is tagged `vMAJOR.MINOR.PATCH`. The tags for 0.1.0 through
|
|
8
|
+
0.6.0 were **reconstructed in September 2026**: the project was published to PyPI for
|
|
9
|
+
its first year with only one tag (`v0.2.2`) ever created by hand.
|
|
10
|
+
|
|
11
|
+
Each tag was placed by comparing the `fastlsq/*.py` sources at every commit in the
|
|
12
|
+
repository against the sdist actually published to PyPI, not by guessing from dates.
|
|
13
|
+
Fourteen of the seventeen published releases matched a commit byte for byte. The one
|
|
14
|
+
pre-existing tag, `v0.2.2`, was left untouched and independently resolved to the same
|
|
15
|
+
commit the reconstruction chose, which is the main evidence that the method is sound.
|
|
16
|
+
|
|
17
|
+
Three tags are **approximate**, and their tag messages say so:
|
|
18
|
+
|
|
19
|
+
| Version | What is wrong | Authoritative artefact |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| 0.1.2 | The published sdist contains `fastlsq/problems/apebench.py`, which exists in no commit in this repository | `fastlsq-0.1.2.tar.gz` on PyPI |
|
|
22
|
+
| 0.1.3 | Same file, same problem | `fastlsq-0.1.3.tar.gz` on PyPI |
|
|
23
|
+
| 0.1.5 | The published `fastlsq/problems/linear.py` is ahead of every committed version of that file | `fastlsq-0.1.5.tar.gz` on PyPI |
|
|
24
|
+
|
|
25
|
+
All three were released from a working tree holding source that was never committed.
|
|
26
|
+
For those versions the sdist on PyPI is the record, not the tag.
|
|
27
|
+
|
|
28
|
+
### Versions documented here that were never released
|
|
29
|
+
|
|
30
|
+
- **0.2.0** (dated 2026-03-01 below) was never on PyPI and `pyproject.toml` never
|
|
31
|
+
declared it. The published sequence runs 0.1.4 → 0.1.5 → 0.2.1. There is no `v0.2.0`
|
|
32
|
+
tag. The entry is kept for the history of the work, not as a release.
|
|
33
|
+
- **0.4.3** and **0.5.0** are real code milestones on `main` -- `pyproject.toml`
|
|
34
|
+
declares each -- but neither was uploaded. The published sequence runs 0.4.2
|
|
35
|
+
(2026-07-20) straight to 0.6.0 (2026-07-21). Both are tagged, and both tags say
|
|
36
|
+
`NEVER PUBLISHED TO PyPI`.
|
|
37
|
+
|
|
38
|
+
### Releases missing from this file
|
|
39
|
+
|
|
40
|
+
**0.1.1, 0.1.2, 0.1.3 and 0.1.4 were published to PyPI but have no entry below.**
|
|
41
|
+
They are tagged, and their scope can be read from the tags and the commit history, but
|
|
42
|
+
this file jumps 0.1.0 → 0.2.0 → 0.1.5 and does not describe them. Reconstructing four
|
|
43
|
+
changelog entries a year after the fact would be invention rather than record, so the
|
|
44
|
+
gap is documented here instead of filled in.
|
|
45
|
+
|
|
46
|
+
## [0.6.1] - 2026-09-18
|
|
47
|
+
|
|
48
|
+
A correctness and packaging pass. No published number changes, and no API is
|
|
49
|
+
removed -- but three of the fixes below were silent wrong answers, not errors.
|
|
50
|
+
|
|
51
|
+
### Fixed -- silent wrong answers
|
|
52
|
+
|
|
53
|
+
- **kernels** -- `SeparableKernelOperator.inner_products` keyed its cache on
|
|
54
|
+
`(id(basis), n_features)`. A freed basis' address is reused by the next one, and
|
|
55
|
+
`LearnableFastLSQ.basis` builds a new basis object on every access, so a learnable fit
|
|
56
|
+
of a Fredholm problem could train on another basis' operators (measured error of the
|
|
57
|
+
assembled block 0.083 on entries of about 0.05, with no warning). The key is now the
|
|
58
|
+
storage pointer and version counter of `W` and `b`, plus a weak reference to the basis.
|
|
59
|
+
- **linalg** -- `method="qr"` on a rank-deficient matrix returned garbage with no
|
|
60
|
+
exception and no warning (`||x|| = 7e18`, residual `6e4`, where `svd` gives `59` and
|
|
61
|
+
`1e-8`). The diagonal of `R` is now tested against `rcond` and warned about.
|
|
62
|
+
- **learnable** -- `driver="gelsd"` was hard-coded, and torch accepts the rank-revealing
|
|
63
|
+
LAPACK drivers on CPU only, so the learnable path could not run off CPU. Now CPU-only.
|
|
64
|
+
|
|
65
|
+
### Fixed -- missing operators
|
|
66
|
+
|
|
67
|
+
- **augment** -- `AugmentedBasis` gained `hessian_diag`, `biharmonic`, `advection` and
|
|
68
|
+
`multi_integral`, with the closed forms for the polynomial columns.
|
|
69
|
+
`MultiIntegralOperator.apply(aug, x)` used to raise `AttributeError`, so the `Wave1D`,
|
|
70
|
+
`Wave2D_MS` and `Maxwell2D_TM` problems could not take an augmented basis at all.
|
|
71
|
+
- **basis** -- a 0-d (scalar) symbol is a constant multiplier, not an error.
|
|
72
|
+
- **solvers** -- `add_block(scale=...)` accepts a tuple or tensor of per-axis scales, not
|
|
73
|
+
just a list or ndarray.
|
|
74
|
+
- **newton** -- when no backtracked step satisfied Armijo, the loop restored `beta` and
|
|
75
|
+
then recomputed the identical step until `max_iter`, while `history` recorded the last
|
|
76
|
+
alpha tried as if the step had been taken. It now stops, records the rejection as
|
|
77
|
+
`step_size 0.0`, and tags every exit with a stop reason.
|
|
78
|
+
- **kernels** -- `from_inner_products` objects now raise a clear error from
|
|
79
|
+
`check_quadrature` and `degenerate_eigenvalues` instead of failing inside `leggauss(0)`.
|
|
80
|
+
|
|
81
|
+
### Changed -- diagnostics and documentation
|
|
82
|
+
|
|
83
|
+
- **linalg** -- `return_info` now carries `method_used`, because `"auto"` picks its
|
|
84
|
+
back-end at run time; on CPU with `mu = 0` it never runs QR (Cholesky probe, then
|
|
85
|
+
`gelsd`), which the module docstring claimed otherwise. The docstring now describes what
|
|
86
|
+
the code does.
|
|
87
|
+
- **linalg/api** -- `rank_used` is documented as what it is: a post-hoc count of singular
|
|
88
|
+
values above `rcond * sigma_max`, not the rank the back-end worked with.
|
|
89
|
+
- **newton** -- the convergence test is relative to the first residual, as the code always
|
|
90
|
+
did; the docstring said absolute.
|
|
91
|
+
- **kernels** -- `degenerate_eigenvalues` no longer runs a full quadrature for inner
|
|
92
|
+
products it discards, and its docstring no longer claims the values depend on the basis.
|
|
93
|
+
- **basis** -- the `1/sqrt(N)` normalisation convention is documented, including the
|
|
94
|
+
differing defaults of `solve_linear` and `solve_nonlinear`.
|
|
95
|
+
|
|
96
|
+
### Tests
|
|
97
|
+
|
|
98
|
+
- `test_symbol` used `np.trapz`, removed in NumPy 2, so the fractional-Laplacian check
|
|
99
|
+
against the singular-integral definition silently never ran on a current install. With
|
|
100
|
+
`np.trapezoid` the suite goes from 202 passed / 3 failed to 205 passed.
|
|
101
|
+
- New `tests/test_closed_forms_property.py`: 46 property tests checking every closed form
|
|
102
|
+
against an independent reference (autograd, Gauss-Legendre quadrature, the analytic
|
|
103
|
+
characteristic value) at random dimensions, feature counts, bandwidths and orders,
|
|
104
|
+
including the cache-invalidation regression above.
|
|
105
|
+
- `test_version` compared `fastlsq.__version__` against a hard-coded literal, so it had
|
|
106
|
+
to be edited on every release and never caught anything. It now compares
|
|
107
|
+
`__version__` against the version in `pyproject.toml`, which is the drift that can
|
|
108
|
+
actually happen.
|
|
109
|
+
- Full suite: 251 passed.
|
|
110
|
+
|
|
111
|
+
### Packaging and repository
|
|
112
|
+
|
|
113
|
+
- **`scipy` is declared as a test dependency.** Eight scripts under `examples/` use it for
|
|
114
|
+
their reference solvers, and `tests/test_grad_shafranov.py` and `tests/test_grid_swing.py`
|
|
115
|
+
import those scripts -- but `scipy` appeared only in the `battery` extra, never in `dev`
|
|
116
|
+
or `requirements.txt`. `pip install -e ".[dev]"` into a clean environment produced six
|
|
117
|
+
errors; the suite passed locally only where scipy happened to be installed for other
|
|
118
|
+
reasons. Found by the new CI on its first run.
|
|
119
|
+
- `fastlsq/py.typed` is now actually shipped. `[tool.setuptools.package-data]` had
|
|
120
|
+
declared it since 0.4.0, but the file did not exist, so the package advertised PEP 561
|
|
121
|
+
inline typing that type checkers never saw.
|
|
122
|
+
- The build requirement is `setuptools>=77.0`. `license = "MIT"` is the PEP 639 SPDX
|
|
123
|
+
expression form, which setuptools only understands from 77.0 on; the pin said `>=68.0`.
|
|
124
|
+
- Continuous integration runs the suite on Python 3.9 through 3.12 (`.github/workflows/tests.yml`).
|
|
125
|
+
- The JOSS submission draft (`paper.md`, `paper.bib`) is tracked in the repository.
|
|
126
|
+
- Two 0.5.x changelog entries advertised example scripts under `examples/inverse/` that
|
|
127
|
+
were never shipped; both entries now say so.
|
|
128
|
+
|
|
129
|
+
### Fixed -- documentation
|
|
130
|
+
|
|
131
|
+
- **The citation in `README.md` had the wrong paper title.** It read *"FastLSQ: A
|
|
132
|
+
Framework for One-Shot PDE Solving"*; the actual title of arXiv:2602.10541 is
|
|
133
|
+
*"FastLSQ: Solving PDEs in One Shot via Fourier Features with Exact Analytical
|
|
134
|
+
Derivatives"*. Anyone who copied that BibTeX block produced a wrong bibliography
|
|
135
|
+
entry. The block now matches the arXiv record and carries the DOI.
|
|
136
|
+
- `paper.bib` cited the same preprint without the `FastLSQ:` title prefix. Corrected to
|
|
137
|
+
the arXiv title, so the JOSS paper and the README agree.
|
|
138
|
+
|
|
139
|
+
### Added -- release tags and README
|
|
140
|
+
|
|
141
|
+
- Release tags for every version, and the *Release tags* section above documenting how
|
|
142
|
+
they were reconstructed, which three are approximate, and which documented versions
|
|
143
|
+
were never released.
|
|
144
|
+
- `README.md`: status badges (CI, PyPI, Python versions, licence, arXiv); the
|
|
145
|
+
dependency and optional-extras list; a **Development** section covering the test
|
|
146
|
+
suite and CI; a **Releases and versioning** section; and a pointer to the JOSS paper
|
|
147
|
+
draft.
|
|
148
|
+
|
|
149
|
+
### Changed -- README
|
|
150
|
+
|
|
151
|
+
- `README.md`: the BerkeleyLab ATAP talk link moved from above the project title, where
|
|
152
|
+
it preceded the description, into the **Paper** section with the other references.
|
|
153
|
+
|
|
5
154
|
## [0.6.0] - 2026-07-21
|
|
6
155
|
|
|
7
156
|
Completes the operator taxonomy: multi-axis integrals, separable kernels, and
|
|
@@ -361,8 +510,10 @@ augmentation columns (§2.3).
|
|
|
361
510
|
Gauss--Hermite quadrature of the slice integral to machine precision in d = 2, 3, 4
|
|
362
511
|
(≤4e-13 observed), that autodiff of the rows wrt `c` matches finite differences, and
|
|
363
512
|
that a windowed field is recovered from its projections at several directions in one
|
|
364
|
-
LSQ.
|
|
365
|
-
|
|
513
|
+
LSQ. *(Correction, 0.6.1: this entry also announced an
|
|
514
|
+
`examples/inverse/tomography_projection.py` demonstrating the full reconstruction plus
|
|
515
|
+
the differentiable-optics gradient. That example was never shipped; the reconstruction
|
|
516
|
+
and the gradient check live in `tests/test_projection.py` instead.)*
|
|
366
517
|
|
|
367
518
|
### Scope (honest)
|
|
368
519
|
|
|
@@ -401,9 +552,11 @@ augmentation columns (§2.3).
|
|
|
401
552
|
linear-least-squares design matrix; coefficients stay differentiable so learnable
|
|
402
553
|
integral-term coefficients train through the solve. All three exported from `fastlsq`.
|
|
403
554
|
- **Examples** `examples/integro_differential_demo.py` (one-shot forward solve of
|
|
404
|
-
`u'(x) + ∫_0^x u ds = f`, rel-L2 ~3e-11)
|
|
405
|
-
`examples/inverse/inverse_memory_kernel.py`
|
|
406
|
-
noisy data via AdamW through the differentiable solve
|
|
555
|
+
`u'(x) + ∫_0^x u ds = f`, rel-L2 ~3e-11). *(Correction, 0.6.1: this entry also
|
|
556
|
+
announced an `examples/inverse/inverse_memory_kernel.py` recovering an unknown memory
|
|
557
|
+
strength λ from noisy data via AdamW through the differentiable solve. That example was
|
|
558
|
+
never shipped; gradient flow through the solve is covered by `tests/test_integral.py`.)*
|
|
559
|
+
New `tests/test_integral.py`
|
|
407
560
|
asserts ∫-then-∂ round-trips to identity, Volterra/definite match quadrature, the DC
|
|
408
561
|
guard stays finite, and gradients flow to learnable coefficients.
|
|
409
562
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: FastLSQ
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: One-shot PDE solving via Fourier features with exact analytical derivatives; rank-revealing solvers, learnable anisotropic bandwidth, and CPU/CUDA/MPS support
|
|
5
5
|
Author: Antonin Sulc
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,6 +33,7 @@ Requires-Dist: scipy>=1.10; extra == "battery"
|
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
35
35
|
Requires-Dist: pandas>=2.0; extra == "dev"
|
|
36
|
+
Requires-Dist: scipy>=1.10; extra == "dev"
|
|
36
37
|
Requires-Dist: build; extra == "dev"
|
|
37
38
|
Requires-Dist: twine; extra == "dev"
|
|
38
39
|
Provides-Extra: lightning
|
|
@@ -41,8 +42,11 @@ Dynamic: license-file
|
|
|
41
42
|
|
|
42
43
|
# FastLSQ
|
|
43
44
|
|
|
44
|
-
[
|
|
45
|
-
|
|
45
|
+
[](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
46
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
47
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
[](https://arxiv.org/abs/2602.10541)
|
|
46
50
|
|
|
47
51
|
<p align="center">
|
|
48
52
|
<img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
|
|
@@ -68,14 +72,23 @@ regularisation, 1/sqrt(N) feature normalisation, and continuation/homotopy.
|
|
|
68
72
|
pip install fastlsq
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
Requires Python 3.9+, PyTorch 2.0+, NumPy 1.24+ and Matplotlib 3.7+. There is no
|
|
76
|
+
compiled extension and no mesh library: everything runs on the PyTorch tensor stack,
|
|
77
|
+
on CPU, CUDA or Apple-MPS.
|
|
78
|
+
|
|
79
|
+
For development -- test runner, the SciPy reference solvers the example scripts
|
|
80
|
+
compare against, and the build tools:
|
|
72
81
|
|
|
73
82
|
```bash
|
|
74
83
|
git clone https://github.com/sulcantonin/FastLSQ.git
|
|
75
84
|
cd FastLSQ
|
|
76
85
|
pip install -e ".[dev]"
|
|
86
|
+
pytest tests/ # 251 tests, about 30 s on a laptop CPU
|
|
77
87
|
```
|
|
78
88
|
|
|
89
|
+
Optional extras: `.[battery]` for the battery-degradation examples (`progpy`),
|
|
90
|
+
`.[lightning]` for the PyTorch Lightning training loop.
|
|
91
|
+
|
|
79
92
|
## Quick start
|
|
80
93
|
|
|
81
94
|
### Solve a linear PDE in one line
|
|
@@ -516,23 +529,57 @@ See `examples/add_your_own_pde.py` for the complete tutorial.
|
|
|
516
529
|
- **PyTorch Lightning**: Integration for training loops
|
|
517
530
|
- **20+ benchmark problems**: Linear, nonlinear, and regression-mode PDEs
|
|
518
531
|
|
|
532
|
+
## Development
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
pip install -e ".[dev]"
|
|
536
|
+
pytest tests/
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
The suite is 251 tests and runs in about 30 seconds on a laptop CPU. Every closed
|
|
540
|
+
form -- derivative, integral, Fourier symbol, projection -- is checked against an
|
|
541
|
+
independent reference (autograd, Gauss-Legendre quadrature, or the analytic value) in
|
|
542
|
+
`tests/test_closed_forms_property.py`, so a wrong closed form fails the suite rather
|
|
543
|
+
than silently returning a plausible number.
|
|
544
|
+
|
|
545
|
+
[Continuous integration](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
546
|
+
runs the suite on Python 3.9, 3.10, 3.11 and 3.12, and separately builds the sdist and
|
|
547
|
+
wheel and checks their metadata.
|
|
548
|
+
|
|
549
|
+
## Releases and versioning
|
|
550
|
+
|
|
551
|
+
Released versions are on [PyPI](https://pypi.org/project/FastLSQ/) and tagged in this
|
|
552
|
+
repository as `vMAJOR.MINOR.PATCH`. `CHANGELOG.md` documents every release.
|
|
553
|
+
|
|
554
|
+
The tags for 0.1.0 through 0.6.0 were reconstructed after the fact, since the project
|
|
555
|
+
was published to PyPI for its first year without tagging. Each tag was matched to its
|
|
556
|
+
commit by comparing the commit's `fastlsq/*.py` sources against the sdist actually
|
|
557
|
+
published, so most are byte-for-byte exact; the three that are not say so in the tag
|
|
558
|
+
message. See the *Release tags* note at the top of `CHANGELOG.md`.
|
|
559
|
+
|
|
519
560
|
## Paper
|
|
520
561
|
|
|
521
|
-
The
|
|
562
|
+
The preprint is on [arXiv](https://arxiv.org/abs/2602.10541). A software paper for the
|
|
563
|
+
[Journal of Open Source Software](https://joss.theoj.org/) is drafted in
|
|
564
|
+
[`paper.md`](paper.md).
|
|
565
|
+
|
|
566
|
+
There is also a [BerkeleyLab ATAP talk](https://github.com/sulcantonin/FastLSQ/raw/main/presentations/ATAP_Sulc_20260324.pptx)
|
|
567
|
+
covering the method and the accelerator-physics applications.
|
|
522
568
|
|
|
523
569
|
## Citing this work
|
|
524
570
|
|
|
525
571
|
If you use FastLSQ in your research, please cite:
|
|
526
572
|
|
|
527
573
|
```bibtex
|
|
528
|
-
@misc{
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
574
|
+
@misc{sulc2026fastlsq,
|
|
575
|
+
author = {Sulc, Antonin},
|
|
576
|
+
title = {{FastLSQ}: Solving {PDEs} in One Shot via {Fourier} Features with Exact Analytical Derivatives},
|
|
577
|
+
year = {2026},
|
|
578
|
+
eprint = {2602.10541},
|
|
579
|
+
archivePrefix = {arXiv},
|
|
580
|
+
primaryClass = {math.NA},
|
|
581
|
+
doi = {10.48550/arXiv.2602.10541},
|
|
582
|
+
url = {https://arxiv.org/abs/2602.10541}
|
|
536
583
|
}
|
|
537
584
|
```
|
|
538
585
|
|
|
@@ -94,6 +94,7 @@ fastlsq/lightning.py
|
|
|
94
94
|
fastlsq/linalg.py
|
|
95
95
|
fastlsq/newton.py
|
|
96
96
|
fastlsq/plotting.py
|
|
97
|
+
fastlsq/py.typed
|
|
97
98
|
fastlsq/solvers.py
|
|
98
99
|
fastlsq/tuning.py
|
|
99
100
|
fastlsq/utils.py
|
|
@@ -108,6 +109,7 @@ tests/test_augment.py
|
|
|
108
109
|
tests/test_basic.py
|
|
109
110
|
tests/test_benchmarks_inverse.py
|
|
110
111
|
tests/test_block.py
|
|
112
|
+
tests/test_closed_forms_property.py
|
|
111
113
|
tests/test_derivatives.py
|
|
112
114
|
tests/test_device.py
|
|
113
115
|
tests/test_diagnostics_timing.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: FastLSQ
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: One-shot PDE solving via Fourier features with exact analytical derivatives; rank-revealing solvers, learnable anisotropic bandwidth, and CPU/CUDA/MPS support
|
|
5
5
|
Author: Antonin Sulc
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,6 +33,7 @@ Requires-Dist: scipy>=1.10; extra == "battery"
|
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
35
35
|
Requires-Dist: pandas>=2.0; extra == "dev"
|
|
36
|
+
Requires-Dist: scipy>=1.10; extra == "dev"
|
|
36
37
|
Requires-Dist: build; extra == "dev"
|
|
37
38
|
Requires-Dist: twine; extra == "dev"
|
|
38
39
|
Provides-Extra: lightning
|
|
@@ -41,8 +42,11 @@ Dynamic: license-file
|
|
|
41
42
|
|
|
42
43
|
# FastLSQ
|
|
43
44
|
|
|
44
|
-
[
|
|
45
|
-
|
|
45
|
+
[](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
46
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
47
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
[](https://arxiv.org/abs/2602.10541)
|
|
46
50
|
|
|
47
51
|
<p align="center">
|
|
48
52
|
<img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
|
|
@@ -68,14 +72,23 @@ regularisation, 1/sqrt(N) feature normalisation, and continuation/homotopy.
|
|
|
68
72
|
pip install fastlsq
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
Requires Python 3.9+, PyTorch 2.0+, NumPy 1.24+ and Matplotlib 3.7+. There is no
|
|
76
|
+
compiled extension and no mesh library: everything runs on the PyTorch tensor stack,
|
|
77
|
+
on CPU, CUDA or Apple-MPS.
|
|
78
|
+
|
|
79
|
+
For development -- test runner, the SciPy reference solvers the example scripts
|
|
80
|
+
compare against, and the build tools:
|
|
72
81
|
|
|
73
82
|
```bash
|
|
74
83
|
git clone https://github.com/sulcantonin/FastLSQ.git
|
|
75
84
|
cd FastLSQ
|
|
76
85
|
pip install -e ".[dev]"
|
|
86
|
+
pytest tests/ # 251 tests, about 30 s on a laptop CPU
|
|
77
87
|
```
|
|
78
88
|
|
|
89
|
+
Optional extras: `.[battery]` for the battery-degradation examples (`progpy`),
|
|
90
|
+
`.[lightning]` for the PyTorch Lightning training loop.
|
|
91
|
+
|
|
79
92
|
## Quick start
|
|
80
93
|
|
|
81
94
|
### Solve a linear PDE in one line
|
|
@@ -516,23 +529,57 @@ See `examples/add_your_own_pde.py` for the complete tutorial.
|
|
|
516
529
|
- **PyTorch Lightning**: Integration for training loops
|
|
517
530
|
- **20+ benchmark problems**: Linear, nonlinear, and regression-mode PDEs
|
|
518
531
|
|
|
532
|
+
## Development
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
pip install -e ".[dev]"
|
|
536
|
+
pytest tests/
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
The suite is 251 tests and runs in about 30 seconds on a laptop CPU. Every closed
|
|
540
|
+
form -- derivative, integral, Fourier symbol, projection -- is checked against an
|
|
541
|
+
independent reference (autograd, Gauss-Legendre quadrature, or the analytic value) in
|
|
542
|
+
`tests/test_closed_forms_property.py`, so a wrong closed form fails the suite rather
|
|
543
|
+
than silently returning a plausible number.
|
|
544
|
+
|
|
545
|
+
[Continuous integration](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
546
|
+
runs the suite on Python 3.9, 3.10, 3.11 and 3.12, and separately builds the sdist and
|
|
547
|
+
wheel and checks their metadata.
|
|
548
|
+
|
|
549
|
+
## Releases and versioning
|
|
550
|
+
|
|
551
|
+
Released versions are on [PyPI](https://pypi.org/project/FastLSQ/) and tagged in this
|
|
552
|
+
repository as `vMAJOR.MINOR.PATCH`. `CHANGELOG.md` documents every release.
|
|
553
|
+
|
|
554
|
+
The tags for 0.1.0 through 0.6.0 were reconstructed after the fact, since the project
|
|
555
|
+
was published to PyPI for its first year without tagging. Each tag was matched to its
|
|
556
|
+
commit by comparing the commit's `fastlsq/*.py` sources against the sdist actually
|
|
557
|
+
published, so most are byte-for-byte exact; the three that are not say so in the tag
|
|
558
|
+
message. See the *Release tags* note at the top of `CHANGELOG.md`.
|
|
559
|
+
|
|
519
560
|
## Paper
|
|
520
561
|
|
|
521
|
-
The
|
|
562
|
+
The preprint is on [arXiv](https://arxiv.org/abs/2602.10541). A software paper for the
|
|
563
|
+
[Journal of Open Source Software](https://joss.theoj.org/) is drafted in
|
|
564
|
+
[`paper.md`](paper.md).
|
|
565
|
+
|
|
566
|
+
There is also a [BerkeleyLab ATAP talk](https://github.com/sulcantonin/FastLSQ/raw/main/presentations/ATAP_Sulc_20260324.pptx)
|
|
567
|
+
covering the method and the accelerator-physics applications.
|
|
522
568
|
|
|
523
569
|
## Citing this work
|
|
524
570
|
|
|
525
571
|
If you use FastLSQ in your research, please cite:
|
|
526
572
|
|
|
527
573
|
```bibtex
|
|
528
|
-
@misc{
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
574
|
+
@misc{sulc2026fastlsq,
|
|
575
|
+
author = {Sulc, Antonin},
|
|
576
|
+
title = {{FastLSQ}: Solving {PDEs} in One Shot via {Fourier} Features with Exact Analytical Derivatives},
|
|
577
|
+
year = {2026},
|
|
578
|
+
eprint = {2602.10541},
|
|
579
|
+
archivePrefix = {arXiv},
|
|
580
|
+
primaryClass = {math.NA},
|
|
581
|
+
doi = {10.48550/arXiv.2602.10541},
|
|
582
|
+
url = {https://arxiv.org/abs/2602.10541}
|
|
536
583
|
}
|
|
537
584
|
```
|
|
538
585
|
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# FastLSQ
|
|
2
2
|
|
|
3
|
-
[
|
|
4
|
-
|
|
3
|
+
[](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
4
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
5
|
+
[](https://pypi.org/project/FastLSQ/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://arxiv.org/abs/2602.10541)
|
|
5
8
|
|
|
6
9
|
<p align="center">
|
|
7
10
|
<img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
|
|
@@ -27,14 +30,23 @@ regularisation, 1/sqrt(N) feature normalisation, and continuation/homotopy.
|
|
|
27
30
|
pip install fastlsq
|
|
28
31
|
```
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
Requires Python 3.9+, PyTorch 2.0+, NumPy 1.24+ and Matplotlib 3.7+. There is no
|
|
34
|
+
compiled extension and no mesh library: everything runs on the PyTorch tensor stack,
|
|
35
|
+
on CPU, CUDA or Apple-MPS.
|
|
36
|
+
|
|
37
|
+
For development -- test runner, the SciPy reference solvers the example scripts
|
|
38
|
+
compare against, and the build tools:
|
|
31
39
|
|
|
32
40
|
```bash
|
|
33
41
|
git clone https://github.com/sulcantonin/FastLSQ.git
|
|
34
42
|
cd FastLSQ
|
|
35
43
|
pip install -e ".[dev]"
|
|
44
|
+
pytest tests/ # 251 tests, about 30 s on a laptop CPU
|
|
36
45
|
```
|
|
37
46
|
|
|
47
|
+
Optional extras: `.[battery]` for the battery-degradation examples (`progpy`),
|
|
48
|
+
`.[lightning]` for the PyTorch Lightning training loop.
|
|
49
|
+
|
|
38
50
|
## Quick start
|
|
39
51
|
|
|
40
52
|
### Solve a linear PDE in one line
|
|
@@ -475,23 +487,57 @@ See `examples/add_your_own_pde.py` for the complete tutorial.
|
|
|
475
487
|
- **PyTorch Lightning**: Integration for training loops
|
|
476
488
|
- **20+ benchmark problems**: Linear, nonlinear, and regression-mode PDEs
|
|
477
489
|
|
|
490
|
+
## Development
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
pip install -e ".[dev]"
|
|
494
|
+
pytest tests/
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
The suite is 251 tests and runs in about 30 seconds on a laptop CPU. Every closed
|
|
498
|
+
form -- derivative, integral, Fourier symbol, projection -- is checked against an
|
|
499
|
+
independent reference (autograd, Gauss-Legendre quadrature, or the analytic value) in
|
|
500
|
+
`tests/test_closed_forms_property.py`, so a wrong closed form fails the suite rather
|
|
501
|
+
than silently returning a plausible number.
|
|
502
|
+
|
|
503
|
+
[Continuous integration](https://github.com/sulcantonin/FastLSQ/actions/workflows/tests.yml)
|
|
504
|
+
runs the suite on Python 3.9, 3.10, 3.11 and 3.12, and separately builds the sdist and
|
|
505
|
+
wheel and checks their metadata.
|
|
506
|
+
|
|
507
|
+
## Releases and versioning
|
|
508
|
+
|
|
509
|
+
Released versions are on [PyPI](https://pypi.org/project/FastLSQ/) and tagged in this
|
|
510
|
+
repository as `vMAJOR.MINOR.PATCH`. `CHANGELOG.md` documents every release.
|
|
511
|
+
|
|
512
|
+
The tags for 0.1.0 through 0.6.0 were reconstructed after the fact, since the project
|
|
513
|
+
was published to PyPI for its first year without tagging. Each tag was matched to its
|
|
514
|
+
commit by comparing the commit's `fastlsq/*.py` sources against the sdist actually
|
|
515
|
+
published, so most are byte-for-byte exact; the three that are not say so in the tag
|
|
516
|
+
message. See the *Release tags* note at the top of `CHANGELOG.md`.
|
|
517
|
+
|
|
478
518
|
## Paper
|
|
479
519
|
|
|
480
|
-
The
|
|
520
|
+
The preprint is on [arXiv](https://arxiv.org/abs/2602.10541). A software paper for the
|
|
521
|
+
[Journal of Open Source Software](https://joss.theoj.org/) is drafted in
|
|
522
|
+
[`paper.md`](paper.md).
|
|
523
|
+
|
|
524
|
+
There is also a [BerkeleyLab ATAP talk](https://github.com/sulcantonin/FastLSQ/raw/main/presentations/ATAP_Sulc_20260324.pptx)
|
|
525
|
+
covering the method and the accelerator-physics applications.
|
|
481
526
|
|
|
482
527
|
## Citing this work
|
|
483
528
|
|
|
484
529
|
If you use FastLSQ in your research, please cite:
|
|
485
530
|
|
|
486
531
|
```bibtex
|
|
487
|
-
@misc{
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
532
|
+
@misc{sulc2026fastlsq,
|
|
533
|
+
author = {Sulc, Antonin},
|
|
534
|
+
title = {{FastLSQ}: Solving {PDEs} in One Shot via {Fourier} Features with Exact Analytical Derivatives},
|
|
535
|
+
year = {2026},
|
|
536
|
+
eprint = {2602.10541},
|
|
537
|
+
archivePrefix = {arXiv},
|
|
538
|
+
primaryClass = {math.NA},
|
|
539
|
+
doi = {10.48550/arXiv.2602.10541},
|
|
540
|
+
url = {https://arxiv.org/abs/2602.10541}
|
|
495
541
|
}
|
|
496
542
|
```
|
|
497
543
|
|
|
@@ -193,10 +193,14 @@ def solve_linear(
|
|
|
193
193
|
"scale_search_s": scale_search_s,
|
|
194
194
|
"assemble_s": assemble_s,
|
|
195
195
|
"solve_s": solve_s,
|
|
196
|
-
#
|
|
196
|
+
# Conditioning diagnostics of the assembled system. "rank_used" is the
|
|
197
|
+
# number of singular values above rcond * sigma_max -- a property of A, NOT
|
|
198
|
+
# the rank the back-end worked with (QR and Cholesky use every column).
|
|
199
|
+
# "method_used" says which back-end actually ran.
|
|
197
200
|
"rank_used": solve_info["rank_used"],
|
|
198
201
|
"residual": solve_info["residual"],
|
|
199
202
|
"cond_estimate": solve_info["cond_estimate"],
|
|
203
|
+
"method_used": solve_info.get("method_used"),
|
|
200
204
|
}
|
|
201
205
|
if verbose:
|
|
202
206
|
print(f"Value error: {val_err:.2e}, Gradient error: {grad_err:.2e}")
|