Differentiable Gaussian random field generation in PyTorch
Project description
DiffGRF
Differentiable Gaussian random field generation in PyTorch.
DiffGRF implements the spectral randomization method for Gaussian random field (GRF) synthesis (Kraichnan 1970; Hesse et al. 2014) with full PyTorch autograd support. Gradients flow analytically through every physical parameter — variance, correlation length(s), anisotropy, rotation angles and the Matérn smoothness — so the generator can be used as a differentiable building block in inverse problems, design optimisation, and torch-native training pipelines.
Features
- Gaussian and Matérn kernels
- 1D, 2D, and 3D spatial domains
- Isotropic or per-axis anisotropic correlation lengths
- Differentiable rotation (2D angle, 3D Tait–Bryan triplet)
- Structured (regular grid), unstructured (arbitrary points), and
mesh-native (
meshio/ gmsh.msh) sampling - CPU, CUDA, and Apple MPS device support
- End-to-end autograd through all physical parameters
Installation
pip install diffgrf
Or from source:
git clone https://github.com/EJRicketts/diffgrf.git
cd diffgrf
pip install -e .[dev]
Requires Python ≥ 3.10, PyTorch ≥ 2.0, NumPy ≥ 1.22.
GPU acceleration is available via device="cuda" (NVIDIA) or
device="mps" (Apple Silicon). MPS does not support float64, so
pass dtype=torch.float32 when using MPS:
import torch
from diffgrf import DifferentiableGRF
grf = DifferentiableGRF(
kernel="gau", dim=2, variance=1.0, len_scale=10.0, seed=0,
device="mps", dtype=torch.float32,
)
field = grf.structured([256, 256])
Observed speedups on Apple M-series over CPU: 4–5× at 128²–256² 2D, ~10× at 96³ 3D.
Quickstart
Generate a 2D Gaussian random field on a regular grid:
from diffgrf import DifferentiableGRF
grf = DifferentiableGRF(
kernel="gau", dim=2, variance=1.0, len_scale=10.0, seed=0,
)
field = grf.structured([128, 128])
# field is a torch.Tensor of shape (128, 128)
Flow gradients through the correlation length:
import torch
from diffgrf import DifferentiableGRF
len_scale = torch.tensor(10.0, requires_grad=True)
grf = DifferentiableGRF(
kernel="gau", dim=2, variance=1.0, len_scale=len_scale, seed=0,
)
field = grf.structured([128, 128])
loss = field.var()
loss.backward()
print(len_scale.grad) # analytical gradient via spectral reparameterisation
Evaluate a field directly on an unstructured mesh (requires meshio,
pip install diffgrf[mesh]):
import meshio
from diffgrf import DifferentiableGRF
grf = DifferentiableGRF(
kernel="mat", dim=2, variance=1.0, len_scale=5.0, nu=1.5, seed=0,
)
# Accepts a meshio.Mesh OR any path readable by meshio.read.
# Evaluate at vertices (default) or cell centroids.
field_at_nodes = grf.on_mesh(meshio.read("domain.msh"))
field_at_cells = grf.on_mesh("domain.msh", location="cells")
Recover a correlation length from a target sample by gradient descent:
import torch
from diffgrf import DifferentiableGRF
target = DifferentiableGRF(
"gau", 2, 1.0, 12.0, seed=0,
).structured([128, 128])
ell = torch.tensor(5.0, requires_grad=True)
opt = torch.optim.Adam([ell], lr=0.2)
for _ in range(200):
opt.zero_grad()
pred = DifferentiableGRF("gau", 2, 1.0, ell, seed=0).structured([128, 128])
loss = (pred - target).pow(2).mean()
loss.backward()
opt.step()
print(float(ell)) # -> ~12
API
DifferentiableGRF(kernel, dim, variance, len_scale, ...)
The single entry point. See diffgrf/core.py for full signature and
docstrings.
Methods:
.structured(grid_dim)— generate on a regular grid..unstructured(points)— generate at arbitrary spatial points..on_mesh(mesh, location='points')— generate on ameshio.Meshor a path to any meshio-compatible file (.msh,.vtk,.xdmf, ...); evaluate at vertices (location='points') or cell centroids (location='cells'). Requires the optionalmeshiodependency (pip install diffgrf[mesh]).
Citation
If you use DiffGRF in published work, please cite:
@software{diffgrf,
author = {Ricketts, Evan John},
title = {DiffGRF: Differentiable Gaussian random field generation in PyTorch},
year = {2026},
url = {https://github.com/EJRicketts/diffgrf},
}
A peer-reviewed SoftwareX paper describing DiffGRF is in preparation; the citation will be updated once published.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file diffgrf-1.0.0.tar.gz.
File metadata
- Download URL: diffgrf-1.0.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26fc6640e0a5dae0bdef2474ab53a3050e5b9556f223dc6f14e999baf51c3afe
|
|
| MD5 |
08e1e3f2acfed578ef7bfbe2b09be927
|
|
| BLAKE2b-256 |
7307d1800a22f042e935dcd530955ec3d177c6659f8c656eaf871df3ea8fc97b
|
File details
Details for the file diffgrf-1.0.0-py3-none-any.whl.
File metadata
- Download URL: diffgrf-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
857a0376d260a473c9258cc1f66f6d6a42480abc7fb89481f867291216d73b0b
|
|
| MD5 |
238812b7f92b3f055bf7ed19daeca648
|
|
| BLAKE2b-256 |
c6a98a0d2625a24f0cd61a08807b289741f405fe5a871ef1112b8611b1eb5554
|