This release adds the model features developed for the FIA (US Forest Inventory and Analysis) and BWI (German Bundeswaldinventur) calibration projects. Every new argument defaults to the previous behaviour, so code written for 0.1.0 runs unchanged.
Bundled Oregon FIA data as package datasets. The calibration sample that
the D-Fit_to_FIA and E-Mortality vignettes fit on now ships as lazy-loaded
datasets in FINN's input format: fia_obs_dt, fia_env_dt, fia_init_trees
(200 training sites), fia_obs_test, fia_env_test, fia_init_test (200
disjoint holdout sites) and fia_species_dt (the shared species coding). They
are ready for fit() / makeInitCohorts() without any file reading; see
?fia_obs_dt. The fia_*.csv files previously under inst/extdata are gone
(the xz-compressed datasets are ~120 KB versus ~2.2 MB of CSV); the
example_*.csv raw inputs for the data-preparation vignette stay.
Per-predictor environmental scaling (env_autoscale). Previously every
environmental predictor was standardised the same way. env_autoscale now takes
a per-predictor specification — "auto" (z-score, the default), "identity"
(leave as supplied), "0to1" (min-max), or a user-supplied function(x)
returning list(center=, scale=) — given either as a single value applied to
all predictors or as a named vector/list per predictor. Every mode is affine, so
ALE interpretation stays invertible. The fitted constants remain accessible via
compute_env_scaling() / apply_env_scaling(). Dispatch is fully backward
compatible: the previous TRUE / FALSE / NULL forms behave exactly as before.
Saturating regeneration process (FINN::regeneration_saturation). A new,
exported regeneration process function that adds a Beverton-Holt density cap
recruits = K*m/(K+m) on top of the standard mechanistic recruitment, keeping
regeneration bounded at high propagule pressure. It is a drop-in alternative to
FINN::regeneration, used as the regeneration_process in finn(). The fitted
carrying capacity is a normal process parameter, declared through
createProcess(custom_parameters = list(reg_logK = ...)): a length-1 init gives
one shared K, a length-N_species init a per-species K (K = exp(reg_logK),
read back with exp(as.numeric(m$reg_logK))). This replaces the earlier
(unreleased) finn(regeneration_saturation = ) model-level option, so the cap
now composes like any other process rather than as a special case.
Recruitment observation weight (finn(recruit_obs_weight = )). Scales the
regeneration term in the loss so recruitment observations can be up- or
down-weighted relative to the other responses during calibration.
Period-scale growth scoring (finn(growth_period_scale = )). Scores growth
over a multi-year remeasurement interval rather than a single step, for
inventories whose growth is only observed between remeasurements.
Custom process parameters (createProcess(custom_parameters = )). Lets a
user-supplied process function declare and calibrate its own named parameters,
beyond FINN's built-in per-species and per-environment coefficients.
Regeneration observation operator. An internal hook mapping latent recruitment to what an inventory actually records — a building block for the inventory simulator.
createProcess(NN = ...) is no longer silently dropped inside create_nn().First public release.
FINN is a differentiable forest gap model: a cohort-based dynamic vegetation model whose demographic processes (competition, growth, mortality, regeneration) can each be a mechanistic function, a neural network, or a mixture of the two, all calibrated end-to-end by gradient descent.
Highlights of the current interface:
finn() assembles a model from one process per demographic component, each
built with createProcess() (mechanistic) or createHybrid() (neural
network).simulateForest() runs a model forward; fit() calibrates one to data and
predict() scores it, returning patch- and site-level results."mse"/"gaussian"), Poisson, negative
binomial, and a "binomial" likelihood for mortality that takes a
closed-cohort count pair (n_at_risk, n_died).weights = "auto" (the default in fit()) scales each loss by its
intercept-only baseline, so the six responses are commensurable and every term
reads as a fraction of its own null deviance.makeObsData(), resolveSiteIDs() and makeInitCohorts() turn a
raw tree list into FINN's input tables.ALE(), summary(), feature_importance() and
conditionalEffects().See the vignettes for a guided tour: Introduction to FINN, Plausible succession from a handful of species, Preparing your data for FINN, Fitting FINN to forest inventory data, and Mortality.