geosmooth represents a synthetic dataset as four
serializable components: geometry, sampling, truth, and response.
synthetic.spec() combines those components without drawing
data. materialize.synthetic() performs all random work
under an explicit seed and RNG policy and returns a validated
synthetic_dataset.
library(geosmooth)
circle.spec <- synthetic.spec(
geometry = synthetic.circle(radius = 1, ambient.dim = 2),
sampling = synthetic.sampling.grid.interval(
0, 2 * pi, endpoints = "exclude.lower"),
truth = synthetic.truth.polynomial(c(b0 = 0)),
response = synthetic.response.gaussian(sd = 0.05)
)
circle.data <- materialize.synthetic(circle.spec, n = 80, seed = 2026)
circle.data
#> <synthetic_dataset> adhoc__specd155e302ac4d6d54d5298f321d3b01cbba0f539a0eaca5e892e69502f3fce186__n80__seed2026__rngnamed.stream.v1
#> n=80 intrinsic=1 ambient=2 truth=population
plot(circle.data)Quadforms use separate intrinsic and ambient dimensions. A flat geometry has no quadratic forms; a paraboloid or saddle supplies one or more symmetric forms.
surface.spec <- synthetic.spec(
geometry = synthetic.quadform(
intrinsic.dim = 2,
ambient.dim = 5,
forms = list(diag(c(1, -1))),
frame = "random.orthonormal"
),
sampling = synthetic.sampling.uniform.box(-1, 1),
truth = synthetic.truth.polynomial(c(b0 = 0, b1 = 1, b22 = -0.5)),
response = synthetic.response.gaussian(sd = 0.1)
)
surface.data <- materialize.synthetic(surface.spec, n = 100, seed = 17)
as.data.frame(surface.data)
#> dataset.id
#> 1 adhoc__spec90adf9b19cf8db3041878a96a32d5b64aefa1f3bcd1b727a58bb377520b71d2f__n100__seed17__rngnamed.stream.v1
#> recipe.id registry.tag n intrinsic.dim ambient.dim truth.scope
#> 1 <NA> <NA> 100 2 5 population
#> rng.policy
#> 1 named.stream.v1
#> checksum
#> 1 87ba1bb4a26245e58e0edd263233182f4acd37e4d44c53dcc3a01e7687a3b9c6Maintained benchmark recipes are discoverable through
synthetic.registry.ids(). G1–G7 remain compatibility
identifiers; the S01–S16 and V1–V3 identifiers preserve the shared SSRHE
regression suite. Ordinary datasets bind their full specification hash
into dataset.id.
head(synthetic.registry.ids())
#> [1] "G1" "G2" "G3a" "G3b" "G3c" "G3d"
registered <- synthetic.registry.spec("S01.V1")
registered.data <- materialize.synthetic(
registered, n = 160,
seed = synthetic.registry.seed("S01.V1", replicate = 1),
rng.policy = "legacy"
)
synthetic.dataset.checksum(registered.data)
#> [1] "b157f04855125d66efa3802655da6ba495dd9655ea44becc1076daf76c5c5f5c"Use rng.policy = "named.stream.v1" for new work. The
"legacy" policy exists for frozen scientific parity and
pins historical RNG behavior. Predictor noise, response noise, and
finite-design truth normalization are distinct contracts; they should
not be substituted for one another.