Skip to contents

A fixed-sample-size DesignFixed that searches, among balanced (\(n/2\)-treated) allocations, for one that directly minimizes a covariate imbalance criterion \(f(d)\), \(d = M(2w - 1)\), via a native C++ (RcppEigen + OpenMP) greedy pairwise-swap search (greedy_design_search_cpp()). Unlike DesignFixedGreedyDOptimal, which optimizes a model-based information-matrix criterion (D-/A-optimality) implied by an assumed linear model, this design optimizes a direct covariate-distance criterion between the treated and control group means/covariance, with no linear-model assumption: the two supported objectives are

  • "mahal_dist" (default): \(d = L^{-1} X^\top (2w-1) / n\) where \(\Sigma = LL^\top\) is the Cholesky factor of the covariate covariance matrix, and \(f(d) = \lVert d \rVert_2^2\) — the squared Mahalanobis distance between the treated and control covariate means, accounting for covariate correlation/scale. Falls back to "abs_sum_diff" if the covariate covariance matrix is (numerically) singular, since the Cholesky factorization then fails.

  • "abs_sum_diff": \(d = X_{\mathrm{std}}^\top (2w-1) / n\) (covariates standardized to unit variance, no correlation adjustment) and \(f(d) = \lVert d \rVert_1\) — the sum of absolute standardized mean differences across covariates.

Search algorithm. Starting from a random balanced (Fisher-Yates) allocation, the search runs in one of two modes selected by n_iter: Inf (default) runs exhaustive best-improvement search — each round scans every (treated, control) pair, applies the single globally best improving swap, and repeats until no swap improves \(f(d)\), guaranteeing convergence to a strict local optimum; a positive integer instead runs exactly that many stochastic steps, each picking a uniformly random (treated, control) pair and accepting the swap only if it improves \(f(d)\) (with patience-based early stopping). r independent design searches (one per requested replicate) run in parallel via OpenMP, each with its own std::mt19937 generator. This search's randomization is reproducible via the constructor's seed argument: per-thread RNGs are seeded from R's own RNG state (GetRNGstate()/unif_rand()) before the parallel region begins, so private$maybe_set_seed() does govern the resulting allocation, independent of the number of OpenMP threads used.

Same draws as DesignFixedGreedyDOptimal at the defaults. With objective = "mahal_dist" and n_iter = Inf (the defaults), this class returns exactly the same allocations as DesignFixedGreedyDOptimal with its defaults (objective = "D", no prior_precision) for the same seed. Despite the "no linear-model assumption" framing above, the default criterion coincides with D-optimality: with the number of treated subjects fixed, the information about the treatment effect in the linear model \(y = \beta_T w + \beta_0 + X \gamma + \epsilon\) equals a constant minus a positive multiple of the squared Mahalanobis distance between the treated and control covariate means. Both criteria therefore rank every allocation the same way, and the same swap search from the same starting allocation reaches the same allocation (the derivation is in DesignFixedGreedyDOptimal's documentation). The draws differ when this class uses objective = "abs_sum_diff", a finite n_iter, or the "abs_sum_diff" fallback after a failed Cholesky factorization, and when DesignFixedGreedyDOptimal uses an unequal prob_T (which this class does not support), objective = "A" with interest = "all" or a covariate subset, or a prior_precision.

Constraints and fallbacks. Only exactly balanced allocation (prob_T = 0.5, \(n\) even) is supported; the constructor errors otherwise. If no covariates are available, the search degenerates to pure balanced Fisher-Yates randomization (no swap search, since there is nothing to balance on). greedy_design_search_cpp()'s output is trusted unvalidated – it guarantees exactly n x r valid \(\{0,1\}\) columns with \(n/2\) treated subjects per column by construction (see fix_design_hierarchy.md, "AllocationMatrixValidation").

References

Krieger, A. M., Azriel, D., and Kapelner, A. (2019). "Nearly random designs with greatly improved balance." Biometrika, 106(3), 695-701, doi:10.1093/biomet/asz026 , for the greedy-swap balance-optimization approach this class implements. See also Mahalanobis distance for orientation on the default objective.

Super classes

Design -> DesignFixed -> DesignFixedGreedy

Methods

+ inherited public methods from DesignFixed
+ inherited public methods from Design


DesignFixedGreedy$new()

Initialize a greedy pairwise-swap search fixed experimental design. Only prob_T = 0.5 is supported (see class documentation).

Usage

DesignFixedGreedy$new(
  response_type,
  prob_T = 0.5,
  objective = "mahal_dist",
  n_iter = Inf,
  include_is_missing_as_a_new_feature = TRUE,
  n = NULL,
  verbose = FALSE,
  missingness_method = "impute",
  design_formula = ~.,
  seed = NULL
)

Arguments

response_type

The data type of response values.

prob_T

The probability of the treatment assignment. Must be 0.5.

objective

The covariate-imbalance objective to minimize: either "mahal_dist" (default, squared Mahalanobis distance between treated and control covariate means) or "abs_sum_diff" (sum of absolute standardized mean differences); see class documentation for the exact criteria.

n_iter

Number of swap iterations. Inf (default) uses exhaustive best-improvement search guaranteed to reach a strict local optimum. A positive integer runs that many stochastic random-pair iterations with patience-based early stopping.

include_is_missing_as_a_new_feature

Flag for missingness indicators.

n

The sample size.

verbose

Flag for verbosity.

missingness_method

How to handle missing values in covariates.

design_formula

A formula object.

seed

Integer seed for reproducibility. This design's search is reproducible via seed (see class documentation).

Returns

A new `DesignFixedGreedy` object


DesignFixedGreedy$supports_batch_w_pregeneration()

Returns TRUE so the calling framework pre-generates all replicate w vectors for a simulation cell in a single batched call to greedy_design_search_cpp() (which parallelizes the r independent searches over OpenMP threads internally), rather than issuing r separate single-replicate C++ calls.

Usage

DesignFixedGreedy$supports_batch_w_pregeneration()

Returns

Always TRUE for this class.


DesignFixedGreedy$clone()

The objects of this class are cloneable with this method.

Usage

DesignFixedGreedy$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples

des = DesignFixedGreedy$new(n = 10, response_type = 'continuous')