FastLSQ 0.1.0__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.1.0/CHANGELOG.md +63 -0
- fastlsq-0.1.0/FastLSQ.egg-info/PKG-INFO +210 -0
- fastlsq-0.1.0/FastLSQ.egg-info/SOURCES.txt +34 -0
- fastlsq-0.1.0/FastLSQ.egg-info/dependency_links.txt +1 -0
- fastlsq-0.1.0/FastLSQ.egg-info/requires.txt +12 -0
- fastlsq-0.1.0/FastLSQ.egg-info/top_level.txt +1 -0
- fastlsq-0.1.0/LICENSE +21 -0
- fastlsq-0.1.0/MANIFEST.in +8 -0
- fastlsq-0.1.0/PKG-INFO +210 -0
- fastlsq-0.1.0/README.md +174 -0
- fastlsq-0.1.0/examples/add_your_own_pde.py +111 -0
- fastlsq-0.1.0/examples/custom_features.py +65 -0
- fastlsq-0.1.0/examples/run_linear.py +203 -0
- fastlsq-0.1.0/examples/run_nonlinear.py +259 -0
- fastlsq-0.1.0/examples/tutorial_basic.py +44 -0
- fastlsq-0.1.0/examples/tutorial_nonlinear.py +54 -0
- fastlsq-0.1.0/fastlsq/__init__.py +75 -0
- fastlsq-0.1.0/fastlsq/api.py +314 -0
- fastlsq-0.1.0/fastlsq/diagnostics.py +247 -0
- fastlsq-0.1.0/fastlsq/export.py +170 -0
- fastlsq-0.1.0/fastlsq/geometry.py +243 -0
- fastlsq-0.1.0/fastlsq/lightning.py +94 -0
- fastlsq-0.1.0/fastlsq/linalg.py +34 -0
- fastlsq-0.1.0/fastlsq/newton.py +166 -0
- fastlsq-0.1.0/fastlsq/plotting.py +359 -0
- fastlsq-0.1.0/fastlsq/problems/__init__.py +30 -0
- fastlsq-0.1.0/fastlsq/problems/linear.py +432 -0
- fastlsq-0.1.0/fastlsq/problems/nonlinear.py +379 -0
- fastlsq-0.1.0/fastlsq/problems/regression.py +398 -0
- fastlsq-0.1.0/fastlsq/solvers.py +217 -0
- fastlsq-0.1.0/fastlsq/tuning.py +116 -0
- fastlsq-0.1.0/fastlsq/utils.py +48 -0
- fastlsq-0.1.0/pyproject.toml +65 -0
- fastlsq-0.1.0/requirements.txt +5 -0
- fastlsq-0.1.0/setup.cfg +4 -0
- fastlsq-0.1.0/tests/test_basic.py +101 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to FastLSQ will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-02-12
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
#### High-level API
|
|
10
|
+
- `solve_linear()` - One-line function to solve linear PDEs
|
|
11
|
+
- `solve_nonlinear()` - One-line function to solve nonlinear PDEs via Newton-Raphson
|
|
12
|
+
- Automatic scale selection via `auto_select_scale()`
|
|
13
|
+
|
|
14
|
+
#### Plotting & Visualization
|
|
15
|
+
- `plot_solution_1d()` - Plot 1D solutions with exact comparison
|
|
16
|
+
- `plot_solution_2d_slice()` - Plot 2D solutions as 1D slices
|
|
17
|
+
- `plot_solution_2d_contour()` - Contour plots for 2D solutions
|
|
18
|
+
- `plot_convergence()` - Newton iteration convergence plots
|
|
19
|
+
- `plot_spectral_sensitivity()` - Error vs scale analysis
|
|
20
|
+
|
|
21
|
+
#### Geometry & Sampling
|
|
22
|
+
- `sample_box()` - Uniform sampling from hypercubes
|
|
23
|
+
- `sample_ball()` - Uniform sampling from balls
|
|
24
|
+
- `sample_sphere()` - Uniform sampling from sphere surfaces
|
|
25
|
+
- `sample_interval()` - 1D interval sampling
|
|
26
|
+
- `sample_boundary_box()` - Boundary point generation for boxes
|
|
27
|
+
- `get_sampler()` - Get sampler by name
|
|
28
|
+
|
|
29
|
+
#### Diagnostics & Error Handling
|
|
30
|
+
- `check_problem()` - Validate problem definitions (shapes, gradients, data)
|
|
31
|
+
- `check_solver_conditioning()` - Check linear system conditioning
|
|
32
|
+
- `suggest_scale()` - Heuristic scale suggestions
|
|
33
|
+
|
|
34
|
+
#### Export & Interoperability
|
|
35
|
+
- `to_numpy()` - Convert predictions to NumPy arrays
|
|
36
|
+
- `to_dict()` / `from_dict()` - Serialize/deserialize solver state
|
|
37
|
+
- `save_checkpoint()` / `load_checkpoint()` - Save/load solver checkpoints
|
|
38
|
+
- `FastLSQModule` - PyTorch Lightning integration (optional)
|
|
39
|
+
|
|
40
|
+
#### Documentation & Examples
|
|
41
|
+
- `examples/tutorial_basic.py` - Basic linear PDE tutorial
|
|
42
|
+
- `examples/tutorial_nonlinear.py` - Nonlinear PDE tutorial
|
|
43
|
+
- `examples/add_your_own_pde.py` - Guide for adding custom PDEs
|
|
44
|
+
- `examples/custom_features.py` - Extensibility example
|
|
45
|
+
- Comprehensive README with usage examples
|
|
46
|
+
|
|
47
|
+
#### Infrastructure
|
|
48
|
+
- `benchmarks/run_all.py` - Reproducible benchmark suite
|
|
49
|
+
- `tests/test_basic.py` - Basic test suite
|
|
50
|
+
- `.github/workflows/ci.yml` - GitHub Actions CI/CD
|
|
51
|
+
- `CHANGELOG.md` - This file
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- Restructured codebase from 2 monolithic files into a proper Python package
|
|
56
|
+
- Unified `FastLSQSolver` with optional normalization parameter
|
|
57
|
+
- Removed code duplication (Bratu, NL-Helmholtz regression inherit from nonlinear versions)
|
|
58
|
+
- Removed non-scientific content (emojis, casual language)
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- Fixed missing `solve_lstsq` import in linear solver (was only defined in nonlinear file)
|
|
63
|
+
- Improved error messages and diagnostics
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: FastLSQ
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Solving PDEs in one shot via Fourier features with exact analytical derivatives
|
|
5
|
+
Author: Antonin Sulc
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/asulc/FastLSQ
|
|
8
|
+
Project-URL: Repository, https://github.com/asulc/FastLSQ
|
|
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
|
|
12
|
+
Keywords: pde,partial-differential-equations,fourier-features,least-squares,scientific-computing,neural-network,physics-informed,newton-raphson
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: torch>=2.0
|
|
26
|
+
Requires-Dist: numpy>=1.24
|
|
27
|
+
Requires-Dist: matplotlib>=3.7
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pandas>=2.0; extra == "dev"
|
|
31
|
+
Requires-Dist: build; extra == "dev"
|
|
32
|
+
Requires-Dist: twine; extra == "dev"
|
|
33
|
+
Provides-Extra: lightning
|
|
34
|
+
Requires-Dist: pytorch-lightning>=2.0; extra == "lightning"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# FastLSQ
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="800"/>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
**Solving PDEs in one shot via Fourier features with exact analytical derivatives.**
|
|
44
|
+
|
|
45
|
+
FastLSQ is a lightweight PDE solver that uses Random Fourier Features with
|
|
46
|
+
`sin` activation and closed-form first- and second-order derivatives.
|
|
47
|
+
Linear PDEs are solved in a single least-squares step; nonlinear PDEs are
|
|
48
|
+
solved via Newton-Raphson iteration with Tikhonov regularisation,
|
|
49
|
+
1/sqrt(N) feature normalisation, and continuation/homotopy.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install fastlsq
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For development (includes testing and build tools):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/asulc/FastLSQ.git
|
|
61
|
+
cd FastLSQ
|
|
62
|
+
pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
### Solve a linear PDE in one line
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from fastlsq import solve_linear
|
|
71
|
+
from fastlsq.problems.linear import PoissonND
|
|
72
|
+
|
|
73
|
+
problem = PoissonND()
|
|
74
|
+
result = solve_linear(problem, scale=5.0) # Auto-selects scale if None
|
|
75
|
+
|
|
76
|
+
u_fn = result["u_fn"]
|
|
77
|
+
print(f"Value error: {result['metrics']['val_err']:.2e}")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Solve a nonlinear PDE
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from fastlsq import solve_nonlinear
|
|
84
|
+
from fastlsq.problems.nonlinear import NLPoisson2D
|
|
85
|
+
|
|
86
|
+
problem = NLPoisson2D()
|
|
87
|
+
result = solve_nonlinear(problem, max_iter=30)
|
|
88
|
+
|
|
89
|
+
print(f"Converged in {result['n_iters']} iterations")
|
|
90
|
+
print(f"Value error: {result['metrics']['val_err']:.2e}")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Plot solutions
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from fastlsq.plotting import plot_solution_2d_contour, plot_convergence
|
|
97
|
+
|
|
98
|
+
# Plot 2D solution
|
|
99
|
+
plot_solution_2d_contour(result["solver"], problem, save_path="solution.png")
|
|
100
|
+
|
|
101
|
+
# Plot Newton convergence
|
|
102
|
+
plot_convergence(result["history"], problem_name=problem.name, save_path="convergence.png")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Check your problem definition
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from fastlsq.diagnostics import check_problem
|
|
109
|
+
|
|
110
|
+
check_problem(problem) # Validates shapes, gradients, data consistency
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Benchmarks
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Linear PDE benchmark (Fast-LSQ vs PIELM)
|
|
117
|
+
python examples/run_linear.py
|
|
118
|
+
|
|
119
|
+
# Nonlinear PDE benchmark (Newton-Raphson)
|
|
120
|
+
python examples/run_nonlinear.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Features
|
|
124
|
+
|
|
125
|
+
- **High-level API**: Solve PDEs in one line with `solve_linear()` and `solve_nonlinear()`
|
|
126
|
+
- **Auto-tuning**: Automatic scale selection via grid search
|
|
127
|
+
- **Built-in plotting**: Solution visualization, convergence plots, spectral sensitivity
|
|
128
|
+
- **Geometry samplers**: Box, ball, sphere, interval, custom samplers
|
|
129
|
+
- **Diagnostics**: Problem validation, conditioning checks, error detection
|
|
130
|
+
- **Export utilities**: NumPy conversion, checkpoint saving/loading
|
|
131
|
+
- **PyTorch Lightning**: Integration for training loops
|
|
132
|
+
- **20+ benchmark problems**: Linear, nonlinear, and regression-mode PDEs
|
|
133
|
+
|
|
134
|
+
## Method overview
|
|
135
|
+
|
|
136
|
+
1. **Feature construction.** Given collocation points x, compute
|
|
137
|
+
`H = sin(x W + b)` together with exact derivatives
|
|
138
|
+
`dH = cos(x W + b) * W` and `ddH = -sin(x W + b) * W^2`.
|
|
139
|
+
|
|
140
|
+
2. **Linear solve.** Assemble the PDE operator in feature space:
|
|
141
|
+
`A beta = b`, and solve via least squares (optionally Tikhonov-regularised).
|
|
142
|
+
|
|
143
|
+
3. **Newton iteration (nonlinear).** Linearise the PDE residual around the
|
|
144
|
+
current iterate, solve `J delta_beta = -R` with backtracking line search,
|
|
145
|
+
and repeat until convergence.
|
|
146
|
+
|
|
147
|
+
## Adding your own PDE
|
|
148
|
+
|
|
149
|
+
Create a problem class with these methods:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
class MyProblem:
|
|
153
|
+
def __init__(self):
|
|
154
|
+
self.name = "My PDE"
|
|
155
|
+
self.dim = 2 # Spatial dimension
|
|
156
|
+
|
|
157
|
+
def exact(self, x):
|
|
158
|
+
"""Analytical solution u(x)."""
|
|
159
|
+
return torch.sin(np.pi * x[:, 0:1]) * torch.sin(np.pi * x[:, 1:2])
|
|
160
|
+
|
|
161
|
+
def exact_grad(self, x):
|
|
162
|
+
"""Gradient of exact solution."""
|
|
163
|
+
# ... compute gradient analytically
|
|
164
|
+
return grad_u
|
|
165
|
+
|
|
166
|
+
def get_train_data(self, n_pde=5000, n_bc=1000):
|
|
167
|
+
"""Return (x_pde, bcs, f_pde) for training."""
|
|
168
|
+
# ... sample collocation and boundary points
|
|
169
|
+
return x_pde, bcs, f_pde
|
|
170
|
+
|
|
171
|
+
def build(self, solver, x_pde, bcs, f_pde):
|
|
172
|
+
"""Assemble linear system A beta = b."""
|
|
173
|
+
# ... build system matrix
|
|
174
|
+
return A, b
|
|
175
|
+
|
|
176
|
+
def get_test_points(self, n=5000):
|
|
177
|
+
"""Random test points for evaluation."""
|
|
178
|
+
return torch.rand(n, self.dim)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Then solve it:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
problem = MyProblem()
|
|
185
|
+
result = solve_linear(problem)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Paper
|
|
189
|
+
|
|
190
|
+
The full preprint is available on [arXiv](https://arxiv.org/abs/2602.10541)
|
|
191
|
+
|
|
192
|
+
## Citing this work
|
|
193
|
+
|
|
194
|
+
If you use FastLSQ in your research, please cite:
|
|
195
|
+
|
|
196
|
+
```bibtex
|
|
197
|
+
@misc{sulc2026solvingpdesshotfourier,
|
|
198
|
+
title={Solving PDEs in One Shot via Fourier Features with Exact Analytical Derivatives},
|
|
199
|
+
author={Antonin Sulc},
|
|
200
|
+
year={2026},
|
|
201
|
+
eprint={2602.10541},
|
|
202
|
+
archivePrefix={arXiv},
|
|
203
|
+
primaryClass={math.NA},
|
|
204
|
+
url={https://arxiv.org/abs/2602.10541},
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
This project is licensed under the MIT License -- see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,34 @@
|
|
|
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/custom_features.py
|
|
14
|
+
examples/run_linear.py
|
|
15
|
+
examples/run_nonlinear.py
|
|
16
|
+
examples/tutorial_basic.py
|
|
17
|
+
examples/tutorial_nonlinear.py
|
|
18
|
+
fastlsq/__init__.py
|
|
19
|
+
fastlsq/api.py
|
|
20
|
+
fastlsq/diagnostics.py
|
|
21
|
+
fastlsq/export.py
|
|
22
|
+
fastlsq/geometry.py
|
|
23
|
+
fastlsq/lightning.py
|
|
24
|
+
fastlsq/linalg.py
|
|
25
|
+
fastlsq/newton.py
|
|
26
|
+
fastlsq/plotting.py
|
|
27
|
+
fastlsq/solvers.py
|
|
28
|
+
fastlsq/tuning.py
|
|
29
|
+
fastlsq/utils.py
|
|
30
|
+
fastlsq/problems/__init__.py
|
|
31
|
+
fastlsq/problems/linear.py
|
|
32
|
+
fastlsq/problems/nonlinear.py
|
|
33
|
+
fastlsq/problems/regression.py
|
|
34
|
+
tests/test_basic.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fastlsq
|
fastlsq-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Antonin Sulc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
fastlsq-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: FastLSQ
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Solving PDEs in one shot via Fourier features with exact analytical derivatives
|
|
5
|
+
Author: Antonin Sulc
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/asulc/FastLSQ
|
|
8
|
+
Project-URL: Repository, https://github.com/asulc/FastLSQ
|
|
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
|
|
12
|
+
Keywords: pde,partial-differential-equations,fourier-features,least-squares,scientific-computing,neural-network,physics-informed,newton-raphson
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: torch>=2.0
|
|
26
|
+
Requires-Dist: numpy>=1.24
|
|
27
|
+
Requires-Dist: matplotlib>=3.7
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pandas>=2.0; extra == "dev"
|
|
31
|
+
Requires-Dist: build; extra == "dev"
|
|
32
|
+
Requires-Dist: twine; extra == "dev"
|
|
33
|
+
Provides-Extra: lightning
|
|
34
|
+
Requires-Dist: pytorch-lightning>=2.0; extra == "lightning"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# FastLSQ
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="misc/fastlsq_teaser.png" alt="FastLSQ method overview" width="800"/>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
**Solving PDEs in one shot via Fourier features with exact analytical derivatives.**
|
|
44
|
+
|
|
45
|
+
FastLSQ is a lightweight PDE solver that uses Random Fourier Features with
|
|
46
|
+
`sin` activation and closed-form first- and second-order derivatives.
|
|
47
|
+
Linear PDEs are solved in a single least-squares step; nonlinear PDEs are
|
|
48
|
+
solved via Newton-Raphson iteration with Tikhonov regularisation,
|
|
49
|
+
1/sqrt(N) feature normalisation, and continuation/homotopy.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install fastlsq
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For development (includes testing and build tools):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/asulc/FastLSQ.git
|
|
61
|
+
cd FastLSQ
|
|
62
|
+
pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
### Solve a linear PDE in one line
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from fastlsq import solve_linear
|
|
71
|
+
from fastlsq.problems.linear import PoissonND
|
|
72
|
+
|
|
73
|
+
problem = PoissonND()
|
|
74
|
+
result = solve_linear(problem, scale=5.0) # Auto-selects scale if None
|
|
75
|
+
|
|
76
|
+
u_fn = result["u_fn"]
|
|
77
|
+
print(f"Value error: {result['metrics']['val_err']:.2e}")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Solve a nonlinear PDE
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from fastlsq import solve_nonlinear
|
|
84
|
+
from fastlsq.problems.nonlinear import NLPoisson2D
|
|
85
|
+
|
|
86
|
+
problem = NLPoisson2D()
|
|
87
|
+
result = solve_nonlinear(problem, max_iter=30)
|
|
88
|
+
|
|
89
|
+
print(f"Converged in {result['n_iters']} iterations")
|
|
90
|
+
print(f"Value error: {result['metrics']['val_err']:.2e}")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Plot solutions
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from fastlsq.plotting import plot_solution_2d_contour, plot_convergence
|
|
97
|
+
|
|
98
|
+
# Plot 2D solution
|
|
99
|
+
plot_solution_2d_contour(result["solver"], problem, save_path="solution.png")
|
|
100
|
+
|
|
101
|
+
# Plot Newton convergence
|
|
102
|
+
plot_convergence(result["history"], problem_name=problem.name, save_path="convergence.png")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Check your problem definition
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from fastlsq.diagnostics import check_problem
|
|
109
|
+
|
|
110
|
+
check_problem(problem) # Validates shapes, gradients, data consistency
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Benchmarks
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Linear PDE benchmark (Fast-LSQ vs PIELM)
|
|
117
|
+
python examples/run_linear.py
|
|
118
|
+
|
|
119
|
+
# Nonlinear PDE benchmark (Newton-Raphson)
|
|
120
|
+
python examples/run_nonlinear.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Features
|
|
124
|
+
|
|
125
|
+
- **High-level API**: Solve PDEs in one line with `solve_linear()` and `solve_nonlinear()`
|
|
126
|
+
- **Auto-tuning**: Automatic scale selection via grid search
|
|
127
|
+
- **Built-in plotting**: Solution visualization, convergence plots, spectral sensitivity
|
|
128
|
+
- **Geometry samplers**: Box, ball, sphere, interval, custom samplers
|
|
129
|
+
- **Diagnostics**: Problem validation, conditioning checks, error detection
|
|
130
|
+
- **Export utilities**: NumPy conversion, checkpoint saving/loading
|
|
131
|
+
- **PyTorch Lightning**: Integration for training loops
|
|
132
|
+
- **20+ benchmark problems**: Linear, nonlinear, and regression-mode PDEs
|
|
133
|
+
|
|
134
|
+
## Method overview
|
|
135
|
+
|
|
136
|
+
1. **Feature construction.** Given collocation points x, compute
|
|
137
|
+
`H = sin(x W + b)` together with exact derivatives
|
|
138
|
+
`dH = cos(x W + b) * W` and `ddH = -sin(x W + b) * W^2`.
|
|
139
|
+
|
|
140
|
+
2. **Linear solve.** Assemble the PDE operator in feature space:
|
|
141
|
+
`A beta = b`, and solve via least squares (optionally Tikhonov-regularised).
|
|
142
|
+
|
|
143
|
+
3. **Newton iteration (nonlinear).** Linearise the PDE residual around the
|
|
144
|
+
current iterate, solve `J delta_beta = -R` with backtracking line search,
|
|
145
|
+
and repeat until convergence.
|
|
146
|
+
|
|
147
|
+
## Adding your own PDE
|
|
148
|
+
|
|
149
|
+
Create a problem class with these methods:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
class MyProblem:
|
|
153
|
+
def __init__(self):
|
|
154
|
+
self.name = "My PDE"
|
|
155
|
+
self.dim = 2 # Spatial dimension
|
|
156
|
+
|
|
157
|
+
def exact(self, x):
|
|
158
|
+
"""Analytical solution u(x)."""
|
|
159
|
+
return torch.sin(np.pi * x[:, 0:1]) * torch.sin(np.pi * x[:, 1:2])
|
|
160
|
+
|
|
161
|
+
def exact_grad(self, x):
|
|
162
|
+
"""Gradient of exact solution."""
|
|
163
|
+
# ... compute gradient analytically
|
|
164
|
+
return grad_u
|
|
165
|
+
|
|
166
|
+
def get_train_data(self, n_pde=5000, n_bc=1000):
|
|
167
|
+
"""Return (x_pde, bcs, f_pde) for training."""
|
|
168
|
+
# ... sample collocation and boundary points
|
|
169
|
+
return x_pde, bcs, f_pde
|
|
170
|
+
|
|
171
|
+
def build(self, solver, x_pde, bcs, f_pde):
|
|
172
|
+
"""Assemble linear system A beta = b."""
|
|
173
|
+
# ... build system matrix
|
|
174
|
+
return A, b
|
|
175
|
+
|
|
176
|
+
def get_test_points(self, n=5000):
|
|
177
|
+
"""Random test points for evaluation."""
|
|
178
|
+
return torch.rand(n, self.dim)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Then solve it:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
problem = MyProblem()
|
|
185
|
+
result = solve_linear(problem)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Paper
|
|
189
|
+
|
|
190
|
+
The full preprint is available on [arXiv](https://arxiv.org/abs/2602.10541)
|
|
191
|
+
|
|
192
|
+
## Citing this work
|
|
193
|
+
|
|
194
|
+
If you use FastLSQ in your research, please cite:
|
|
195
|
+
|
|
196
|
+
```bibtex
|
|
197
|
+
@misc{sulc2026solvingpdesshotfourier,
|
|
198
|
+
title={Solving PDEs in One Shot via Fourier Features with Exact Analytical Derivatives},
|
|
199
|
+
author={Antonin Sulc},
|
|
200
|
+
year={2026},
|
|
201
|
+
eprint={2602.10541},
|
|
202
|
+
archivePrefix={arXiv},
|
|
203
|
+
primaryClass={math.NA},
|
|
204
|
+
url={https://arxiv.org/abs/2602.10541},
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
This project is licensed under the MIT License -- see [LICENSE](LICENSE) for details.
|