FastLSQ 0.1.5__tar.gz → 0.2.2__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.
Files changed (144) hide show
  1. fastlsq-0.2.2/CHANGELOG.md +249 -0
  2. {fastlsq-0.1.5 → fastlsq-0.2.2/FastLSQ.egg-info}/PKG-INFO +11 -10
  3. fastlsq-0.2.2/FastLSQ.egg-info/SOURCES.txt +106 -0
  4. {fastlsq-0.1.5 → fastlsq-0.2.2}/MANIFEST.in +0 -1
  5. {fastlsq-0.1.5/FastLSQ.egg-info → fastlsq-0.2.2}/PKG-INFO +11 -10
  6. {fastlsq-0.1.5 → fastlsq-0.2.2}/README.md +3 -3
  7. fastlsq-0.2.2/examples/extras/fred_sde.py +262 -0
  8. fastlsq-0.2.2/examples/extras/fred_sde_fastlsq.py +329 -0
  9. fastlsq-0.2.2/examples/extras/gaia_potential.py +183 -0
  10. fastlsq-0.2.2/examples/extras/gaia_potential_fastlsq.py +397 -0
  11. fastlsq-0.2.2/examples/extras/horizons_ephemeris.py +319 -0
  12. fastlsq-0.2.2/examples/extras/numerai_alpha.py +214 -0
  13. fastlsq-0.2.2/examples/extras/numerai_alpha_fastlsq.py +374 -0
  14. fastlsq-0.2.2/examples/extras/run_all_fastlsq.py +107 -0
  15. fastlsq-0.2.2/examples/extras/scenarios/__init__.py +0 -0
  16. fastlsq-0.2.2/examples/extras/scenarios/_alsu_lattice.py +196 -0
  17. fastlsq-0.2.2/examples/extras/scenarios/_common.py +164 -0
  18. fastlsq-0.2.2/examples/extras/scenarios/run_all.py +70 -0
  19. fastlsq-0.2.2/examples/extras/scenarios/s01_beamloss_ode.py +340 -0
  20. fastlsq-0.2.2/examples/extras/scenarios/s01_betatron_tune.py +448 -0
  21. fastlsq-0.2.2/examples/extras/scenarios/s01_green_fff.py +262 -0
  22. fastlsq-0.2.2/examples/extras/scenarios/s01_hill_ivp.py +263 -0
  23. fastlsq-0.2.2/examples/extras/scenarios/s01_observe_fit_act_simulator.py +353 -0
  24. fastlsq-0.2.2/examples/extras/scenarios/s01_orbit_inverse.py +332 -0
  25. fastlsq-0.2.2/examples/extras/scenarios/s01_passive_loco.py +246 -0
  26. fastlsq-0.2.2/examples/extras/scenarios/s01_perturbed_hill.py +247 -0
  27. fastlsq-0.2.2/examples/extras/scenarios/s01_sofb_observe_fit_act.py +619 -0
  28. fastlsq-0.2.2/examples/extras/scenarios/s01_streaming_archive_growth.py +310 -0
  29. fastlsq-0.2.2/examples/extras/scenarios/s01_synchrotron_ode.py +335 -0
  30. fastlsq-0.2.2/examples/extras/scenarios/s01_tides_3months.py +257 -0
  31. fastlsq-0.2.2/examples/extras/scenarios/s01_topoff_impulse.py +375 -0
  32. fastlsq-0.2.2/examples/extras/scenarios/s01_visualize.py +400 -0
  33. fastlsq-0.2.2/examples/extras/scenarios/s02_plasma_wakefield.py +99 -0
  34. fastlsq-0.2.2/examples/extras/scenarios/s03_synchrobetatron.py +75 -0
  35. fastlsq-0.2.2/examples/extras/scenarios/s04_sunspots.py +116 -0
  36. fastlsq-0.2.2/examples/extras/scenarios/s05_helioseismology.py +105 -0
  37. fastlsq-0.2.2/examples/extras/scenarios/s06_tides.py +122 -0
  38. fastlsq-0.2.2/examples/extras/scenarios/s07_iers_earth_rotation.py +97 -0
  39. fastlsq-0.2.2/examples/extras/scenarios/s08_mauna_loa_co2.py +96 -0
  40. fastlsq-0.2.2/examples/extras/scenarios/s09_enso_qbo.py +131 -0
  41. fastlsq-0.2.2/examples/extras/scenarios/s10_pulsar_timing.py +99 -0
  42. fastlsq-0.2.2/examples/extras/scenarios/s11_modal_analysis.py +109 -0
  43. fastlsq-0.2.2/examples/extras/scenarios/s12_mems_resonator.py +150 -0
  44. fastlsq-0.2.2/examples/extras/scenarios/s13_variable_stars_kepler.py +111 -0
  45. fastlsq-0.2.2/examples/extras/scenarios/s14_eeg.py +94 -0
  46. fastlsq-0.2.2/examples/extras/scenarios/s15_circadian.py +130 -0
  47. fastlsq-0.2.2/examples/extras/spectral_expansion.py +96 -0
  48. fastlsq-0.2.2/examples/grad_shafranov.py +186 -0
  49. fastlsq-0.2.2/examples/grid_inverse.py +74 -0
  50. fastlsq-0.2.2/examples/grid_rl_control.py +128 -0
  51. fastlsq-0.2.2/examples/grid_swing.py +130 -0
  52. fastlsq-0.2.2/examples/gs_inverse.py +127 -0
  53. fastlsq-0.2.2/examples/gs_rl_control.py +182 -0
  54. fastlsq-0.2.2/examples/orbit_hill.py +212 -0
  55. fastlsq-0.2.2/examples/orbit_inverse.py +98 -0
  56. fastlsq-0.2.2/examples/orbit_rl.py +154 -0
  57. fastlsq-0.2.2/examples/vector_basis_stream_vorticity.py +146 -0
  58. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/__init__.py +12 -1
  59. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/api.py +17 -10
  60. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/basis.py +51 -9
  61. fastlsq-0.2.2/fastlsq/device.py +130 -0
  62. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/export.py +4 -1
  63. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/geometry.py +16 -16
  64. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/learnable.py +117 -69
  65. fastlsq-0.2.2/fastlsq/linalg.py +137 -0
  66. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/newton.py +10 -4
  67. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/problems/__init__.py +6 -4
  68. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/problems/linear.py +29 -55
  69. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/problems/nonlinear.py +20 -20
  70. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/problems/regression.py +38 -38
  71. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/solvers.py +7 -7
  72. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/tuning.py +12 -5
  73. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/utils.py +8 -2
  74. fastlsq-0.2.2/fastlsq/vector.py +412 -0
  75. fastlsq-0.2.2/fastlsq/viz.py +456 -0
  76. {fastlsq-0.1.5 → fastlsq-0.2.2}/pyproject.toml +8 -7
  77. fastlsq-0.2.2/tests/test_block.py +68 -0
  78. fastlsq-0.2.2/tests/test_derivatives.py +209 -0
  79. fastlsq-0.2.2/tests/test_device.py +43 -0
  80. fastlsq-0.2.2/tests/test_grad_shafranov.py +41 -0
  81. fastlsq-0.2.2/tests/test_grid_swing.py +40 -0
  82. fastlsq-0.2.2/tests/test_learnable.py +98 -0
  83. fastlsq-0.2.2/tests/test_orbit_hill.py +42 -0
  84. fastlsq-0.2.2/tests/test_vector_basis.py +220 -0
  85. fastlsq-0.1.5/CHANGELOG.md +0 -141
  86. fastlsq-0.1.5/FastLSQ.egg-info/SOURCES.txt +0 -77
  87. fastlsq-0.1.5/examples/digital_twins/darcy_heat.py +0 -583
  88. fastlsq-0.1.5/examples/digital_twins/pendulum.py +0 -242
  89. fastlsq-0.1.5/examples/digital_twins/pendulum_benchmark.py +0 -281
  90. fastlsq-0.1.5/examples/digital_twins/plasma_wakefield.py +0 -339
  91. fastlsq-0.1.5/examples/digital_twins/plasma_wakefield_2D_1.py +0 -863
  92. fastlsq-0.1.5/examples/digital_twins/plasma_wakefield_2D_2.py +0 -769
  93. fastlsq-0.1.5/examples/digital_twins/plasma_wakefield_2d_3.py +0 -818
  94. fastlsq-0.1.5/examples/digital_twins/plasma_wakefield_parameteric.py +0 -475
  95. fastlsq-0.1.5/examples/digital_twins/plot_utils.py +0 -42
  96. fastlsq-0.1.5/examples/digital_twins/structural_health_simple.py +0 -343
  97. fastlsq-0.1.5/examples/digital_twins/turbulence_gravity_cooling.py +0 -387
  98. fastlsq-0.1.5/examples/inverse/aero_.py +0 -362
  99. fastlsq-0.1.5/examples/inverse/denoising_parameter_estimation.py +0 -297
  100. fastlsq-0.1.5/examples/inverse/elastic_wave_animation.py +0 -300
  101. fastlsq-0.1.5/examples/inverse/heat_from_video.py +0 -394
  102. fastlsq-0.1.5/examples/inverse/inverse_turbulence.py +0 -811
  103. fastlsq-0.1.5/examples/inverse/shape_ns.py +0 -1426
  104. fastlsq-0.1.5/examples/inverse/subsurface_imaging.py +0 -547
  105. fastlsq-0.1.5/examples/inverse/wing_optimize_simple.py +0 -283
  106. fastlsq-0.1.5/examples/sindy/compare_sindy_methods.py +0 -760
  107. fastlsq-0.1.5/examples/sindy/sindy_benchmarks.py +0 -351
  108. fastlsq-0.1.5/examples/sindy/sindy_differentiable.py +0 -418
  109. fastlsq-0.1.5/examples/sindy/sindy_minimal_diff.py +0 -716
  110. fastlsq-0.1.5/fastlsq/linalg.py +0 -34
  111. fastlsq-0.1.5/misc/fastlsq_teaser.png +0 -0
  112. fastlsq-0.1.5/misc/ideal_quadrupole.png +0 -0
  113. fastlsq-0.1.5/misc/inverse_heat_source.gif +0 -0
  114. fastlsq-0.1.5/misc/inverse_heat_source.png +0 -0
  115. fastlsq-0.1.5/misc/inverse_magnetostatics.png +0 -0
  116. fastlsq-0.1.5/misc/inverse_magnetostatics_convergence.png +0 -0
  117. fastlsq-0.1.5/misc/quadrupole_convergence.png +0 -0
  118. fastlsq-0.1.5/misc/quadrupole_optimization.png +0 -0
  119. fastlsq-0.1.5/misc/tutorial_nlpoisson_convergence.png +0 -0
  120. fastlsq-0.1.5/misc/tutorial_nlpoisson_solution.png +0 -0
  121. {fastlsq-0.1.5 → fastlsq-0.2.2}/FastLSQ.egg-info/dependency_links.txt +0 -0
  122. {fastlsq-0.1.5 → fastlsq-0.2.2}/FastLSQ.egg-info/requires.txt +0 -0
  123. {fastlsq-0.1.5 → fastlsq-0.2.2}/FastLSQ.egg-info/top_level.txt +0 -0
  124. {fastlsq-0.1.5 → fastlsq-0.2.2}/LICENSE +0 -0
  125. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/add_your_own_pde.py +0 -0
  126. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/benchmark_comparison.py +0 -0
  127. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/custom_features.py +0 -0
  128. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/inverse_heat_source.py +0 -0
  129. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/inverse_magnetostatics.py +0 -0
  130. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/inverse_source_position.py +0 -0
  131. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/learnable_helmholtz.py +0 -0
  132. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/pde_discovery.py +0 -0
  133. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/run_all_extensions.py +0 -0
  134. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/run_linear.py +0 -0
  135. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/run_nonlinear.py +0 -0
  136. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/tutorial_basic.py +0 -0
  137. {fastlsq-0.1.5 → fastlsq-0.2.2}/examples/tutorial_nonlinear.py +0 -0
  138. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/block.py +0 -0
  139. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/diagnostics.py +0 -0
  140. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/lightning.py +0 -0
  141. {fastlsq-0.1.5 → fastlsq-0.2.2}/fastlsq/plotting.py +0 -0
  142. {fastlsq-0.1.5 → fastlsq-0.2.2}/requirements.txt +0 -0
  143. {fastlsq-0.1.5 → fastlsq-0.2.2}/setup.cfg +0 -0
  144. {fastlsq-0.1.5 → fastlsq-0.2.2}/tests/test_basic.py +0 -0
@@ -0,0 +1,249 @@
1
+ # Changelog
2
+
3
+ All notable changes to FastLSQ will be documented in this file.
4
+
5
+ ## [0.2.2] - 2026-06-03
6
+
7
+ ### Fixed
8
+
9
+ - **Learnable bandwidth now trains.** `LearnableFastLSQ.solve_inner` replaced the
10
+ backprop-through-`torch.linalg.svd` inner solve (which returned NaN gradients
11
+ w.r.t. the bandwidth on the clustered singular values of random-feature
12
+ matrices) with the SVD-based `gelsd` rank-revealing least-squares driver, so
13
+ `train_bandwidth` / `fit` no longer stall at step 0.
14
+ - **Default-solve accuracy.** Tightened the `_auto_solve` Cholesky-acceptance
15
+ probe from `rcond**0.5` to `rcond**0.25`, so `method="auto"` falls back to SVD
16
+ before the normal-equations Cholesky loses half its float64 digits
17
+ (cond(A) ~ 1e7 previously returned a ~1e-3-accurate answer).
18
+ - **Newton convergence and robustness.** The stop test now combines a *relative*
19
+ residual criterion (`res_norm < tol_res * R0`) with the relative solution
20
+ change (`||Δu||/||u|| < tol_du`); the previous unreachable absolute residual
21
+ tolerance forced every nonlinear solve to run the full `max_iter`. The
22
+ backtracking line search keeps the previous iterate when no step satisfies
23
+ Armijo instead of committing a worse point. `solve_nonlinear` default
24
+ tolerances loosened to `tol_res=1e-8`, `tol_du=1e-10`.
25
+ - **Continuation guard.** `solve_nonlinear` no longer raises `TypeError` when a
26
+ problem sets `use_continuation=True` without a `nu_target`.
27
+ - **Regression problems solvable via the public API.** Their `get_train_data`
28
+ now accepts the `n_pde`/`n_bc` signature used by `solve_linear`,
29
+ `auto_select_scale`, and `check_problem` (was `n_samples`, raising
30
+ `TypeError`); `auto_select_scale` now raises when every trial fails instead of
31
+ silently returning the first scale.
32
+ - **Float32 inputs.** `SinusoidalBasis.cache` promotes inputs to the basis
33
+ dtype/device, so float32 collocation points no longer raise `float != double`.
34
+ - **Checkpoint reload.** `load_checkpoint` passes `weights_only=False`, fixing
35
+ `UnpicklingError` on torch >= 2.6 (checkpoints store NumPy arrays).
36
+ - **Vector per-component scale.** `VectorFastLSQSolver.add_block` accepts a NumPy
37
+ array of per-component bandwidths (previously list/tuple only, silently
38
+ misread as per-dimension).
39
+ - **ElasticWave2D operator.** Scaled the spatial and cross terms by `t_max²`
40
+ (time normalisation), consistent with `Wave2D_MS`.
41
+
42
+ ### Changed
43
+
44
+ - Problem modules (`nonlinear.py`, `regression.py`) resolve the device via the
45
+ live `get_device()` rather than an import-time snapshot.
46
+ - Packaging: the source distribution no longer ships the `misc/` images (the
47
+ sdist was ~14 MB); project URLs point to `github.com/sulcantonin/FastLSQ`;
48
+ README images use absolute URLs so they render on PyPI.
49
+ `examples/orbit_hill.py` solves via rank-revealing `lstsq` rather than a
50
+ normal-equations Cholesky.
51
+
52
+ ## [0.2.1] - 2026-06-02
53
+
54
+ ### Added
55
+
56
+ - **Device abstraction** (`fastlsq/device.py`): `resolve_device`, `set_device`,
57
+ `get_device`, `device_info` for CPU / CUDA / Apple-MPS. dtype-aware -- MPS is
58
+ auto-selected only for float32 (it has no float64), so the default float64
59
+ high-accuracy regime stays on CPU/CUDA. Override with `set_device(...)` or the
60
+ `FASTLSQ_DEVICE` environment variable; internal tensor creation respects the
61
+ active device at call time.
62
+ - **Pluggable linear solver** `solve_lstsq(..., method=...)`:
63
+ - `"svd"` -- rank-revealing truncated SVD (LAPACK `gelsd` fast path on CPU);
64
+ - `"cholesky"` -- fast normal-equations solve for well-conditioned systems;
65
+ - `"rsvd"` -- torch-native randomized SVD (`O(MNk)`) for strongly low-rank `A`;
66
+ - `"auto"` (default) -- Cholesky with a cheap conditioning probe, falling back
67
+ to SVD when ill-conditioned (recovers the fast path without losing accuracy).
68
+ MPS factorizations run on CPU (no robust `svd`/`lstsq` there) and move back.
69
+ - **Working anisotropic Sigma = L Lᵀ learner**: `LearnableFastLSQ` (diagonal &
70
+ cholesky modes) now converges -- `solve_inner` uses a differentiable
71
+ *rank-revealing* solve, the Cholesky factor is log-parameterized (clamped,
72
+ positive-definite), and `train_bandwidth` is robust (gradient clipping,
73
+ best-iterate restore, graceful SVD/gradient-failure handling). Chainable
74
+ `LearnableFastLSQ.fit(problem, ...)` for one-line learn-then-predict.
75
+ - **Vector-valued solutions (`u: ℝᵈ → ℝᵏ`)**: first-class support for coupled and
76
+ decoupled multi-output PDEs via the new `fastlsq.block` module. Problems opt in
77
+ with `self.n_outputs = k`; `solver.beta` is `(N, k)` and `solver.predict(x)`
78
+ returns `(M, k)` (scalar `k=1` is bit-for-bit unchanged). `block_concat`
79
+ assembles a nested list of blocks (`None` = zero block); `pack_beta` /
80
+ `unpack_beta` convert between `(N, k)` and the block-stacked `(N*k, 1)` solve.
81
+ The block-stacked LSQ is solved by the rank-revealing solver, and the
82
+ Σ-learner computes its loss on the flat `_beta_flat` so it stays correct for
83
+ `k>1`.
84
+ - **Learnable operator coefficients**: `Op` accepts `nn.Parameter` (and tensors)
85
+ as coefficients, e.g. `Op.laplacian(d=2) + k**2 * Op.identity(d=2)` with
86
+ `k = nn.Parameter(...)`; gradients flow through the prebuilt linear solve.
87
+
88
+ ### Changed
89
+
90
+ - `solve_lstsq` defaults to the rank-revealing / `auto` solve instead of forming
91
+ the normal equations -- several orders of magnitude more accurate on the
92
+ rank-deficient random-feature systems (at a higher, still one-shot, cost).
93
+ - `solve_linear` is one-shot: the bandwidth-learning hyper-parameters live on
94
+ `LearnableFastLSQ.fit()` / `train_bandwidth`, not the solve signature.
95
+ - Packaging: `requires-python` lowered to `>=3.9` (+3.9 classifier); description
96
+ updated.
97
+
98
+ ### Fixed
99
+
100
+ - The previously dead `LearnableFastLSQ(mode="cholesky")` path, which diverged
101
+ from an unstable inner `torch.linalg.lstsq` and an unconstrained `L`.
102
+
103
+ ## [0.1.5] - 2026-05-25
104
+
105
+ ### Added
106
+
107
+ - **Vector-valued features**: new `VectorBasis` and `VectorFastLSQSolver`
108
+ (`fastlsq/vector.py`) for solving coupled systems where the unknown is a
109
+ vector field `u(x) = (u_1, ..., u_K)`. Use cases include
110
+ streamfunction-vorticity NS `(psi, omega)`, incompressible NS primitive
111
+ variables `(u, v, p)`, multi-species transport, MHD, etc.
112
+
113
+ - `VectorBasis.random(input_dim, n_features, sigma, n_components, sigmas=...)`
114
+ creates K independent random-Fourier `SinusoidalBasis`es; per-component
115
+ bandwidth can be tuned via `sigmas`.
116
+ - Stacked evaluators: `evaluate(x) -> (M, K, N)`, `gradient -> (M, K, d, N)`,
117
+ `laplacian`, `hessian_diag`, `derivative(alpha)`.
118
+ - Block-diagonal assembly helpers (`block_diag_evaluate`,
119
+ `block_diag_laplacian`, `block_diag_derivative`) for systems whose
120
+ rows are independent per component.
121
+ - Coefficient packing utilities (`stack_betas`, `unstack_beta`,
122
+ `predict`) accept per-component lists, stacked columns, or
123
+ `(N, K)` matrices interchangeably.
124
+ - `VectorFastLSQSolver(input_dim, n_components, normalize=True)` is the
125
+ multi-component counterpart of `FastLSQSolver`; `add_block(scale=...)`
126
+ accepts either a scalar or a list of K scalars for per-component
127
+ bandwidth.
128
+ - `component(k)` / `component_solver(k)` give direct access to the k-th
129
+ scalar basis / solver for ad-hoc per-component work.
130
+
131
+ ### Other
132
+
133
+ - Synchronised `pyproject.toml`, `fastlsq.__version__`, and CHANGELOG (the
134
+ package source had drifted to `__version__ = "0.1.0"` against
135
+ `pyproject.toml = "0.1.4"`; both now read `"0.1.5"`).
136
+
137
+ ## [0.2.0] - 2026-03-01
138
+
139
+ ### Added
140
+
141
+ #### SinusoidalBasis -- analytical derivative engine (new foundation)
142
+ - `SinusoidalBasis` class: evaluates arbitrary-order mixed partial derivatives
143
+ of sinusoidal features in O(1) via the cyclic derivative identity
144
+ - `BasisCache`: pre-computes sin(Z)/cos(Z) once, reuses across all derivative
145
+ evaluations at the same points
146
+ - `DiffOperator` / `Op`: symbolic linear differential operators that compose
147
+ via `+`, `-`, scalar `*`. Factory methods: `Op.laplacian()`,
148
+ `Op.partial()`, `Op.identity()`, `Op.biharmonic()`, `Op.gradient_component()`
149
+ - `FeatureBasis`: adapter wrapping non-sinusoidal solvers (e.g. PIELMSolver
150
+ with tanh) into the same basis interface
151
+
152
+ #### Learnable bandwidth
153
+ - `LearnableFastLSQ`: PyTorch `nn.Module` with learnable bandwidth via
154
+ reparameterisation trick (scalar, diagonal, or full Cholesky modes)
155
+ - `train_bandwidth()`: hybrid training loop (inner exact solve + outer AdamW
156
+ on bandwidth parameters)
157
+
158
+ #### PDE discovery example
159
+ - `examples/pde_discovery.py`: sparse regression (SINDy-style) using
160
+ analytical derivatives from `SinusoidalBasis` as the dictionary
161
+
162
+ ### Changed
163
+
164
+ #### Architecture: basis-centric API (breaking)
165
+ - **`solver.basis`** is now the single entry point for all feature and
166
+ derivative computations. Every solver exposes a `.basis` property
167
+ (`SinusoidalBasis` for FastLSQ, `FeatureBasis` for PIELM).
168
+ - All problem classes (`linear.py`, `nonlinear.py`, `regression.py`) rewritten
169
+ to use `solver.basis.evaluate()`, `.gradient()`, `.hessian_diag()`,
170
+ `.laplacian()`, and `.cache()` instead of tuple unpacking.
171
+ - `FastLSQSolver.predict()`, `.predict_with_grad()`, `.predict_with_laplacian()`
172
+ delegate directly to `self.basis`.
173
+ - `PIELMSolver` now exposes `.basis` (via `FeatureBasis` adapter) so problem
174
+ classes work identically for both solver types.
175
+ - `newton.py`: uses `solver.basis.evaluate()` for convergence metrics.
176
+
177
+ #### Examples rewritten
178
+ - `add_your_own_pde.py`: shows `Op`-based PDE definition only
179
+ - `custom_features.py`: shows cosine features via phase shift only
180
+
181
+ ### Removed
182
+ - `get_features()` method removed from public API (all solvers, all problems)
183
+ - `SinusoidalBasis.get_features()` legacy tuple interface removed
184
+ - `CustomFeatureSolver` subclass pattern removed
185
+ - Legacy `build()` patterns using `(H, dH, ddH)` tuple unpacking
186
+
187
+ ### Fixed
188
+ - Missing `sample_ball` import in `tests/test_basic.py`
189
+
190
+
191
+ ## [0.1.0] - 2026-02-12
192
+
193
+ ### Added
194
+
195
+ #### High-level API
196
+ - `solve_linear()` - One-line function to solve linear PDEs
197
+ - `solve_nonlinear()` - One-line function to solve nonlinear PDEs via Newton-Raphson
198
+ - Automatic scale selection via `auto_select_scale()`
199
+
200
+ #### Plotting & Visualization
201
+ - `plot_solution_1d()` - Plot 1D solutions with exact comparison
202
+ - `plot_solution_2d_slice()` - Plot 2D solutions as 1D slices
203
+ - `plot_solution_2d_contour()` - Contour plots for 2D solutions
204
+ - `plot_convergence()` - Newton iteration convergence plots
205
+ - `plot_spectral_sensitivity()` - Error vs scale analysis
206
+
207
+ #### Geometry & Sampling
208
+ - `sample_box()` - Uniform sampling from hypercubes
209
+ - `sample_ball()` - Uniform sampling from balls
210
+ - `sample_sphere()` - Uniform sampling from sphere surfaces
211
+ - `sample_interval()` - 1D interval sampling
212
+ - `sample_boundary_box()` - Boundary point generation for boxes
213
+ - `get_sampler()` - Get sampler by name
214
+
215
+ #### Diagnostics & Error Handling
216
+ - `check_problem()` - Validate problem definitions (shapes, gradients, data)
217
+ - `check_solver_conditioning()` - Check linear system conditioning
218
+ - `suggest_scale()` - Heuristic scale suggestions
219
+
220
+ #### Export & Interoperability
221
+ - `to_numpy()` - Convert predictions to NumPy arrays
222
+ - `to_dict()` / `from_dict()` - Serialize/deserialize solver state
223
+ - `save_checkpoint()` / `load_checkpoint()` - Save/load solver checkpoints
224
+ - `FastLSQModule` - PyTorch Lightning integration (optional)
225
+
226
+ #### Documentation & Examples
227
+ - `examples/tutorial_basic.py` - Basic linear PDE tutorial
228
+ - `examples/tutorial_nonlinear.py` - Nonlinear PDE tutorial
229
+ - `examples/add_your_own_pde.py` - Guide for adding custom PDEs
230
+ - `examples/custom_features.py` - Extensibility example
231
+ - Comprehensive README with usage examples
232
+
233
+ #### Infrastructure
234
+ - `benchmarks/run_all.py` - Reproducible benchmark suite
235
+ - `tests/test_basic.py` - Basic test suite
236
+ - `.github/workflows/ci.yml` - GitHub Actions CI/CD
237
+ - `CHANGELOG.md` - This file
238
+
239
+ ### Changed
240
+
241
+ - Restructured codebase from 2 monolithic files into a proper Python package
242
+ - Unified `FastLSQSolver` with optional normalization parameter
243
+ - Removed code duplication (Bratu, NL-Helmholtz regression inherit from nonlinear versions)
244
+ - Removed non-scientific content (emojis, casual language)
245
+
246
+ ### Fixed
247
+
248
+ - Fixed missing `solve_lstsq` import in linear solver (was only defined in nonlinear file)
249
+ - Improved error messages and diagnostics
@@ -1,25 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FastLSQ
3
- Version: 0.1.5
4
- Summary: Solving PDEs in one shot via Fourier features with exact analytical derivatives
3
+ Version: 0.2.2
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
7
- Project-URL: Homepage, https://github.com/asulc/FastLSQ
8
- Project-URL: Repository, https://github.com/asulc/FastLSQ
7
+ Project-URL: Homepage, https://github.com/sulcantonin/FastLSQ
8
+ Project-URL: Repository, https://github.com/sulcantonin/FastLSQ
9
9
  Project-URL: Paper, https://arxiv.org/abs/2602.10541
10
- Project-URL: Bug Tracker, https://github.com/asulc/FastLSQ/issues
11
- Project-URL: Changelog, https://github.com/asulc/FastLSQ/blob/main/CHANGELOG.md
10
+ Project-URL: Bug Tracker, https://github.com/sulcantonin/FastLSQ/issues
11
+ Project-URL: Changelog, https://github.com/sulcantonin/FastLSQ/blob/main/CHANGELOG.md
12
12
  Keywords: pde,partial-differential-equations,fourier-features,least-squares,scientific-computing,neural-network,physics-informed,newton-raphson
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
17
18
  Classifier: Programming Language :: Python :: 3.10
18
19
  Classifier: Programming Language :: Python :: 3.11
19
20
  Classifier: Programming Language :: Python :: 3.12
20
21
  Classifier: Topic :: Scientific/Engineering :: Mathematics
21
22
  Classifier: Topic :: Scientific/Engineering :: Physics
22
- Requires-Python: >=3.10
23
+ Requires-Python: >=3.9
23
24
  Description-Content-Type: text/markdown
24
25
  License-File: LICENSE
25
26
  Requires-Dist: torch>=2.0
@@ -44,7 +45,7 @@ Dynamic: license-file
44
45
 
45
46
 
46
47
  <p align="center">
47
- <img src="misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
48
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
48
49
  </p>
49
50
 
50
51
  **Solving PDEs in one shot via Fourier features with exact analytical derivatives.**
@@ -234,8 +235,8 @@ python examples/learnable_helmholtz.py
234
235
  The analytical derivatives enable gradients through the pre-factored solve, making inverse problems tractable. Example: recovering 4 anisotropic Gaussian heat sources (24 parameters) from 4 sparse sensors. The heat equation is solved in space-time; L-BFGS-B optimises source positions and shapes to match sensor time-series. *(Click image for animation.)*
235
236
 
236
237
  <p align="center">
237
- <a href="misc/inverse_heat_source.gif">
238
- <img src="misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
238
+ <a href="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.gif">
239
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
239
240
  </a>
240
241
  </p>
241
242
 
@@ -0,0 +1,106 @@
1
+ CHANGELOG.md
2
+ LICENSE
3
+ MANIFEST.in
4
+ README.md
5
+ pyproject.toml
6
+ requirements.txt
7
+ FastLSQ.egg-info/PKG-INFO
8
+ FastLSQ.egg-info/SOURCES.txt
9
+ FastLSQ.egg-info/dependency_links.txt
10
+ FastLSQ.egg-info/requires.txt
11
+ FastLSQ.egg-info/top_level.txt
12
+ examples/add_your_own_pde.py
13
+ examples/benchmark_comparison.py
14
+ examples/custom_features.py
15
+ examples/grad_shafranov.py
16
+ examples/grid_inverse.py
17
+ examples/grid_rl_control.py
18
+ examples/grid_swing.py
19
+ examples/gs_inverse.py
20
+ examples/gs_rl_control.py
21
+ examples/inverse_heat_source.py
22
+ examples/inverse_magnetostatics.py
23
+ examples/inverse_source_position.py
24
+ examples/learnable_helmholtz.py
25
+ examples/orbit_hill.py
26
+ examples/orbit_inverse.py
27
+ examples/orbit_rl.py
28
+ examples/pde_discovery.py
29
+ examples/run_all_extensions.py
30
+ examples/run_linear.py
31
+ examples/run_nonlinear.py
32
+ examples/tutorial_basic.py
33
+ examples/tutorial_nonlinear.py
34
+ examples/vector_basis_stream_vorticity.py
35
+ examples/extras/fred_sde.py
36
+ examples/extras/fred_sde_fastlsq.py
37
+ examples/extras/gaia_potential.py
38
+ examples/extras/gaia_potential_fastlsq.py
39
+ examples/extras/horizons_ephemeris.py
40
+ examples/extras/numerai_alpha.py
41
+ examples/extras/numerai_alpha_fastlsq.py
42
+ examples/extras/run_all_fastlsq.py
43
+ examples/extras/spectral_expansion.py
44
+ examples/extras/scenarios/__init__.py
45
+ examples/extras/scenarios/_alsu_lattice.py
46
+ examples/extras/scenarios/_common.py
47
+ examples/extras/scenarios/run_all.py
48
+ examples/extras/scenarios/s01_beamloss_ode.py
49
+ examples/extras/scenarios/s01_betatron_tune.py
50
+ examples/extras/scenarios/s01_green_fff.py
51
+ examples/extras/scenarios/s01_hill_ivp.py
52
+ examples/extras/scenarios/s01_observe_fit_act_simulator.py
53
+ examples/extras/scenarios/s01_orbit_inverse.py
54
+ examples/extras/scenarios/s01_passive_loco.py
55
+ examples/extras/scenarios/s01_perturbed_hill.py
56
+ examples/extras/scenarios/s01_sofb_observe_fit_act.py
57
+ examples/extras/scenarios/s01_streaming_archive_growth.py
58
+ examples/extras/scenarios/s01_synchrotron_ode.py
59
+ examples/extras/scenarios/s01_tides_3months.py
60
+ examples/extras/scenarios/s01_topoff_impulse.py
61
+ examples/extras/scenarios/s01_visualize.py
62
+ examples/extras/scenarios/s02_plasma_wakefield.py
63
+ examples/extras/scenarios/s03_synchrobetatron.py
64
+ examples/extras/scenarios/s04_sunspots.py
65
+ examples/extras/scenarios/s05_helioseismology.py
66
+ examples/extras/scenarios/s06_tides.py
67
+ examples/extras/scenarios/s07_iers_earth_rotation.py
68
+ examples/extras/scenarios/s08_mauna_loa_co2.py
69
+ examples/extras/scenarios/s09_enso_qbo.py
70
+ examples/extras/scenarios/s10_pulsar_timing.py
71
+ examples/extras/scenarios/s11_modal_analysis.py
72
+ examples/extras/scenarios/s12_mems_resonator.py
73
+ examples/extras/scenarios/s13_variable_stars_kepler.py
74
+ examples/extras/scenarios/s14_eeg.py
75
+ examples/extras/scenarios/s15_circadian.py
76
+ fastlsq/__init__.py
77
+ fastlsq/api.py
78
+ fastlsq/basis.py
79
+ fastlsq/block.py
80
+ fastlsq/device.py
81
+ fastlsq/diagnostics.py
82
+ fastlsq/export.py
83
+ fastlsq/geometry.py
84
+ fastlsq/learnable.py
85
+ fastlsq/lightning.py
86
+ fastlsq/linalg.py
87
+ fastlsq/newton.py
88
+ fastlsq/plotting.py
89
+ fastlsq/solvers.py
90
+ fastlsq/tuning.py
91
+ fastlsq/utils.py
92
+ fastlsq/vector.py
93
+ fastlsq/viz.py
94
+ fastlsq/problems/__init__.py
95
+ fastlsq/problems/linear.py
96
+ fastlsq/problems/nonlinear.py
97
+ fastlsq/problems/regression.py
98
+ tests/test_basic.py
99
+ tests/test_block.py
100
+ tests/test_derivatives.py
101
+ tests/test_device.py
102
+ tests/test_grad_shafranov.py
103
+ tests/test_grid_swing.py
104
+ tests/test_learnable.py
105
+ tests/test_orbit_hill.py
106
+ tests/test_vector_basis.py
@@ -2,7 +2,6 @@ include LICENSE
2
2
  include README.md
3
3
  include CHANGELOG.md
4
4
  include requirements.txt
5
- recursive-include misc *.png *.gif
6
5
  recursive-include examples *.py
7
6
  recursive-include tests *.py
8
7
  recursive-exclude * __pycache__
@@ -1,25 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FastLSQ
3
- Version: 0.1.5
4
- Summary: Solving PDEs in one shot via Fourier features with exact analytical derivatives
3
+ Version: 0.2.2
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
7
- Project-URL: Homepage, https://github.com/asulc/FastLSQ
8
- Project-URL: Repository, https://github.com/asulc/FastLSQ
7
+ Project-URL: Homepage, https://github.com/sulcantonin/FastLSQ
8
+ Project-URL: Repository, https://github.com/sulcantonin/FastLSQ
9
9
  Project-URL: Paper, https://arxiv.org/abs/2602.10541
10
- Project-URL: Bug Tracker, https://github.com/asulc/FastLSQ/issues
11
- Project-URL: Changelog, https://github.com/asulc/FastLSQ/blob/main/CHANGELOG.md
10
+ Project-URL: Bug Tracker, https://github.com/sulcantonin/FastLSQ/issues
11
+ Project-URL: Changelog, https://github.com/sulcantonin/FastLSQ/blob/main/CHANGELOG.md
12
12
  Keywords: pde,partial-differential-equations,fourier-features,least-squares,scientific-computing,neural-network,physics-informed,newton-raphson
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
17
18
  Classifier: Programming Language :: Python :: 3.10
18
19
  Classifier: Programming Language :: Python :: 3.11
19
20
  Classifier: Programming Language :: Python :: 3.12
20
21
  Classifier: Topic :: Scientific/Engineering :: Mathematics
21
22
  Classifier: Topic :: Scientific/Engineering :: Physics
22
- Requires-Python: >=3.10
23
+ Requires-Python: >=3.9
23
24
  Description-Content-Type: text/markdown
24
25
  License-File: LICENSE
25
26
  Requires-Dist: torch>=2.0
@@ -44,7 +45,7 @@ Dynamic: license-file
44
45
 
45
46
 
46
47
  <p align="center">
47
- <img src="misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
48
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
48
49
  </p>
49
50
 
50
51
  **Solving PDEs in one shot via Fourier features with exact analytical derivatives.**
@@ -234,8 +235,8 @@ python examples/learnable_helmholtz.py
234
235
  The analytical derivatives enable gradients through the pre-factored solve, making inverse problems tractable. Example: recovering 4 anisotropic Gaussian heat sources (24 parameters) from 4 sparse sensors. The heat equation is solved in space-time; L-BFGS-B optimises source positions and shapes to match sensor time-series. *(Click image for animation.)*
235
236
 
236
237
  <p align="center">
237
- <a href="misc/inverse_heat_source.gif">
238
- <img src="misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
238
+ <a href="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.gif">
239
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
239
240
  </a>
240
241
  </p>
241
242
 
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
  <p align="center">
7
- <img src="misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
7
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="400"/>
8
8
  </p>
9
9
 
10
10
  **Solving PDEs in one shot via Fourier features with exact analytical derivatives.**
@@ -194,8 +194,8 @@ python examples/learnable_helmholtz.py
194
194
  The analytical derivatives enable gradients through the pre-factored solve, making inverse problems tractable. Example: recovering 4 anisotropic Gaussian heat sources (24 parameters) from 4 sparse sensors. The heat equation is solved in space-time; L-BFGS-B optimises source positions and shapes to match sensor time-series. *(Click image for animation.)*
195
195
 
196
196
  <p align="center">
197
- <a href="misc/inverse_heat_source.gif">
198
- <img src="misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
197
+ <a href="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.gif">
198
+ <img src="https://raw.githubusercontent.com/sulcantonin/FastLSQ/main/misc/inverse_heat_source.png" alt="Inverse heat source localisation" width="700"/>
199
199
  </a>
200
200
  </p>
201
201