Flexible Sampling¶
Advanced sampling patterns using SamplingSpec.
Different Grids per Function¶
Sample each quantity at optimal resolution:
import numpy as np
from gp4c import sample_prior, SamplingSpec
spec = SamplingSpec(
x_f=np.linspace(0, 5, 100), # Dense for function
x_g=np.linspace(0, 5, 50), # Coarse for integral
x_h=np.linspace(0.1, 4.9, 80) # Avoid boundaries for derivative
)
result = sample_prior(spec, ell=0.5, n_samples=10)
This is efficient when you need different resolutions for different quantities.
Selective Sampling¶
Only sample what you need:
# Just the derivative
spec = SamplingSpec(x_h=x)
result = sample_prior(spec, ell=0.5, n_samples=5)
# Function and derivative, skip integral
spec = SamplingSpec(x_f=x, x_h=x)
result = sample_prior(spec, ell=0.5, n_samples=5)
# Function and second derivative
spec = SamplingSpec(x_f=x, x_u=x)
result = sample_prior(spec, ell=0.5, n_samples=5)
Skipping unused quantities improves performance.
Region-Specific Sampling¶
Sample different quantities in different regions:
# Fine function samples in region of interest
x_f_roi = np.linspace(1.0, 2.0, 200)
# Coarse derivative samples everywhere
x_h_coarse = np.linspace(0, 5, 50)
spec = SamplingSpec(x_f=x_f_roi, x_h=x_h_coarse)
result = sample_prior(spec, ell=0.3, n_samples=10)
Boundary Considerations¶
Derivatives can be unstable at boundaries:
# Exclude boundaries for derivative
x = np.linspace(0, 5, 100)
x_interior = x[5:-5] # Drop 5 points on each side
spec = SamplingSpec(x_f=x, x_h=x_interior)
result = sample_prior(spec, ell=0.5, n_samples=5)
Tip
For stable derivative sampling, use interior points or increase length scale.
Posterior with Different Grids¶
Observe on one grid, predict on another:
from gp4c import sample_posterior, Observations
# Sparse observations
x_obs = np.array([0.5, 1.5, 2.5, 3.5, 4.5])
y_obs = np.sin(x_obs)
obs = Observations(x_f=x_obs, y_f=y_obs, noise_f=0.01)
# Dense predictions for different quantities
spec = SamplingSpec(
x_f=np.linspace(0, 5, 200), # Dense function
x_h=np.linspace(0.2, 4.8, 100) # Dense derivative, interior points
)
result = sample_posterior(obs, spec, ell=1.0, n_samples=10)
Sampling Combinations¶
The API supports any subset of {f, g, h, u}. Common combinations:
# f only
spec = SamplingSpec(x_f=x)
# f + g (function and integral)
spec = SamplingSpec(x_f=x, x_g=x)
# f + h (function and first derivative)
spec = SamplingSpec(x_f=x, x_h=x)
# f + u (function and second derivative)
spec = SamplingSpec(x_f=x, x_u=x)
# h + u (first and second derivative, no function values)
spec = SamplingSpec(x_h=x, x_u=x)
# f + g + h (all three original quantities)
spec = SamplingSpec(x_f=x, x_g=x, x_h=x)
# f + h + u (function with both derivatives)
spec = SamplingSpec(x_f=x, x_h=x, x_u=x)
# f + g + h + u (all four quantities)
spec = SamplingSpec(x_f=x, x_g=x, x_h=x, x_u=x)
Each combination is tested and numerically stable.
Kernel support for u¶
Not all kernels support second derivative sampling. Requesting x_u with an unsupported kernel will raise an error:
| Kernel | Supports u? |
|---|---|
'rbf' |
Yes |
'matern52' |
Yes |
'matern32' |
No |
'periodic' |
Yes |
'locally_periodic' |
Yes |
Performance Tips¶
- Sample only what you need - Skip unused quantities
- Use coarser grids for integrals (they're smoother)
- Avoid very small length scales with derivatives
- Interior points for derivatives when possible
Next Steps¶
- API Reference - SamplingSpec details
- Performance Guide - Optimization tips