Skip to main content

Periodic Gaussian random field generation using spectral filtering techniques

Project description

rfgen

Periodic Gaussian Random Field Generation and Analysis

PyPI version Python 3.9+ License: BSD-3-Clause

Generate periodic 1D/2D/3D Gaussian random fields with prescribed power spectra using Fourier-space filtering. Includes tools for spectral analysis, autocorrelation, and statistical moments.

1D/2D/3D Correlated Random Surface Generation


Features

  • Self-affine (power-law) spectrum — controlled by Hurst exponent $H \in [0, 1]$
  • Matérn covariance spectrum — controlled by smoothness parameter $\nu > 0$
  • Two generation modes:
    • noise=True: Filtered white noise (spectrum follows target on average)
    • noise=False: Ideal spectrum with random phases (spectrum matches target exactly)
  • Analysis tools:
    • Fast FFT-based autocorrelation (1D, 2D, N-D)
    • Power spectral density computation
    • Spectral moments ($m_{00}$, $m_{20}$, $m_{02}$, $m_{40}$, $m_{04}$, etc.)
    • Hurst exponent estimation
    • RMS height, slope, curvature
  • Configurable spectral band: $k_{\text{low}}$, $k_{\text{high}}$
  • Optional plateau for $k < k_{\text{low}}$

Installation

pip install rfgen

With optional dependencies:

pip install rfgen[plot]   # Include matplotlib for visualization
pip install rfgen[all]    # All optional dependencies

Quick Start

Generate a self-affine random field

import numpy as np
from rfgen import selfaffine_field

# Random generator seed
rng = np.random.default_rng(42)

# Generate 2D field with Hurst exponent H=0.8
N = 512
field = selfaffine_field(
    dim=2,
    N=N,
    Hurst=0.8,
    k_low=8/N,
    k_high=128/N,
    rng=rng
)

# Normalize to unit standard deviation
field /= np.std(field)

Generate a Matérn random field

from rfgen import matern_field

rng = np.random.default_rng(42)

field = matern_field(
    dim=2,
    N=512,
    nu=1.5,                  # Smoothness parameter
    correlation_length=0.05,
    k_low=0.01,
    k_high=0.25,
    rng=rng
)

Ideal spectrum (no spectral noise)

# Use noise=False for exact power-law spectrum
field_ideal = selfaffine_field(
    dim=2, N=256, Hurst=0.7,
    noise=False,  # Exact spectrum, random phases only
    rng=rng
)

API Reference

Generators

selfaffine_field

selfaffine_field(
    dim=2,           # Dimension (1, 2, or 3)
    N=256,           # Grid size per dimension
    Hurst=0.5,       # Hurst exponent ∈ [0, 1]
    k_low=0.03,      # Lower wavenumber cutoff
    k_high=0.3,      # Upper wavenumber cutoff (≤ 0.5 Nyquist)
    plateau=False,   # Flat spectrum for k < k_low
    noise=True,      # True: filtered noise, False: ideal spectrum
    rng=None,        # numpy.random.Generator for reproducibility
    verbose=False    # Print parameters
) -> np.ndarray

Power spectral density: $\Phi(k) \propto |k|^{-(\mathrm{dim} + 2H)}$

matern_field

matern_field(
    dim=2,                    # Dimension (1, 2, or 3)
    N=256,                    # Grid size per dimension
    nu=0.5,                   # Smoothness parameter (ν > 0)
    correlation_length=0.1,   # Correlation length
    sigma=1.0,                # Standard deviation
    k_low=0.03,               # Lower wavenumber cutoff
    k_high=0.3,               # Upper wavenumber cutoff
    noise=True,               # True: filtered noise, False: ideal spectrum
    rng=None,                 # numpy.random.Generator
    verbose=False             # Print parameters
) -> np.ndarray

Power spectral density: $\Phi(k) \propto (a + k^2)^{-(\nu+\mathrm{dim}/2)}$

Special cases for $\nu$:

  • $\nu = 0.5$: Exponential covariance (Ornstein-Uhlenbeck)
  • $\nu = 1.5$: Once differentiable
  • $\nu = 2.5$: Twice differentiable
  • $\nu \to \infty$: Squared exponential (Gaussian)

Analysis Tools

Autocorrelation

from rfgen import autocorrelation_1d, autocorrelation_2d, correlation_length

# Compute autocorrelation
R = autocorrelation_2d(field, normalize=True)

# Estimate correlation length (first zero crossing)
profile = field[N//2, :]
R_1d = autocorrelation_1d(profile)
l_corr = correlation_length(R_1d, threshold=0.0, spacing=1/N)

Power Spectral Density

from rfgen import psd_1d, psd_radial_average, fit_power_law, estimate_hurst_exponent

# 1D PSD
k, psd = psd_1d(profile, spacing=1/N)

# Radially averaged 2D PSD
k, psd = psd_radial_average(field, spacing=1/N)

# Fit power law and estimate Hurst exponent
A, beta, r_squared = fit_power_law(k, psd, k_min=k_low, k_max=k_high)
H_est, r2 = estimate_hurst_exponent(field, k_low=k_low, k_high=k_high, spacing=1/N)

Spectral Moments

from rfgen import spectral_moment, compute_standard_moments, rms_quantities, nayak_parameter

# Individual moment m_ij
m20 = spectral_moment(field, i=2, j=0, spacing=1/N)

# All standard moments
moments = compute_standard_moments(field, spacing=1/N)
# Returns: {'m00', 'm10', 'm01', 'm20', 'm02', 'm11', 'm40', 'm04', 'm22'}

# RMS quantities
rms = rms_quantities(field, spacing=1/N)
# Returns: {'rms_height', 'rms_slope_x', 'rms_slope_y', 'rms_slope',
#           'rms_curvature_x', 'rms_curvature_y', 'rms_curvature'}

# Nayak's bandwidth parameter
alpha = nayak_parameter(field, spacing=1/N)

Examples

Example scripts are available in the examples/ directory:

  • generation_example.py — Field generation with different spectra
  • analysis_example.py — Complete analysis workflow

Theory

Self-affine spectrum

The power spectral density follows:

$$\Phi(k) = C \cdot |k/k_0|^{-(\mathrm{dim} + 2H)}$$

where $\mathrm{dim}$ is the dimension and $H$ is the Hurst exponent.

Matérn spectrum

$$S(k) = \frac{\sigma^2 \cdot 2^\mathrm{dim} \cdot \pi^{\mathrm{dim}/2} \cdot \Gamma(\nu + \mathrm{dim}/2) \cdot (2\nu)^\nu}{\Gamma(\nu) \cdot \ell^{2\nu}} \cdot \left(\frac{2\nu}{\ell^2} + 4\pi^2 k^2\right)^{-(\nu + \mathrm{dim}/2)}$$

Generation methods

  • Filtered noise (noise=True): White noise in real space is transformed to Fourier space and multiplied by $\sqrt{\Phi(k)}$. The resulting PSD has random fluctuations around the target, see, e.g., [3].

  • Ideal spectrum (noise=False): Fourier coefficients are constructed with exact magnitudes $\sqrt{\Phi(k)}$ and random phases. Hermitian symmetry ensures real-valued output, see, e.g. [4].


References

[1] Hu, Y.Z.; Tonder, K. (1992). Simulation of 3-D random rough surface by 2-D digital filter and Fourier analysis. Int. J. Mach. Tools Manufact. 32(1-2), 83–90. DOI: 10.1016/0890-6955(92)90064-N

[2] Nayak, P.R. (1971). Random process model of rough surfaces. J. Lubrication Technology 93(3), 398–407.

[3] Yastrebov, V.A.; Anciaux, G.; Molinari, J.F. (2017). The role of the roughness spectral breadth in elastic contact of rough surfaces. J. Mech. Phys. Solids 107, 469–493. DOI: 10.1016/j.jmps.2017.07.016

[4] Müser, M.H., Dapp, W.B., Bugnicourt, R., Sainsot, P., Lesaffre, N., Lubrecht, T.A., Persson, B.N., Harris, K., Bennett, A., Schulze, K., Rohde, S. et al. (2017). Meeting the contact-mechanics challenge. Tribology Letters, 65(4), p.118. DOI: 10.1007/s11249-017-0900-2


Project Information

  • Author: Vladislav A. Yastrebov
  • Affiliation: CNRS, Mines Paris - PSL, Centre des Matériaux
  • AI usage: Claude Opus 4.5 in Cursor helped considerably in folder organization, testing and deployment, the core code, readme and tests were verified by the author.
  • License: BSD 3-Clause
  • Repository: github.com/vyastreb/rfgen
  • Heritage: This package evolved from SelfAffineSurfaceGenerator, extending the Python implementation with additional analysis tools and broader functionality.

License

BSD 3-Clause License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rfgen-0.1.2.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rfgen-0.1.2-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

Details for the file rfgen-0.1.2.tar.gz.

File metadata

  • Download URL: rfgen-0.1.2.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for rfgen-0.1.2.tar.gz
Algorithm Hash digest
SHA256 b4fdcf49feec68617cdd0feb498e8e02b980091120127c4d795ea0c387fa21ce
MD5 ca633f95366b715ba4795c40cefc1be6
BLAKE2b-256 79109e2f96aa6c9281107883fd396fcf83adc3a89767695fa0fc8528d516c4f3

See more details on using hashes here.

File details

Details for the file rfgen-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: rfgen-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 21.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for rfgen-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f77c7b0c2c5dba520a2910d3b8ca4b358a28300df0cf3330f7af6c5c44b1b538
MD5 f6a7375c3fce35bfd0a9f79cf8d0816c
BLAKE2b-256 c73de4962645447c39895ab9e9067cf56c151fcacf081cd3fa693a0fe0596a9c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page