A Python wrapper for a high-performance Fortran kriging and Sequential Gaussian Simulation (SGSIM) engine. The Fortran core is parallelised with OpenMP and supports:
- Ordinary and simple kriging (point and block)
- Co-kriging (multiple variables, Linear Model of Coregionalisation)
- Universal kriging (external drift / KED)
- Sequential Gaussian Simulation (SGSIM) with reproducible paths and samples
- Cross-validation (leave-one-out)
- Anisotropic search and per-block variogram scaling
| Component | Minimum version |
|---|---|
| Python | 3.10 |
| NumPy | 1.24 |
| gfortran or Intel ifx/ifort | any recent |
git clone https://github.com/your-username/pykriging.git
cd pykrigingLinux / macOS (gfortran)
python build_lib.py
# or with explicit compiler:
python build_lib.py --compiler gfortran
# debug build (adds -g -fcheck=all):
python build_lib.py --opt debugWindows (Intel ifx)
call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
python build_lib.py --compiler ifxThe script compiles all Fortran sources in src/libkriging/ in dependency order and
places the resulting libkriging.so (or kriging.dll) inside src/pykriging/.
pip install -e . # editable install (recommended for development)
# or:
pip install . # regular installpip install -e ".[dev]"
pytestimport numpy as np
from pykriging import ordinary_kriging, Kriging
# --- Convenience function: one-shot ordinary kriging ---
obs_coord = np.array([[0,0],[1,0],[0,1],[1,1],[0.5,0.5]], dtype=float)
obs_value = np.array([1.0, 2.0, 3.0, 4.0, 2.5])
grid_coord = np.mgrid[0:1.1:0.25, 0:1.1:0.25].reshape(2,-1).T
est, var = ordinary_kriging(
obs_coord, obs_value, grid_coord,
vgm_spec=dict(vtype="sph", nugget=0.0, sill=1.0, a_major=1.0, a_minor1=0.8),
nmax=5,
)
print(est.shape, var.shape) # (25,) (25,)
# --- Full class interface ---
k = Kriging(ndim=2, nvar=1)
k.set_vgm(ivar=1, jvar=1, vtype="sph", nugget=0.0, sill=1.0, a_major=1.0, a_minor1=0.8)
k.set_obs(ivar=1, coord=obs_coord, value=obs_value, nmax=5)
k.set_grid(coord=grid_coord)
k.set_sim()
k.set_search(ivar=1)
k.solve()
est, var = k.get_results()All coordinate arrays use (nobs, ndim) shape — rows are points, columns are spatial dimensions. This matches NumPy, pandas, and scikit-learn. The wrapper transposes to Fortran's (ndim, nobs) column-major layout internally.
obs_coord = np.array([[x1,y1], [x2,y2], ...]) # shape (nobs, ndim)
grid_coord = np.array([[gx1,gy1], [gx2,gy2], ...]) # shape (ngrid, ndim)
drift = np.array([[d1a,d1b], [d2a,d2b], ...]) # shape (nobs, ndrift)Variograms are specified via keyword arguments to set_vgm:
| Parameter | Default | Description |
|---|---|---|
vtype |
(required) | Model type: sph exp gau pow lin hol bsq cir nug |
nugget |
0.0 |
Nugget effect |
sill |
1.0 |
Partial sill (variance contributed by this structure) |
a_major |
1.0 |
Range along the major axis |
a_minor1 |
a_major |
Range along the minor horizontal axis (defaults to isotropic) |
a_minor2 |
a_minor1 |
Range along the vertical axis (3D only) |
azimuth |
0.0 |
Azimuth of major axis (degrees, clockwise from North) |
dip |
0.0 |
Dip angle (degrees, positive downward) |
plunge |
0.0 |
Plunge angle (degrees) |
Call set_vgm multiple times to build a composite (nested) model:
k.set_vgm(1, 1, vtype="sph", nugget=100.0, sill=400.0, a_major=1000, a_minor1=500) # structure 1
k.set_vgm(1, 1, vtype="exp", nugget=0.0, sill=500.0, a_major=500, a_minor1=300) # structure 2from pykriging import cokriging
est, var = cokriging(
obs_coords=[coord_primary, coord_secondary],
obs_values=[value_primary, value_secondary],
grid_coord=grid,
vgm_spec={
(1, 1): dict(vtype="sph", nugget=0, sill=1.0, a_major=1000, a_minor1=500), # primary auto-vgm
(2, 2): dict(vtype="sph", nugget=0, sill=1.0, a_major=1000, a_minor1=500), # secondary auto-vgm
(1, 2): dict(vtype="sph", nugget=0, sill=0.8, a_major=1000, a_minor1=500), # cross-vgm (b12²≤b11·b22)
},
nmax=20,
)from pykriging import sequential_gaussian_simulation
# Returns shape (nsim, ngrid)
sims = sequential_gaussian_simulation(
obs_coord, obs_value, grid_coord,
vgm_spec=dict(vtype="sph", nugget=0.0, sill=1.0, a_major=1000, a_minor1=500),
nsim=100,
nmax=20,
seed=42,
)
ensemble_mean = sims.mean(axis=0)Single large job — control OpenMP threads from Python before importing:
import os
os.environ["OMP_NUM_THREADS"] = "8"
from pykriging import KrigingMultiple independent jobs — use multiprocessing to avoid shared Fortran state:
import os, multiprocessing as mp
from pykriging import ordinary_kriging
def run(args):
os.environ["OMP_NUM_THREADS"] = "4"
coord, value, grid, spec = args
return ordinary_kriging(coord, value, grid, spec)
with mp.Pool(4) as pool:
results = pool.map(run, jobs)pykriging/
├── src/ Source codes
│ ├── libkriging Core kriging engine/library
│ ├── ppsgs Pilot point based SGSIM tool
│ └── pykriging Python wrapper
├── tests/ pytest test suite
├── test_data/ CSV files used by the test suite
├── docs/ Extended documentation (optional)
├── build_lib.py Compile script (gfortran / ifx / ifort)
├── pyproject.toml pip package configuration
├── LICENSE MIT
└── README.md
- Fork the repository on GitHub.
- Create a feature branch:
git checkout -b feature/my-feature. - Make your changes and add tests.
- Run
pytestto ensure all tests pass. - Open a pull request.
MIT — see LICENSE.