
Simulate an Empirically Calibrated Shifted Replicate
Source:R/simulation-generators.R
simulateShiftedDataset.RdGenerate a single known-shift simulation replicate using the empirically calibrated multi-shift framework. The function supports both the proportional generating-model scenario and a generator-specific non-proportional robustness scenario.
Usage
simulateShiftedDataset(
template,
tree_tip_count = NULL,
num_shifts,
min_shift_tips,
max_shift_tips,
scale_mode = c("proportional", "correlation"),
scale_factor_range = c(0.1, 2),
exclude_range = c(0.5, 1.5),
buffer = 3,
seed = NULL,
simulation_generator = c("original", "empirical"),
covariance_df = NULL,
integration_power_range = c(0.5, 1.25),
integration_exclude_range = c(0.8, 1.1),
eigen_floor = 1e-08
)Arguments
- template
A
bifrost_simulation_templatereturned bycreateSimulationTemplate().- tree_tip_count
Optional integer tip count for random subtree sampling. If
NULL, the full empirical tree fromtemplateis used.- num_shifts
Integer number of shifts to simulate.
- min_shift_tips
Integer minimum size of any shifted clade.
- max_shift_tips
Integer maximum size of any shifted clade.
- scale_mode
Character string specifying the generating scenario:
"proportional"for the manuscript generating model or"correlation"for the generator-specific non-proportional robustness scenario. With the default"original"generator, the latter reproduces the published correlation transform; withsimulation_generator = "empirical", it is an integration-rate trade-off.- scale_factor_range
Strictly positive numeric length-2 vector giving the full range of possible shift scalars.
- exclude_range
Numeric length-2 vector specifying the central interval excluded from sampled shift scalars.
- buffer
Integer minimum node distance between simulated shifts.
- seed
Optional integer random seed. When supplied, the function restores the caller's previous RNG state before returning.
- simulation_generator
Covariance and correlation-shift generator to use.
"original", the default, reproduces the published simulation operations exactly."empirical"draws around the full fitted covariance and changes integration and marginal evolutionary variance in opposing directions. Supply exactly one supported string; explicitly supplied vectors are rejected. When omitted,"original"is used.- covariance_df
Optional integer degrees of freedom for empirical Wishart draws. It must be at least the number of response traits. The default uses the residual degrees of freedom stored in
template.- integration_power_range
Strictly positive increasing numeric length-2 vector spanning one. Corrected correlation shifts draw spectral powers from the two tails of this range.
- integration_exclude_range
Increasing numeric length-2 vector that contains one and lies strictly inside
integration_power_range. Powers in this central interval are excluded so shifts have a material effect.- eigen_floor
Numeric stability floor, as a fraction of the largest eigenvalue, used by empirical correlation transforms.
Value
A list of class bifrost_simulation_replicate_shifted containing the
painted generating tree, the true shift nodes, the simulated response
matrix, a response-only trait_data object used for downstream model
fitting, regime covariance matrices, sampled scale factors or integration
powers, reciprocal marginal-variance scale factors, generator
metadata, covariance diagnostics, and a scenario label. For schema
compatibility, sampledScaleFactors contains the sampled integration
powers under the empirical correlation generator; the explicit
sampledIntegrationPowers and sampledVarianceScaleFactors fields should
be preferred for interpretation.
Details
This function generates shifted residual processes around the fitted mean structure stored in the template:
random subtree sampling from the empirical tree,
shift placement subject to clade-size and non-overlap constraints,
buffer enforcement using node distances,
generation of a fresh ancestral covariance matrix centered on the full empirical residual covariance for each empirical replicate,
construction of derived regimes by either proportional scaling or the generator-specific non-proportional robustness scenario, and
simulation of multivariate BMM residuals that are added to the empirical fitted mean structure from the global calibration model.
Under scale_mode = "proportional", derived regimes are scalar multiples of
the ancestral covariance matrix and therefore match the generating assumptions
of the current bifrost BMM search. Under scale_mode = "correlation", the
empirical generator raises the eigenvalues of the ancestral correlation matrix
to a sampled positive power and renormalizes the result to a correlation
matrix. Powers below one reduce integration; powers above one increase it.
The derived covariance is then divided by the same power. Consequently,
powers below one pair reduced integration with increased marginal
evolutionary variance, whereas powers above one pair increased integration
with decreased marginal variance. More precisely,
diag(Sigma_derived) = diag(Sigma_ancestral) / power. This deliberate
integration-rate trade-off remains a model-misspecification robustness test
because the search fits proportional covariance shifts.
The "original" generator is supplied for exact reproduction. Its
correlation scenario scales correlations and inversely scales marginal
variances according to the original manuscript operations; it should not be
interpreted as holding marginal variances fixed.
Downstream simulation studies still evaluate intercept-only shift searches on
the regenerated response block, so the returned trait_data contains only
the simulated response variables. This is the lower-level shifted-replicate
generator used by runShiftRecoverySimulationStudy() and
runSearchTuningGrid(); use those wrappers for replicated shift-recovery or
tuning-grid workflows.
Examples
if (FALSE) { # \dontrun{
set.seed(1)
tr <- ape::rtree(40)
X <- matrix(rnorm(40 * 3), ncol = 3)
rownames(X) <- tr$tip.label
tmpl <- createSimulationTemplate(tr, X, formula = "trait_data ~ 1", method = "LL")
sim_shift <- simulateShiftedDataset(
tmpl,
tree_tip_count = 25,
num_shifts = 2,
min_shift_tips = 3,
max_shift_tips = 8,
scale_mode = "proportional",
seed = 3
)
sim_shift$shiftNodes
} # }