Run a full-factorial sensitivity sweep for the janusplot 24-category
shape classifier. For each combination of ground-truth shape, sample
size n, noise level sigma, and replicate, the sweep:
Generates
npoints from the noiseless canonical curve on[0, 1]+ Gaussian noise with SD =sigma(fraction of the y-range, so signal-to-noise is comparable across shapes).Fits
mgcv::gam(y ~ s(x), method = "REML").Runs
janusplot_shape_metrics()to classify the fitted smooth.Records correctness at both the fine (24-category) and archetype (7-family) levels.
The function is the package-native implementation of
simulation/scripts/scenario_4_shape_recognition.R. A small
precomputed dataset is shipped as shape_sensitivity_demo for
downstream examples without requiring users to re-run the sweep.
Usage
janusplot_shape_sensitivity(
shapes = NULL,
n_grid = c(50L, 100L, 200L, 500L),
sigma_grid = c(0.02, 0.05, 0.1, 0.2, 0.4),
n_rep = 200L,
cutoffs = janusplot_shape_cutoffs(),
parallel = FALSE,
seed = 2026L,
verbose = interactive()
)Arguments
- shapes
Character vector of ground-truth names from
janusplot_shape_sensitivity_shapes(). DefaultNULL→ all 14.- n_grid
Integer vector of sample sizes. Default
c(50L, 100L, 200L, 500L).- sigma_grid
Numeric vector of noise levels (fraction of the y-range). Default
c(0.02, 0.05, 0.10, 0.20, 0.40).- n_rep
Integer. Replicates per cell. Default
200L.- cutoffs
Named list of classification thresholds; see
janusplot_shape_cutoffs().- parallel
Logical. If
TRUEandfuture.applyis installed, dispatch replicates in parallel. The caller is responsible for configuringfuture::plan()(e.g.future::plan(future::multisession)).- seed
Integer. Base seed — each fit uses
seed + row_indexso results are reproducible and cell-permutation-invariant.- verbose
Logical. Print progress messages to the console. Default is
interactive().
Value
A data frame with one row per fit. Columns:
truthGround-truth shape name.
nSample size for this fit.
sigmaNoise level for this fit.
seedRNG seed used.
predictedClassifier output at the fine (24-category) level.
correctLogical — does
predicted == truth?archetype_truthExpected archetype for
truth.archetype_predArchetype of
predicted.archetype_correctLogical — archetype-level correctness.
monotonicity_indexMonotonicity index
M(seejanusplot_shape_metrics()).convexity_indexConvexity index
C(seejanusplot_shape_metrics()).n_turn,n_inflectRecovered turning-point and inflection counts.
error"gam_fit_failed"whenmgcv::gam()errored;NAotherwise.
Examples
# Tiny-run smoke test (< 2 seconds): 3 shapes x 2 n x 2 sigma x 5 reps.
res <- janusplot_shape_sensitivity(
shapes = c("linear_up", "u_shape", "wave"),
n_grid = c(100L, 200L),
sigma_grid = c(0.05, 0.20),
n_rep = 5L,
verbose = FALSE
)
head(res)
#> truth n sigma seed predicted correct archetype_truth archetype_pred
#> 1 linear_up 100 0.05 2027 linear_up TRUE monotone_linear monotone_linear
#> 2 u_shape 100 0.05 2028 u_shape TRUE unimodal unimodal
#> 3 wave 100 0.05 2029 broad_peak FALSE wave unimodal
#> 4 linear_up 200 0.05 2030 linear_up TRUE monotone_linear monotone_linear
#> 5 u_shape 200 0.05 2031 u_shape TRUE unimodal unimodal
#> 6 wave 200 0.05 2032 broad_peak FALSE wave unimodal
#> archetype_correct monotonicity_index convexity_index n_turn n_inflect error
#> 1 TRUE 1.00000000 0.0000000 0 0 <NA>
#> 2 TRUE 0.02660353 0.9768746 1 0 <NA>
#> 3 FALSE -0.10849908 -0.2416725 1 2 <NA>
#> 4 TRUE 1.00000000 0.0000000 0 0 <NA>
#> 5 TRUE 0.06946110 0.9999646 1 0 <NA>
#> 6 FALSE -0.07133879 -0.2442866 1 2 <NA>
janusplot_shape_sensitivity_summary(res, level = "archetype")
#> truth n sigma accuracy
#> 1 linear_up 100 0.05 0.8
#> 2 u_shape 100 0.05 1.0
#> 3 wave 100 0.05 0.0
#> 4 linear_up 200 0.05 0.8
#> 5 u_shape 200 0.05 1.0
#> 6 wave 200 0.05 0.0
#> 7 linear_up 100 0.20 0.6
#> 8 u_shape 100 0.20 1.0
#> 9 wave 100 0.20 0.0
#> 10 linear_up 200 0.20 0.8
#> 11 u_shape 200 0.20 1.0
#> 12 wave 200 0.20 0.0
